From 26840ede0758026111eeaa2c248765fea594b90a Mon Sep 17 00:00:00 2001 From: WispX Date: Fri, 16 Apr 2021 16:57:16 +0800 Subject: [PATCH] :package: Compatible with PHP8. Closed #192 --- composer.lock | 252 +- thinkphp/README.md | 8 +- thinkphp/library/think/App.php | 12 +- thinkphp/library/think/Collection.php | 2 +- thinkphp/library/think/Container.php | 50 + thinkphp/library/think/Model.php | 63 +- thinkphp/library/think/Request.php | 2 +- thinkphp/library/think/Route.php | 2 + thinkphp/library/think/Validate.php | 2 + thinkphp/library/think/cache/driver/Redis.php | 2 +- thinkphp/library/think/db/Builder.php | 2 +- thinkphp/library/think/db/Query.php | 4 +- thinkphp/library/think/db/builder/Mysql.php | 8 +- thinkphp/library/think/db/connector/Mysql.php | 16 +- thinkphp/library/think/facade/Route.php | 2 +- thinkphp/library/think/model/Collection.php | 16 + .../think/model/concern/Conversion.php | 2 +- .../think/model/concern/RelationShip.php | 27 + .../think/model/concern/SoftDelete.php | 4 + .../think/model/relation/BelongsToMany.php | 3 +- .../think/model/relation/HasManyThrough.php | 12 +- .../library/think/model/relation/HasOne.php | 2 +- .../library/think/model/relation/MorphTo.php | 10 +- .../library/think/model/relation/OneToOne.php | 14 +- thinkphp/library/think/route/Domain.php | 1 + vendor/aliyuncs/oss-sdk-php/CHANGELOG.md | 28 +- vendor/aliyuncs/oss-sdk-php/README-CN.md | 2 +- vendor/aliyuncs/oss-sdk-php/README.md | 14 +- .../oss-sdk-php/src/OSS/Core/OssUtil.php | 32 +- .../oss-sdk-php/src/OSS/Http/RequestCore.php | 2 + .../oss-sdk-php/src/OSS/Model/BucketInfo.php | 111 +- .../oss-sdk-php/src/OSS/Model/BucketStat.php | 85 + .../src/OSS/Model/DeleteMarkerInfo.php | 65 + .../src/OSS/Model/DeleteObjectInfo.php | 41 + .../src/OSS/Model/DeletedObjectInfo.php | 63 + .../src/OSS/Model/ExtendWormConfig.php | 64 + .../src/OSS/Model/GetLiveChannelHistory.php | 3 + .../src/OSS/Model/InitiateWormConfig.php | 64 + .../src/OSS/Model/ObjectVersionInfo.php | 114 + .../src/OSS/Model/ObjectVersionListInfo.php | 162 + .../src/OSS/Model/RequestPaymentConfig.php | 68 + .../src/OSS/Model/RestoreConfig.php | 77 + .../OSS/Model/ServerSideEncryptionConfig.php | 91 + .../src/OSS/Model/StorageCapacityConfig.php | 2 + .../oss-sdk-php/src/OSS/Model/Tag.php | 41 + .../src/OSS/Model/TaggingConfig.php | 89 + .../src/OSS/Model/VersioningConfig.php | 67 + .../oss-sdk-php/src/OSS/Model/WormConfig.php | 90 + .../oss-sdk-php/src/OSS/OssClient.php | 919 ++- .../src/OSS/Result/CopyObjectResult.php | 2 +- .../OSS/Result/DeleteObjectVersionsResult.php | 39 + .../OSS/Result/GetBucketEncryptionResult.php | 26 + .../src/OSS/Result/GetBucketInfoResult.php | 37 + .../Result/GetBucketRequestPaymentResult.php | 26 + .../src/OSS/Result/GetBucketStatResult.php | 26 + .../src/OSS/Result/GetBucketTagsResult.php | 26 + .../OSS/Result/GetBucketVersioningResult.php | 26 + .../src/OSS/Result/GetBucketWormResult.php | 26 + .../OSS/Result/InitiateBucketWormResult.php | 27 + .../src/OSS/Result/ListBucketsResult.php | 5 +- .../OSS/Result/ListObjectVersionsResult.php | 96 + .../tests/OSS/Tests/BucketLiveChannelTest.php | 33 + .../tests/OSS/Tests/ContentTypeTest.php | 16 +- .../Tests/DeleteObjectVersionsResultTest.php | 187 + .../Tests/GetBucketEncryptionResultTest.php | 95 + .../GetBucketRequestPaymentResultTest.php | 66 + .../OSS/Tests/GetBucketStatResultTest.php | 59 + .../OSS/Tests/GetBucketTagsResultTest.php | 77 + .../OSS/Tests/GetBucketWormResultTest.php | 84 + .../tests/OSS/Tests/ListBucketsResultTest.php | 88 +- .../Tests/ListObjectVersionsResultTest.php | 213 + .../tests/OSS/Tests/LiveChannelXmlTest.php | 30 +- .../tests/OSS/Tests/ObjectAclTest.php | 6 +- .../Tests/OssClientBucketEncryptionTest.php | 63 + .../OSS/Tests/OssClientBucketInfoTest.php | 20 + .../OSS/Tests/OssClientBucketPolicyTest.php | 47 + .../OssClientBucketRequestPaymentTest.php | 51 + .../OSS/Tests/OssClientBucketStatTestTest.php | 34 + .../OSS/Tests/OssClientBucketTagsTest.php | 76 + .../tests/OSS/Tests/OssClientBucketTest.php | 27 + .../Tests/OssClientBucketVersioningTest.php | 40 + .../OSS/Tests/OssClientBucketWormTest.php | 36 + .../tests/OSS/Tests/OssClientImageTest.php | 61 +- .../OSS/Tests/OssClientListObjectsTest.php | 184 + .../Tests/OssClientMultipartUploadTest.php | 114 +- .../OssClientObjectRequestPaymentTest.php | 471 ++ .../OSS/Tests/OssClientObjectTaggingTest.php | 160 + .../tests/OSS/Tests/OssClientObjectTest.php | 84 +- .../Tests/OssClientObjectVersioningTest.php | 610 ++ .../OSS/Tests/OssClientRestoreObjectTest.php | 78 + .../OSS/Tests/OssClientSignatureTest.php | 56 + .../tests/OSS/Tests/OssClientTest.php | 141 +- .../tests/OSS/Tests/OssTrafficLimitTest.php | 96 + .../tests/OSS/Tests/OssUtilTest.php | 55 +- .../OSS/Tests/StorageCapacityConfigTest.php | 58 + .../tests/OSS/Tests/SymlinkTest.php | 13 +- .../tests/OSS/Tests/TestOssClientBase.php | 4 +- vendor/composer/ClassLoader.php | 6 +- vendor/composer/InstalledVersions.php | 550 ++ vendor/composer/autoload_classmap.php | 2 + vendor/composer/autoload_files.php | 4 +- vendor/composer/autoload_psr4.php | 2 +- vendor/composer/autoload_real.php | 4 +- vendor/composer/autoload_static.php | 16 +- vendor/composer/installed.json | 2621 ++++---- vendor/composer/installed.php | 365 ++ vendor/composer/platform_check.php | 27 + vendor/guzzlehttp/promises/CHANGELOG.md | 19 + vendor/guzzlehttp/promises/README.md | 42 +- vendor/guzzlehttp/promises/composer.json | 13 +- .../promises/src/AggregateException.php | 1 + .../promises/src/CancellationException.php | 1 + vendor/guzzlehttp/promises/src/Coroutine.php | 28 +- vendor/guzzlehttp/promises/src/Create.php | 84 + vendor/guzzlehttp/promises/src/Each.php | 90 + .../guzzlehttp/promises/src/EachPromise.php | 71 +- .../promises/src/FulfilledPromise.php | 10 +- vendor/guzzlehttp/promises/src/Is.php | 46 + vendor/guzzlehttp/promises/src/Promise.php | 68 +- .../promises/src/PromiseInterface.php | 4 + .../promises/src/PromisorInterface.php | 1 + .../promises/src/RejectedPromise.php | 14 +- .../promises/src/RejectionException.php | 3 +- vendor/guzzlehttp/promises/src/TaskQueue.php | 5 +- .../promises/src/TaskQueueInterface.php | 3 +- vendor/guzzlehttp/promises/src/Utils.php | 274 + vendor/guzzlehttp/promises/src/functions.php | 254 +- .../guzzlehttp/psr7/.github/workflows/bc.yml | 16 + .../guzzlehttp/psr7/.github/workflows/ci.yml | 30 + .../psr7/.github/workflows/integration.yml | 37 + vendor/guzzlehttp/psr7/.php_cs.dist | 56 + vendor/guzzlehttp/psr7/CHANGELOG.md | 45 +- vendor/guzzlehttp/psr7/README.md | 322 +- vendor/guzzlehttp/psr7/composer.json | 6 +- vendor/guzzlehttp/psr7/src/AppendStream.php | 7 +- vendor/guzzlehttp/psr7/src/BufferStream.php | 5 + vendor/guzzlehttp/psr7/src/CachingStream.php | 9 +- vendor/guzzlehttp/psr7/src/DroppingStream.php | 3 + vendor/guzzlehttp/psr7/src/FnStream.php | 5 + vendor/guzzlehttp/psr7/src/Header.php | 71 + vendor/guzzlehttp/psr7/src/InflateStream.php | 4 + vendor/guzzlehttp/psr7/src/LazyOpenStream.php | 7 +- vendor/guzzlehttp/psr7/src/LimitStream.php | 6 +- vendor/guzzlehttp/psr7/src/Message.php | 252 + vendor/guzzlehttp/psr7/src/MessageTrait.php | 7 +- vendor/guzzlehttp/psr7/src/MimeType.php | 140 + .../guzzlehttp/psr7/src/MultipartStream.php | 19 +- vendor/guzzlehttp/psr7/src/NoSeekStream.php | 5 +- vendor/guzzlehttp/psr7/src/PumpStream.php | 23 +- vendor/guzzlehttp/psr7/src/Query.php | 113 + vendor/guzzlehttp/psr7/src/Request.php | 7 +- vendor/guzzlehttp/psr7/src/Response.php | 7 +- vendor/guzzlehttp/psr7/src/Rfc7230.php | 1 + vendor/guzzlehttp/psr7/src/ServerRequest.php | 15 +- vendor/guzzlehttp/psr7/src/Stream.php | 9 +- .../psr7/src/StreamDecoratorTrait.php | 5 +- vendor/guzzlehttp/psr7/src/StreamWrapper.php | 4 + vendor/guzzlehttp/psr7/src/UploadedFile.php | 40 +- vendor/guzzlehttp/psr7/src/Uri.php | 62 +- vendor/guzzlehttp/psr7/src/UriNormalizer.php | 3 + vendor/guzzlehttp/psr7/src/UriResolver.php | 3 + vendor/guzzlehttp/psr7/src/Utils.php | 427 ++ vendor/guzzlehttp/psr7/src/functions.php | 749 +-- vendor/nicolab/php-ftp-client/README.md | 2 +- .../src/FtpClient/FtpClient.php | 24 +- .../src/FtpClient/FtpWrapper.php | 2 +- vendor/phpmailer/phpmailer/README.md | 135 +- vendor/phpmailer/phpmailer/SECURITY.md | 2 +- vendor/phpmailer/phpmailer/VERSION | 2 +- vendor/phpmailer/phpmailer/composer.json | 20 +- .../phpmailer/phpmailer/get_oauth_token.php | 34 +- .../phpmailer/language/phpmailer.lang-af.php | 1 + .../phpmailer/language/phpmailer.lang-ar.php | 1 + .../phpmailer/language/phpmailer.lang-az.php | 1 + .../phpmailer/language/phpmailer.lang-ba.php | 3 +- .../phpmailer/language/phpmailer.lang-be.php | 1 + .../phpmailer/language/phpmailer.lang-bg.php | 1 + .../phpmailer/language/phpmailer.lang-ca.php | 1 + .../phpmailer/language/phpmailer.lang-ch.php | 1 + .../phpmailer/language/phpmailer.lang-cs.php | 3 + .../phpmailer/language/phpmailer.lang-da.php | 5 +- .../phpmailer/language/phpmailer.lang-de.php | 3 + .../phpmailer/language/phpmailer.lang-el.php | 1 + .../phpmailer/language/phpmailer.lang-eo.php | 1 + .../phpmailer/language/phpmailer.lang-es.php | 1 + .../phpmailer/language/phpmailer.lang-et.php | 1 + .../phpmailer/language/phpmailer.lang-fa.php | 1 + .../phpmailer/language/phpmailer.lang-fi.php | 1 + .../phpmailer/language/phpmailer.lang-fo.php | 1 + .../phpmailer/language/phpmailer.lang-fr.php | 3 + .../phpmailer/language/phpmailer.lang-gl.php | 1 + .../phpmailer/language/phpmailer.lang-he.php | 1 + .../phpmailer/language/phpmailer.lang-hi.php | 3 +- .../phpmailer/language/phpmailer.lang-hr.php | 1 + .../phpmailer/language/phpmailer.lang-hu.php | 1 + .../phpmailer/language/phpmailer.lang-hy.php | 3 +- .../phpmailer/language/phpmailer.lang-id.php | 28 +- .../phpmailer/language/phpmailer.lang-it.php | 1 + .../phpmailer/language/phpmailer.lang-ja.php | 1 + .../phpmailer/language/phpmailer.lang-ka.php | 1 + .../phpmailer/language/phpmailer.lang-ko.php | 1 + .../phpmailer/language/phpmailer.lang-lt.php | 1 + .../phpmailer/language/phpmailer.lang-lv.php | 1 + .../phpmailer/language/phpmailer.lang-mg.php | 2 + .../phpmailer/language/phpmailer.lang-ms.php | 1 + .../phpmailer/language/phpmailer.lang-nb.php | 1 + .../phpmailer/language/phpmailer.lang-nl.php | 1 + .../phpmailer/language/phpmailer.lang-pl.php | 3 +- .../phpmailer/language/phpmailer.lang-pt.php | 1 + .../language/phpmailer.lang-pt_br.php | 1 + .../phpmailer/language/phpmailer.lang-ro.php | 1 + .../phpmailer/language/phpmailer.lang-ru.php | 1 + .../phpmailer/language/phpmailer.lang-sk.php | 3 + .../phpmailer/language/phpmailer.lang-sl.php | 6 +- .../phpmailer/language/phpmailer.lang-sr.php | 1 + .../language/phpmailer.lang-sr_latn.php | 28 + .../phpmailer/language/phpmailer.lang-sv.php | 1 + .../phpmailer/language/phpmailer.lang-tl.php | 25 +- .../phpmailer/language/phpmailer.lang-tr.php | 1 + .../phpmailer/language/phpmailer.lang-uk.php | 1 + .../phpmailer/language/phpmailer.lang-vi.php | 1 + .../phpmailer/language/phpmailer.lang-zh.php | 1 + .../language/phpmailer.lang-zh_cn.php | 1 + vendor/phpmailer/phpmailer/phpunit.xml.dist | 35 + vendor/phpmailer/phpmailer/src/Exception.php | 3 +- vendor/phpmailer/phpmailer/src/OAuth.php | 5 +- vendor/phpmailer/phpmailer/src/PHPMailer.php | 531 +- vendor/phpmailer/phpmailer/src/POP3.php | 85 +- vendor/phpmailer/phpmailer/src/SMTP.php | 141 +- vendor/qiniu/php-sdk/.scrutinizer.yml | 7 + vendor/qiniu/php-sdk/.travis.yml | 13 +- vendor/qiniu/php-sdk/CHANGELOG.md | 27 + vendor/qiniu/php-sdk/README.md | 27 +- vendor/qiniu/php-sdk/docs/rtc/README.md | 71 - vendor/qiniu/php-sdk/docs/rtc/example.php | 42 - vendor/qiniu/php-sdk/docs/sms/example.php | 70 - vendor/qiniu/php-sdk/examples/README.md | 8 +- .../php-sdk/examples/bucket_lifecycleRule.php | 28 +- .../php-sdk/examples/cdn_get_bandwidth.php | 17 +- .../qiniu/php-sdk/examples/cdn_get_flux.php | 13 +- .../php-sdk/examples/cdn_get_log_list.php | 14 +- .../examples/cdn_get_prefetch_list.php | 46 + .../php-sdk/examples/cdn_get_refresh_list.php | 48 + .../examples/cdn_refresh_urls_dirs.php | 27 +- .../examples/cdn_timestamp_antileech.php | 13 +- .../qiniu/php-sdk/examples/censor_image.php | 42 + .../qiniu/php-sdk/examples/censor_video.php | 52 + .../qiniu/php-sdk/examples/delete_bucket.php | 21 +- .../php-sdk/examples/delete_bucketEvent.php | 23 +- .../examples/delete_bucketLifecycleRule.php | 22 +- .../php-sdk/examples/get_bucketEvents.php | 20 +- .../examples/get_bucketLifecycleRules.php | 20 +- .../qiniu/php-sdk/examples/get_bucketList.php | 20 +- .../php-sdk/examples/get_bucketQuota.php | 20 +- .../qiniu/php-sdk/examples/get_bucketinfo.php | 19 +- .../php-sdk/examples/get_bucketinfos.php | 20 +- .../qiniu/php-sdk/examples/get_corsRules.php | 20 +- .../php-sdk/examples/image_url_builder.php | 18 +- .../php-sdk/examples/persistent_fop_init.php | 15 +- .../examples/persistent_fop_status.php | 15 +- vendor/qiniu/php-sdk/examples/pfop_mkzip.php | 29 +- vendor/qiniu/php-sdk/examples/pfop_vframe.php | 27 +- .../php-sdk/examples/pfop_video_avthumb.php | 30 +- .../qiniu/php-sdk/examples/pfop_watermark.php | 37 +- vendor/qiniu/php-sdk/examples/prefop.php | 20 +- vendor/qiniu/php-sdk/examples/pulpvideo.php | 55 - .../php-sdk/examples/put_bucketAccessMode.php | 22 +- .../examples/put_bucketAccessStyleMode.php | 22 +- .../php-sdk/examples/put_bucketEvent.php | 25 +- .../php-sdk/examples/put_bucketMaxAge.php | 22 +- .../php-sdk/examples/put_bucketQuota.php | 21 +- .../php-sdk/examples/put_referAntiLeech.php | 27 +- vendor/qiniu/php-sdk/examples/qetag.php | 13 +- .../php-sdk/examples/rs_asynch_fetch.php | 71 + .../php-sdk/examples/rs_batch_change_mime.php | 20 +- .../php-sdk/examples/rs_batch_change_type.php | 21 +- .../qiniu/php-sdk/examples/rs_batch_copy.php | 18 +- .../php-sdk/examples/rs_batch_delete.php | 18 +- .../examples/rs_batch_delete_after_days.php | 21 +- .../qiniu/php-sdk/examples/rs_batch_move.php | 18 +- .../qiniu/php-sdk/examples/rs_batch_stat.php | 20 +- .../php-sdk/examples/rs_bucket_domains.php | 23 +- vendor/qiniu/php-sdk/examples/rs_buckets.php | 24 +- .../qiniu/php-sdk/examples/rs_change_mime.php | 17 +- .../php-sdk/examples/rs_change_status.php | 17 +- .../qiniu/php-sdk/examples/rs_change_type.php | 19 +- vendor/qiniu/php-sdk/examples/rs_copy.php | 17 +- vendor/qiniu/php-sdk/examples/rs_delete.php | 16 +- .../php-sdk/examples/rs_delete_after_days.php | 12 +- .../php-sdk/examples/rs_download_urls.php | 8 +- vendor/qiniu/php-sdk/examples/rs_fetch.php | 15 +- vendor/qiniu/php-sdk/examples/rs_move.php | 7 +- vendor/qiniu/php-sdk/examples/rs_prefetch.php | 8 +- .../qiniu/php-sdk/examples/rs_pub_domain.php | 19 - vendor/qiniu/php-sdk/examples/rs_stat.php | 25 +- .../php-sdk/examples/rsf_list_bucket.php | 9 +- .../qiniu/php-sdk/examples/rsf_list_files.php | 9 +- .../php-sdk/examples/rsf_v2list_bucket.php | 17 +- vendor/qiniu/php-sdk/examples/rtc/README.md | 34 + .../php-sdk/examples/rtc/rtc_createApp.php | 32 + .../examples/rtc/rtc_create_roomToken.php | 34 + .../php-sdk/examples/rtc/rtc_deleteApp.php | 25 + .../qiniu/php-sdk/examples/rtc/rtc_getApp.php | 26 + .../examples/rtc/rtc_rooms_kickUser.php | 31 + .../rtc/rtc_rooms_listActiveRooms.php | 35 + .../examples/rtc/rtc_rooms_listUser.php | 29 + .../examples/rtc/rtc_rooms_stopMerge.php | 28 + .../php-sdk/examples/rtc/rtc_updateApp.php | 40 + vendor/qiniu/php-sdk/examples/saveas.php | 23 +- vendor/qiniu/php-sdk/examples/sms/README.md | 45 + .../examples/sms/sms_create_signature.php | 29 + .../examples/sms/sms_create_template.php | 33 + .../examples/sms/sms_delete_signature.php | 25 + .../examples/sms/sms_delete_template.php | 25 + .../examples/sms/sms_edit_signature.php | 30 + .../examples/sms/sms_edit_template.php | 31 + .../examples/sms/sms_query_send_sms.php | 50 + .../examples/sms/sms_query_signature.php | 28 + .../sms/sms_query_single_signature.php | 26 + .../sms/sms_query_single_template.php | 26 + .../examples/sms/sms_query_template.php | 28 + .../php-sdk/examples/sms/sms_send_message.php | 32 + .../php-sdk/examples/update_bucketEvent.php | 20 +- .../examples/update_bucketLifecycleRule.php | 18 +- .../php-sdk/examples/upload_and_callback.php | 19 +- .../php-sdk/examples/upload_and_pfop.php | 21 +- .../php-sdk/examples/upload_mgr_init.php | 9 +- .../php-sdk/examples/upload_multi_demos.php | 24 +- .../php-sdk/examples/upload_simple_file.php | 6 +- .../qiniu/php-sdk/examples/upload_tokens.php | 28 +- .../examples/upload_verify_callback.php | 10 +- .../php-sdk/examples/upload_with_qvmzone.php | 40 + .../php-sdk/examples/upload_with_zone.php | 39 + vendor/qiniu/php-sdk/src/Qiniu/Auth.php | 1 + .../php-sdk/src/Qiniu/Cdn/CdnManager.php | 75 + vendor/qiniu/php-sdk/src/Qiniu/Config.php | 4 +- .../qiniu/php-sdk/src/Qiniu/Http/Response.php | 2 +- .../src/Qiniu/Processing/ImageUrlBuilder.php | 76 +- .../src/Qiniu/Processing/Operation.php | 4 +- .../src/Qiniu/Processing/PersistentFop.php | 16 +- .../qiniu/php-sdk/src/Qiniu/Rtc/AppClient.php | 157 +- vendor/qiniu/php-sdk/src/Qiniu/Sms/Sms.php | 381 +- .../src/Qiniu/Storage/ArgusManager.php | 76 +- .../src/Qiniu/Storage/BucketManager.php | 668 +- .../src/Qiniu/Storage/FormUploader.php | 33 +- .../src/Qiniu/Storage/ResumeUploader.php | 14 +- vendor/qiniu/php-sdk/src/Qiniu/functions.php | 10 +- .../php-sdk/tests/Qiniu/Tests/BucketTest.php | 256 +- .../tests/Qiniu/Tests/CdnManagerTest.php | 120 +- .../php-sdk/tests/Qiniu/Tests/HttpTest.php | 44 +- .../tests/Qiniu/Tests/ResumeUpTest.php | 2 +- .../php-sdk/tests/Qiniu/Tests/ZoneTest.php | 66 + vendor/qiniu/php-sdk/tests/bootstrap.php | 9 + vendor/symfony/polyfill-intl-idn/Idn.php | 998 ++- vendor/symfony/polyfill-intl-idn/Info.php | 23 + vendor/symfony/polyfill-intl-idn/LICENSE | 2 +- .../Resources/unidata/DisallowedRanges.php | 375 ++ .../Resources/unidata/Regex.php | 24 + .../Resources/unidata/deviation.php | 8 + .../Resources/unidata/disallowed.php | 2638 ++++++++ .../unidata/disallowed_STD3_mapped.php | 308 + .../unidata/disallowed_STD3_valid.php | 71 + .../Resources/unidata/ignored.php | 273 + .../Resources/unidata/mapped.php | 5778 +++++++++++++++++ .../Resources/unidata/virama.php | 65 + .../symfony/polyfill-intl-idn/bootstrap.php | 14 +- .../symfony/polyfill-intl-idn/bootstrap80.php | 128 + .../symfony/polyfill-intl-idn/composer.json | 10 +- .../LICENSE | 0 .../polyfill-intl-normalizer/Normalizer.php | 310 + .../polyfill-intl-normalizer/README.md | 14 + .../Resources/stubs/Normalizer.php | 17 + .../unidata/canonicalComposition.php | 945 +++ .../unidata/canonicalDecomposition.php | 2065 ++++++ .../Resources/unidata/combiningClass.php | 876 +++ .../unidata/compatibilityDecomposition.php | 3695 +++++++++++ .../polyfill-intl-normalizer/bootstrap.php | 23 + .../polyfill-intl-normalizer/bootstrap80.php | 19 + .../composer.json | 17 +- vendor/symfony/polyfill-mbstring/Mbstring.php | 847 --- vendor/symfony/polyfill-mbstring/README.md | 13 - .../Resources/unidata/lowerCase.php | 1397 ---- .../Resources/unidata/titleCaseRegexp.php | 5 - .../Resources/unidata/upperCase.php | 1414 ---- .../symfony/polyfill-mbstring/bootstrap.php | 141 - vendor/symfony/polyfill-php72/Php72.php | 20 +- vendor/symfony/polyfill-php72/bootstrap.php | 16 +- vendor/symfony/polyfill-php72/composer.json | 4 +- vendor/topthink/think-installer/composer.json | 4 +- .../think-installer/src/LibraryInstaller.php | 28 + .../topthink/think-installer/src/Plugin.php | 12 +- .../topthink/think-installer/src/Promise.php | 11 + .../think-installer/src/ThinkExtend.php | 18 +- .../think-installer/src/ThinkFramework.php | 31 +- .../think-installer/src/ThinkTesting.php | 24 +- 395 files changed, 33759 insertions(+), 8584 deletions(-) create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/BucketStat.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/DeleteMarkerInfo.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/DeleteObjectInfo.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/DeletedObjectInfo.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ExtendWormConfig.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/InitiateWormConfig.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ObjectVersionInfo.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ObjectVersionListInfo.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/RequestPaymentConfig.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/RestoreConfig.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ServerSideEncryptionConfig.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/Tag.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/TaggingConfig.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/VersioningConfig.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Model/WormConfig.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Result/DeleteObjectVersionsResult.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketEncryptionResult.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketInfoResult.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketRequestPaymentResult.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketStatResult.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketTagsResult.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketVersioningResult.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketWormResult.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Result/InitiateBucketWormResult.php create mode 100644 vendor/aliyuncs/oss-sdk-php/src/OSS/Result/ListObjectVersionsResult.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/DeleteObjectVersionsResultTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketEncryptionResultTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketRequestPaymentResultTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketStatResultTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketTagsResultTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketWormResultTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ListObjectVersionsResultTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketEncryptionTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketInfoTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketPolicyTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketRequestPaymentTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketStatTestTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketTagsTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketVersioningTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketWormTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientListObjectsTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectRequestPaymentTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectTaggingTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectVersioningTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssTrafficLimitTest.php create mode 100644 vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/StorageCapacityConfigTest.php create mode 100644 vendor/composer/InstalledVersions.php create mode 100644 vendor/composer/installed.php create mode 100644 vendor/composer/platform_check.php create mode 100644 vendor/guzzlehttp/promises/src/Create.php create mode 100644 vendor/guzzlehttp/promises/src/Each.php create mode 100644 vendor/guzzlehttp/promises/src/Is.php create mode 100644 vendor/guzzlehttp/promises/src/Utils.php create mode 100644 vendor/guzzlehttp/psr7/.github/workflows/bc.yml create mode 100644 vendor/guzzlehttp/psr7/.github/workflows/ci.yml create mode 100644 vendor/guzzlehttp/psr7/.github/workflows/integration.yml create mode 100644 vendor/guzzlehttp/psr7/.php_cs.dist create mode 100644 vendor/guzzlehttp/psr7/src/Header.php create mode 100644 vendor/guzzlehttp/psr7/src/Message.php create mode 100644 vendor/guzzlehttp/psr7/src/MimeType.php create mode 100644 vendor/guzzlehttp/psr7/src/Query.php create mode 100644 vendor/guzzlehttp/psr7/src/Utils.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-sr_latn.php create mode 100644 vendor/phpmailer/phpmailer/phpunit.xml.dist delete mode 100755 vendor/qiniu/php-sdk/docs/rtc/README.md delete mode 100755 vendor/qiniu/php-sdk/docs/rtc/example.php delete mode 100644 vendor/qiniu/php-sdk/docs/sms/example.php create mode 100644 vendor/qiniu/php-sdk/examples/cdn_get_prefetch_list.php create mode 100644 vendor/qiniu/php-sdk/examples/cdn_get_refresh_list.php create mode 100644 vendor/qiniu/php-sdk/examples/censor_image.php create mode 100755 vendor/qiniu/php-sdk/examples/censor_video.php delete mode 100755 vendor/qiniu/php-sdk/examples/pulpvideo.php create mode 100644 vendor/qiniu/php-sdk/examples/rs_asynch_fetch.php delete mode 100644 vendor/qiniu/php-sdk/examples/rs_pub_domain.php create mode 100755 vendor/qiniu/php-sdk/examples/rtc/README.md create mode 100644 vendor/qiniu/php-sdk/examples/rtc/rtc_createApp.php create mode 100644 vendor/qiniu/php-sdk/examples/rtc/rtc_create_roomToken.php create mode 100644 vendor/qiniu/php-sdk/examples/rtc/rtc_deleteApp.php create mode 100644 vendor/qiniu/php-sdk/examples/rtc/rtc_getApp.php create mode 100644 vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_kickUser.php create mode 100644 vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_listActiveRooms.php create mode 100644 vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_listUser.php create mode 100644 vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_stopMerge.php create mode 100644 vendor/qiniu/php-sdk/examples/rtc/rtc_updateApp.php create mode 100755 vendor/qiniu/php-sdk/examples/sms/README.md create mode 100644 vendor/qiniu/php-sdk/examples/sms/sms_create_signature.php create mode 100644 vendor/qiniu/php-sdk/examples/sms/sms_create_template.php create mode 100644 vendor/qiniu/php-sdk/examples/sms/sms_delete_signature.php create mode 100644 vendor/qiniu/php-sdk/examples/sms/sms_delete_template.php create mode 100644 vendor/qiniu/php-sdk/examples/sms/sms_edit_signature.php create mode 100644 vendor/qiniu/php-sdk/examples/sms/sms_edit_template.php create mode 100644 vendor/qiniu/php-sdk/examples/sms/sms_query_send_sms.php create mode 100644 vendor/qiniu/php-sdk/examples/sms/sms_query_signature.php create mode 100644 vendor/qiniu/php-sdk/examples/sms/sms_query_single_signature.php create mode 100644 vendor/qiniu/php-sdk/examples/sms/sms_query_single_template.php create mode 100644 vendor/qiniu/php-sdk/examples/sms/sms_query_template.php create mode 100644 vendor/qiniu/php-sdk/examples/sms/sms_send_message.php create mode 100644 vendor/qiniu/php-sdk/examples/upload_with_qvmzone.php create mode 100644 vendor/qiniu/php-sdk/examples/upload_with_zone.php create mode 100644 vendor/symfony/polyfill-intl-idn/Info.php create mode 100644 vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php create mode 100644 vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php create mode 100644 vendor/symfony/polyfill-intl-idn/Resources/unidata/deviation.php create mode 100644 vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php create mode 100644 vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php create mode 100644 vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php create mode 100644 vendor/symfony/polyfill-intl-idn/Resources/unidata/ignored.php create mode 100644 vendor/symfony/polyfill-intl-idn/Resources/unidata/mapped.php create mode 100644 vendor/symfony/polyfill-intl-idn/Resources/unidata/virama.php create mode 100644 vendor/symfony/polyfill-intl-idn/bootstrap80.php rename vendor/symfony/{polyfill-mbstring => polyfill-intl-normalizer}/LICENSE (100%) create mode 100644 vendor/symfony/polyfill-intl-normalizer/Normalizer.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/README.md create mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalComposition.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/bootstrap.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/bootstrap80.php rename vendor/symfony/{polyfill-mbstring => polyfill-intl-normalizer}/composer.json (62%) delete mode 100644 vendor/symfony/polyfill-mbstring/Mbstring.php delete mode 100644 vendor/symfony/polyfill-mbstring/README.md delete mode 100644 vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php delete mode 100644 vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php delete mode 100644 vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php delete mode 100644 vendor/symfony/polyfill-mbstring/bootstrap.php create mode 100644 vendor/topthink/think-installer/src/LibraryInstaller.php create mode 100644 vendor/topthink/think-installer/src/Promise.php diff --git a/composer.lock b/composer.lock index ffe365748..a28c77b3c 100644 --- a/composer.lock +++ b/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "aliyuncs/oss-sdk-php", - "version": "v2.3.1", + "version": "v2.4.1", "source": { "type": "git", "url": "https://github.com/aliyun/aliyun-oss-php-sdk.git", - "reference": "053d7ba9e798e4c09b9c5c1edab153d25ea9643a" + "reference": "492866331b7bafaac09506cf42f351b7e9e63766" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aliyun/aliyun-oss-php-sdk/zipball/053d7ba9e798e4c09b9c5c1edab153d25ea9643a", - "reference": "053d7ba9e798e4c09b9c5c1edab153d25ea9643a", + "url": "https://api.github.com/repos/aliyun/aliyun-oss-php-sdk/zipball/492866331b7bafaac09506cf42f351b7e9e63766", + "reference": "492866331b7bafaac09506cf42f351b7e9e63766", "shasum": "", "mirrors": [ { @@ -39,7 +39,7 @@ "OSS\\": "src/OSS" } }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -51,7 +51,11 @@ ], "description": "Aliyun OSS SDK for PHP", "homepage": "http://www.aliyun.com/product/oss/", - "time": "2019-11-15T11:05:42+00:00" + "support": { + "issues": "https://github.com/aliyun/aliyun-oss-php-sdk/issues", + "source": "https://github.com/aliyun/aliyun-oss-php-sdk/tree/v2.4.1" + }, + "time": "2020-09-29T06:23:57+00:00" }, { "name": "guzzle/guzzle", @@ -152,6 +156,10 @@ "rest", "web service" ], + "support": { + "issues": "https://github.com/guzzle/guzzle3/issues", + "source": "https://github.com/guzzle/guzzle3/tree/master" + }, "abandoned": "guzzlehttp/guzzle", "time": "2015-03-18T18:23:50+00:00" }, @@ -226,20 +234,24 @@ "rest", "web service" ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/6.5" + }, "time": "2020-06-16T21:01:06+00:00" }, { "name": "guzzlehttp/promises", - "version": "v1.3.1", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d", + "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d", "shasum": "", "mirrors": [ { @@ -249,10 +261,10 @@ ] }, "require": { - "php": ">=5.5.0" + "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "^4.0" + "symfony/phpunit-bridge": "^4.4 || ^5.1" }, "type": "library", "extra": { @@ -283,20 +295,24 @@ "keywords": [ "promise" ], - "time": "2016-12-20T10:07:11+00:00" + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.4.1" + }, + "time": "2021-03-07T09:25:29+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.6.1", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/35ea11d335fd638b5882ff1725228b3d35496ab1", + "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1", "shasum": "", "mirrors": [ { @@ -315,15 +331,15 @@ }, "require-dev": { "ext-zlib": "*", - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" }, "suggest": { - "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6-dev" + "dev-master": "1.7-dev" } }, "autoload": { @@ -360,20 +376,24 @@ "uri", "url" ], - "time": "2019-07-01T23:21:34+00:00" + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.8.1" + }, + "time": "2021-03-21T16:25:00+00:00" }, { "name": "nicolab/php-ftp-client", - "version": "v1.5.3", + "version": "v1.5.5", "source": { "type": "git", "url": "https://github.com/Nicolab/php-ftp-client.git", - "reference": "692ea47a87049cf6b4f4dbce935e0551364e0576" + "reference": "3c34d6beb4e31f29756ab92bc8436cd761f345d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Nicolab/php-ftp-client/zipball/692ea47a87049cf6b4f4dbce935e0551364e0576", - "reference": "692ea47a87049cf6b4f4dbce935e0551364e0576", + "url": "https://api.github.com/repos/Nicolab/php-ftp-client/zipball/3c34d6beb4e31f29756ab92bc8436cd761f345d3", + "reference": "3c34d6beb4e31f29756ab92bc8436cd761f345d3", "shasum": "", "mirrors": [ { @@ -415,20 +435,23 @@ "ssl", "ssl-ftp" ], - "time": "2020-03-09T13:56:46+00:00" + "support": { + "source": "https://github.com/Nicolab/php-ftp-client/tree/v1.5.5" + }, + "time": "2021-01-06T13:58:04+00:00" }, { "name": "phpmailer/phpmailer", - "version": "v6.1.7", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0" + "reference": "050d430203105c27c30efd1dce7aa421ad882d01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0", - "reference": "2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/050d430203105c27c30efd1dce7aa421ad882d01", + "reference": "050d430203105c27c30efd1dce7aa421ad882d01", "shasum": "", "mirrors": [ { @@ -440,15 +463,19 @@ "require": { "ext-ctype": "*", "ext-filter": "*", + "ext-hash": "*", "php": ">=5.5.0" }, "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "doctrine/annotations": "^1.2", - "friendsofphp/php-cs-fixer": "^2.2", - "phpunit/phpunit": "^4.8 || ^5.7" + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.5.6", + "yoast/phpunit-polyfills": "^0.2.0" }, "suggest": { - "ext-mbstring": "Needed to send email in multibyte encoding charset", + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", "league/oauth2-google": "Needed for Google XOAUTH2 authentication", "psr/log": "For optional PSR-3 debug logging", @@ -483,13 +510,17 @@ } ], "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.4.0" + }, "funding": [ { - "url": "https://github.com/synchro", + "url": "https://github.com/Synchro", "type": "github" } ], - "time": "2020-07-14T18:50:27+00:00" + "time": "2021-03-31T20:06:42+00:00" }, { "name": "psr/http-message", @@ -545,6 +576,9 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, "time": "2016-08-06T14:39:51+00:00" }, { @@ -597,20 +631,24 @@ "php", "qcloud" ], + "support": { + "issues": "https://github.com/tencentyun/cos-php-sdk-v5/issues", + "source": "https://github.com/tencentyun/cos-php-sdk-v5/tree/1.3" + }, "time": "2019-09-02T12:08:44+00:00" }, { "name": "qiniu/php-sdk", - "version": "v7.2.10", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/qiniu/php-sdk.git", - "reference": "d89987163f560ebf9dfa5bb25de9bd9b1a3b2bd8" + "reference": "0a461e13b09545b23df361843c6a65fdd3a26426" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/qiniu/php-sdk/zipball/d89987163f560ebf9dfa5bb25de9bd9b1a3b2bd8", - "reference": "d89987163f560ebf9dfa5bb25de9bd9b1a3b2bd8", + "url": "https://api.github.com/repos/qiniu/php-sdk/zipball/0a461e13b09545b23df361843c6a65fdd3a26426", + "reference": "0a461e13b09545b23df361843c6a65fdd3a26426", "shasum": "", "mirrors": [ { @@ -654,7 +692,11 @@ "sdk", "storage" ], - "time": "2019-10-28T10:23:23+00:00" + "support": { + "issues": "https://github.com/qiniu/php-sdk/issues", + "source": "https://github.com/qiniu/php-sdk/tree/v7.3.0" + }, + "time": "2020-09-24T07:31:29+00:00" }, { "name": "ralouphie/getallheaders", @@ -700,6 +742,10 @@ } ], "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, "time": "2019-03-08T08:55:37+00:00" }, { @@ -750,7 +796,7 @@ "/Tests/" ] }, - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -766,20 +812,23 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v2.8.50" + }, "time": "2018-11-21T14:20:20+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.17.1", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "a57f8161502549a742a63c09f0a604997bf47027" + "reference": "2d63434d922daf7da8dd863e7907e67ee3031483" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a57f8161502549a742a63c09f0a604997bf47027", - "reference": "a57f8161502549a742a63c09f0a604997bf47027", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/2d63434d922daf7da8dd863e7907e67ee3031483", + "reference": "2d63434d922daf7da8dd863e7907e67ee3031483", "shasum": "", "mirrors": [ { @@ -789,8 +838,8 @@ ] }, "require": { - "php": ">=5.3.3", - "symfony/polyfill-mbstring": "^1.3", + "php": ">=7.1", + "symfony/polyfill-intl-normalizer": "^1.10", "symfony/polyfill-php72": "^1.10" }, "suggest": { @@ -799,7 +848,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.17-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -823,6 +872,10 @@ "name": "Laurent Bassin", "email": "laurent@bassin.info" }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" @@ -838,6 +891,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.22.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -852,20 +908,20 @@ "type": "tidelift" } ], - "time": "2020-06-06T08:46:27+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { - "name": "symfony/polyfill-mbstring", - "version": "v1.17.1", + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.22.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "7110338d81ce1cbc3e273136e4574663627037a7" + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7110338d81ce1cbc3e273136e4574663627037a7", - "reference": "7110338d81ce1cbc3e273136e4574663627037a7", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248", + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248", "shasum": "", "mirrors": [ { @@ -875,15 +931,15 @@ ] }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { - "ext-mbstring": "For best performance" + "ext-intl": "For best performance" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.17-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -892,10 +948,13 @@ }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, "files": [ "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -912,15 +971,19 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for the Mbstring extension", + "description": "Symfony polyfill for intl's Normalizer class and related functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "mbstring", + "intl", + "normalizer", "polyfill", "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -935,20 +998,20 @@ "type": "tidelift" } ], - "time": "2020-06-06T08:46:27+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.17.1", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "3d9c70ff1b9f6bb618f9954b2f7f760220c2b38a" + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/3d9c70ff1b9f6bb618f9954b2f7f760220c2b38a", - "reference": "3d9c70ff1b9f6bb618f9954b2f7f760220c2b38a", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", "shasum": "", "mirrors": [ { @@ -958,12 +1021,12 @@ ] }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.17-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1000,6 +1063,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.22.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1014,20 +1080,20 @@ "type": "tidelift" } ], - "time": "2020-06-06T08:46:27+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "topthink/framework", - "version": "v5.1.39", + "version": "v5.1.41", "source": { "type": "git", "url": "https://github.com/top-think/framework.git", - "reference": "5762858f3d58faafb3a39427f8788884b2927007" + "reference": "7137741a323a4a60cfca334507cd1812fac91bb2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/framework/zipball/5762858f3d58faafb3a39427f8788884b2927007", - "reference": "5762858f3d58faafb3a39427f8788884b2927007", + "url": "https://api.github.com/repos/top-think/framework/zipball/7137741a323a4a60cfca334507cd1812fac91bb2", + "reference": "7137741a323a4a60cfca334507cd1812fac91bb2", "shasum": "", "mirrors": [ { @@ -1050,7 +1116,7 @@ "squizlabs/php_codesniffer": "2.*" }, "type": "think-framework", - "notification-url": "https://repo.packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], @@ -1071,7 +1137,11 @@ "orm", "thinkphp" ], - "time": "2019-11-17T23:22:02+00:00" + "support": { + "issues": "https://github.com/top-think/framework/issues", + "source": "https://github.com/top-think/framework/tree/v5.1.41" + }, + "time": "2021-01-11T02:51:29+00:00" }, { "name": "topthink/think-captcha", @@ -1116,6 +1186,10 @@ } ], "description": "captcha package for thinkphp5", + "support": { + "issues": "https://github.com/top-think/think-captcha/issues", + "source": "https://github.com/top-think/think-captcha/tree/2.0" + }, "time": "2017-12-31T16:37:49+00:00" }, { @@ -1162,20 +1236,24 @@ } ], "description": "The ThinkPHP5 Image Package", + "support": { + "issues": "https://github.com/top-think/think-image/issues", + "source": "https://github.com/top-think/think-image/tree/master" + }, "time": "2016-09-29T06:05:43+00:00" }, { "name": "topthink/think-installer", - "version": "v2.0.0", + "version": "v2.0.5", "source": { "type": "git", "url": "https://github.com/top-think/think-installer.git", - "reference": "f5400a12c60e513911aef41fe443fa6920952675" + "reference": "38ba647706e35d6704b5d370c06f8a160b635f88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/think-installer/zipball/f5400a12c60e513911aef41fe443fa6920952675", - "reference": "f5400a12c60e513911aef41fe443fa6920952675", + "url": "https://api.github.com/repos/top-think/think-installer/zipball/38ba647706e35d6704b5d370c06f8a160b635f88", + "reference": "38ba647706e35d6704b5d370c06f8a160b635f88", "shasum": "", "mirrors": [ { @@ -1185,10 +1263,10 @@ ] }, "require": { - "composer-plugin-api": "^1.0" + "composer-plugin-api": "^1.0||^2.0" }, "require-dev": { - "composer/composer": "1.0.*@dev" + "composer/composer": "^1.0||^2.0" }, "type": "composer-plugin", "extra": { @@ -1209,7 +1287,11 @@ "email": "448901948@qq.com" } ], - "time": "2018-05-11T06:45:42+00:00" + "support": { + "issues": "https://github.com/top-think/think-installer/issues", + "source": "https://github.com/top-think/think-installer/tree/v2.0.5" + }, + "time": "2021-01-14T12:12:14+00:00" }, { "name": "upyun/sdk", @@ -1275,6 +1357,10 @@ "sdk", "upyun" ], + "support": { + "issues": "https://github.com/upyun/php-sdk/issues", + "source": "https://github.com/upyun/php-sdk/tree/master" + }, "time": "2020-04-22T06:08:39+00:00" } ], @@ -1288,5 +1374,5 @@ "php": ">=5.6.0" }, "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.0.0" } diff --git a/thinkphp/README.md b/thinkphp/README.md index b2a791b8b..1339e6c7b 100644 --- a/thinkphp/README.md +++ b/thinkphp/README.md @@ -35,7 +35,7 @@ ThinkPHP5.1对底层架构做了进一步的改进,减少依赖,其主要特 + 内置控制器扩展类 + 模型自动验证 -> ThinkPHP5.1的运行环境要求PHP5.6+。 +> ThinkPHP5.1的运行环境要求PHP5.6+ 兼容PHP8.0。 ## 安装 @@ -70,6 +70,12 @@ composer update topthink/framework + [完全开发手册](https://www.kancloud.cn/manual/thinkphp5_1/content) + [升级指导](https://www.kancloud.cn/manual/thinkphp5_1/354155) + +## 官方服务 + ++ [应用服务市场](https://market.topthink.com/) ++ [ThinkAPI——统一API服务](https://docs.topthink.com/think-api) + ## 命名规范 `ThinkPHP5.1`遵循PSR-2命名规范和PSR-4自动加载规范。 diff --git a/thinkphp/library/think/App.php b/thinkphp/library/think/App.php index 5cd55a8b7..35924a5ba 100644 --- a/thinkphp/library/think/App.php +++ b/thinkphp/library/think/App.php @@ -20,7 +20,7 @@ */ class App extends Container { - const VERSION = '5.1.39 LTS'; + const VERSION = '5.1.41 LTS'; /** * 当前模块路径 @@ -548,12 +548,10 @@ public function config($name = '') public function routeInit() { // 路由检测 - $files = scandir($this->routePath); - foreach ($files as $file) { - if (strpos($file, '.php')) { - $filename = $this->routePath . $file; - // 导入路由配置 - $rules = include $filename; + if (is_dir($this->routePath)) { + $files = glob($this->routePath . '*.php'); + foreach ($files as $file) { + $rules = include $file; if (is_array($rules)) { $this->route->import($rules); } diff --git a/thinkphp/library/think/Collection.php b/thinkphp/library/think/Collection.php index 8251fc8f1..d7454ec59 100644 --- a/thinkphp/library/think/Collection.php +++ b/thinkphp/library/think/Collection.php @@ -400,7 +400,7 @@ public function where($field, $operator, $value = null) */ public function column($columnKey, $indexKey = null) { - return array_column($this->items, $columnKey, $indexKey); + return array_column($this->toArray(), $columnKey, $indexKey); } /** diff --git a/thinkphp/library/think/Container.php b/thinkphp/library/think/Container.php index cd7954c06..91b32aa63 100644 --- a/thinkphp/library/think/Container.php +++ b/thinkphp/library/think/Container.php @@ -461,6 +461,25 @@ protected function bindParams($reflect, $vars = []) $type = key($vars) === 0 ? 1 : 0; $params = $reflect->getParameters(); + if (PHP_VERSION > 8.0) { + $args = $this->parseParamsForPHP8($params, $vars, $type); + } else { + $args = $this->parseParams($params, $vars, $type); + } + + return $args; + } + + /** + * 解析参数 + * @access protected + * @param array $params 参数列表 + * @param array $vars 参数数据 + * @param int $type 参数类别 + * @return array + */ + protected function parseParams($params, $vars, $type) + { foreach ($params as $param) { $name = $param->getName(); $lowerName = Loader::parseName($name); @@ -480,7 +499,38 @@ protected function bindParams($reflect, $vars = []) throw new InvalidArgumentException('method param miss:' . $name); } } + return $args; + } + + /** + * 解析参数 + * @access protected + * @param array $params 参数列表 + * @param array $vars 参数数据 + * @param int $type 参数类别 + * @return array + */ + protected function parseParamsForPHP8($params, $vars, $type) + { + foreach ($params as $param) { + $name = $param->getName(); + $lowerName = Loader::parseName($name); + $reflectionType = $param->getType(); + if ($reflectionType && $reflectionType->isBuiltin() === false) { + $args[] = $this->getObjectParam($reflectionType->getName(), $vars); + } elseif (1 == $type && !empty($vars)) { + $args[] = array_shift($vars); + } elseif (0 == $type && array_key_exists($name, $vars)) { + $args[] = $vars[$name]; + } elseif (0 == $type && array_key_exists($lowerName, $vars)) { + $args[] = $vars[$lowerName]; + } elseif ($param->isDefaultValueAvailable()) { + $args[] = $param->getDefaultValue(); + } else { + throw new InvalidArgumentException('method param miss:' . $name); + } + } return $args; } diff --git a/thinkphp/library/think/Model.php b/thinkphp/library/think/Model.php index 93be3dc01..4544ab21f 100644 --- a/thinkphp/library/think/Model.php +++ b/thinkphp/library/think/Model.php @@ -18,34 +18,43 @@ * Class Model * @package think * @mixin Query - * @method Query where(mixed $field, string $op = null, mixed $condition = null) static 查询条件 - * @method Query whereRaw(string $where, array $bind = []) static 表达式查询 - * @method Query whereExp(string $field, string $condition, array $bind = []) static 字段表达式查询 - * @method Query when(mixed $condition, mixed $query, mixed $otherwise = null) static 条件查询 - * @method Query join(mixed $join, mixed $condition = null, string $type = 'INNER') static JOIN查询 - * @method Query view(mixed $join, mixed $field = null, mixed $on = null, string $type = 'INNER') static 视图查询 - * @method Query with(mixed $with) static 关联预载入 - * @method Query count(string $field) static Count统计查询 - * @method Query min(string $field) static Min统计查询 - * @method Query max(string $field) static Max统计查询 - * @method Query sum(string $field) static SUM统计查询 - * @method Query avg(string $field) static Avg统计查询 - * @method Query field(mixed $field, boolean $except = false) static 指定查询字段 - * @method Query fieldRaw(string $field, array $bind = []) static 指定查询字段 - * @method Query union(mixed $union, boolean $all = false) static UNION查询 - * @method Query limit(mixed $offset, integer $length = null) static 查询LIMIT - * @method Query order(mixed $field, string $order = null) static 查询ORDER - * @method Query orderRaw(string $field, array $bind = []) static 查询ORDER - * @method Query cache(mixed $key = null , integer $expire = null) static 设置查询缓存 - * @method mixed value(string $field) static 获取某个字段的值 + * @method $this scope(string|array $scope) static 查询范围 + * @method $this where(mixed $field, string $op = null, mixed $condition = null) static 查询条件 + * @method $this whereRaw(string $where, array $bind = [], string $logic = 'AND') static 表达式查询 + * @method $this whereExp(string $field, string $condition, array $bind = [], string $logic = 'AND') static 字段表达式查询 + * @method $this when(mixed $condition, mixed $query, mixed $otherwise = null) static 条件查询 + * @method $this join(mixed $join, mixed $condition = null, string $type = 'INNER', array $bind = []) static JOIN查询 + * @method $this view(mixed $join, mixed $field = null, mixed $on = null, string $type = 'INNER') static 视图查询 + * @method $this with(mixed $with, callable $callback = null) static 关联预载入 + * @method $this count(string $field = '*') static Count统计查询 + * @method $this min(string $field, bool $force = true) static Min统计查询 + * @method $this max(string $field, bool $force = true) static Max统计查询 + * @method $this sum(string $field) static SUM统计查询 + * @method $this avg(string $field) static Avg统计查询 + * @method $this field(mixed $field, boolean $except = false, string $tableName = '', string $prefix = '', string $alias = '') static 指定查询字段 + * @method $this fieldRaw(string $field) static 指定查询字段 + * @method $this union(mixed $union, boolean $all = false) static UNION查询 + * @method $this limit(mixed $offset, integer $length = null) static 查询LIMIT + * @method $this order(mixed $field, string $order = null) static 查询ORDER + * @method $this orderRaw(string $field, array $bind = []) static 查询ORDER + * @method $this cache(mixed $key = null , integer|\DateTime $expire = null, string $tag = null) static 设置查询缓存 + * @method mixed value(string $field, mixed $default = null) static 获取某个字段的值 * @method array column(string $field, string $key = '') static 获取某个列的值 - * @method mixed find(mixed $data = null) static 查询单个记录 - * @method mixed select(mixed $data = null) static 查询多个记录 - * @method mixed get(mixed $data = null,mixed $with =[],bool $cache= false) static 查询单个记录 支持关联预载入 - * @method mixed getOrFail(mixed $data = null,mixed $with =[],bool $cache= false) static 查询单个记录 不存在则抛出异常 - * @method mixed findOrEmpty(mixed $data = null,mixed $with =[],bool $cache= false) static 查询单个记录 不存在则返回空模型 - * @method mixed all(mixed $data = null,mixed $with =[],bool $cache= false) static 查询多个记录 支持关联预载入 - * @method \think\Model withAttr(array $name,\Closure $closure) 动态定义获取器 + * @method $this find(mixed $data = null) static 查询单个记录 + * @method $this findOrFail(mixed $data = null) 查询单个记录 + * @method Collection|$this[] select(mixed $data = null) static 查询多个记录 + * @method $this get(mixed $data = null,mixed $with = [],bool $cache = false, bool $failException = false) static 查询单个记录 支持关联预载入 + * @method $this getOrFail(mixed $data = null,mixed $with = [],bool $cache = false) static 查询单个记录 不存在则抛出异常 + * @method $this findOrEmpty(mixed $data = null) static 查询单个记录 不存在则返回空模型 + * @method Collection|$this[] all(mixed $data = null,mixed $with = [],bool $cache = false) static 查询多个记录 支持关联预载入 + * @method $this withAttr(array $name,\Closure $closure = null) static 动态定义获取器 + * @method $this withJoin(string|array $with, string $joinType = '') static + * @method $this withCount(string|array $relation, bool $subQuery = true) static 关联统计 + * @method $this withSum(string|array $relation, string $field, bool $subQuery = true) static 关联SUM统计 + * @method $this withMax(string|array $relation, string $field, bool $subQuery = true) static 关联MAX统计 + * @method $this withMin(string|array $relation, string $field, bool $subQuery = true) static 关联Min统计 + * @method $this withAvg(string|array $relation, string $field, bool $subQuery = true) static 关联Avg统计 + * @method Paginator|$this paginate() static 分页 */ abstract class Model implements \JsonSerializable, \ArrayAccess { diff --git a/thinkphp/library/think/Request.php b/thinkphp/library/think/Request.php index 92a401d73..6b6dd4b41 100644 --- a/thinkphp/library/think/Request.php +++ b/thinkphp/library/think/Request.php @@ -1800,7 +1800,7 @@ public function setHost($host) public function host($strict = false) { if (!$this->host) { - $this->host = $this->server('HTTP_X_REAL_HOST') ?: $this->server('HTTP_HOST'); + $this->host = $this->server('HTTP_X_REAL_HOST') ?: $this->server('HTTP_X_FORWARDED_HOST') ?: $this->server('HTTP_HOST'); } return true === $strict && strpos($this->host, ':') ? strstr($this->host, ':', true) : $this->host; diff --git a/thinkphp/library/think/Route.php b/thinkphp/library/think/Route.php index 44af9871b..97f6dc7d4 100644 --- a/thinkphp/library/think/Route.php +++ b/thinkphp/library/think/Route.php @@ -13,9 +13,11 @@ use think\exception\RouteNotFoundException; use think\route\AliasRule; +use think\route\Dispatch; use think\route\dispatch\Url as UrlDispatch; use think\route\Domain; use think\route\Resource; +use think\route\Rule; use think\route\RuleGroup; use think\route\RuleItem; diff --git a/thinkphp/library/think/Validate.php b/thinkphp/library/think/Validate.php index f58d7a88d..5fde7f310 100644 --- a/thinkphp/library/think/Validate.php +++ b/thinkphp/library/think/Validate.php @@ -408,6 +408,7 @@ public function check($data, $rules = [], $scene = '') foreach ($this->append as $key => $rule) { if (!isset($rules[$key])) { $rules[$key] = $rule; + unset($this->append[$key]); } } @@ -520,6 +521,7 @@ protected function checkItem($field, $value, $rules, $data, $title = '', $msg = if (isset($this->append[$field])) { // 追加额外的验证规则 $rules = array_unique(array_merge($rules, $this->append[$field]), SORT_REGULAR); + unset($this->append[$field]); } $i = 0; diff --git a/thinkphp/library/think/cache/driver/Redis.php b/thinkphp/library/think/cache/driver/Redis.php index 813746e77..4eff2cf5e 100644 --- a/thinkphp/library/think/cache/driver/Redis.php +++ b/thinkphp/library/think/cache/driver/Redis.php @@ -90,7 +90,7 @@ public function __construct($options = []) */ public function has($name) { - return $this->handler->exists($this->getCacheKey($name)); + return $this->handler->exists($this->getCacheKey($name)) ? true : false; } /** diff --git a/thinkphp/library/think/db/Builder.php b/thinkphp/library/think/db/Builder.php index a0faada87..60b470e86 100644 --- a/thinkphp/library/think/db/Builder.php +++ b/thinkphp/library/think/db/Builder.php @@ -684,7 +684,7 @@ protected function parseIn(Query $query, $key, $exp, $value, $field, $bindType) */ protected function parseClosure(Query $query, $call, $show = true) { - $newQuery = $query->newQuery()->setConnection($this->connection); + $newQuery = $query->newQuery()->removeOption(); $call($newQuery); return $newQuery->buildSql($show); diff --git a/thinkphp/library/think/db/Query.php b/thinkphp/library/think/db/Query.php index 0c3df8995..ba082794a 100644 --- a/thinkphp/library/think/db/Query.php +++ b/thinkphp/library/think/db/Query.php @@ -1764,7 +1764,7 @@ public function page($page, $listRows = null) * var_page:分页变量, * list_rows:每页数量 * type:分页类名 - * @return \think\Paginator + * @return $this[]|\think\Paginator * @throws DbException */ public function paginate($listRows = null, $simple = false, $config = []) @@ -3464,7 +3464,7 @@ public function findOrFail($data = null) } /** - * 查找单条记录 如果不存在则抛出异常 + * 查找单条记录 不存在则返回空模型 * @access public * @param array|string|Query|\Closure $data * @return array|\PDOStatement|string|Model diff --git a/thinkphp/library/think/db/builder/Mysql.php b/thinkphp/library/think/db/builder/Mysql.php index af364dff0..f7384b31e 100644 --- a/thinkphp/library/think/db/builder/Mysql.php +++ b/thinkphp/library/think/db/builder/Mysql.php @@ -125,7 +125,13 @@ public function parseKey(Query $query, $key, $strict = false) $key = trim($key); - if (strpos($key, '->') && false === strpos($key, '(')) { + if(strpos($key, '->>') && false === strpos($key, '(')){ + // JSON字段支持 + list($field, $name) = explode('->>', $key, 2); + + return $this->parseKey($query, $field, true) . '->>\'$' . (strpos($name, '[') === 0 ? '' : '.') . str_replace('->>', '.', $name) . '\''; + } + elseif (strpos($key, '->') && false === strpos($key, '(')) { // JSON字段支持 list($field, $name) = explode('->', $key, 2); diff --git a/thinkphp/library/think/db/connector/Mysql.php b/thinkphp/library/think/db/connector/Mysql.php index 1713b99b9..cfd2ac72b 100644 --- a/thinkphp/library/think/db/connector/Mysql.php +++ b/thinkphp/library/think/db/connector/Mysql.php @@ -97,10 +97,10 @@ public function getFields($tableName) $info[$val['field']] = [ 'name' => $val['field'], 'type' => $val['type'], - 'notnull' => (bool) ('' === $val['null']), // not null is empty, null is yes + 'notnull' => 'NO' == $val['null'], 'default' => $val['default'], - 'primary' => (strtolower($val['key']) == 'pri'), - 'autoinc' => (strtolower($val['extra']) == 'auto_increment'), + 'primary' => strtolower($val['key']) == 'pri', + 'autoinc' => strtolower($val['extra']) == 'auto_increment', ]; } } @@ -187,7 +187,7 @@ public function startTransXa($xid) return false; } - $this->execute("XA START '$xid'"); + $this->linkID->exec("XA START '$xid'"); } /** @@ -199,8 +199,8 @@ public function startTransXa($xid) public function prepareXa($xid) { $this->initConnect(true); - $this->execute("XA END '$xid'"); - $this->execute("XA PREPARE '$xid'"); + $this->linkID->exec("XA END '$xid'"); + $this->linkID->exec("XA PREPARE '$xid'"); } /** @@ -212,7 +212,7 @@ public function prepareXa($xid) public function commitXa($xid) { $this->initConnect(true); - $this->execute("XA COMMIT '$xid'"); + $this->linkID->exec("XA COMMIT '$xid'"); } /** @@ -224,6 +224,6 @@ public function commitXa($xid) public function rollbackXa($xid) { $this->initConnect(true); - $this->execute("XA ROLLBACK '$xid'"); + $this->linkID->exec("XA ROLLBACK '$xid'"); } } diff --git a/thinkphp/library/think/facade/Route.php b/thinkphp/library/think/facade/Route.php index 77196dfe4..6457ba4b8 100644 --- a/thinkphp/library/think/facade/Route.php +++ b/thinkphp/library/think/facade/Route.php @@ -27,7 +27,7 @@ * @method void import(array $rules, string $type = '*') static 导入配置文件的路由规则 * @method \think\route\RuleItem rule(string $rule, mixed $route, string $method = '*', array $option = [], array $pattern = []) static 注册路由规则 * @method void rules(array $rules, string $method = '*', array $option = [], array $pattern = []) static 批量注册路由规则 - * @method \think\route\RuleGroup group(string|array $name, mixed $route, string $method = '*', array $option = [], array $pattern = []) static 注册路由分组 + * @method \think\route\RuleGroup group(string|array $name, array|\Closure $route, array $method = '*', array $option = [], array $pattern = []) static 注册路由分组 * @method \think\route\RuleItem any(string $rule, mixed $route, array $option = [], array $pattern = []) static 注册路由 * @method \think\route\RuleItem get(string $rule, mixed $route, array $option = [], array $pattern = []) static 注册路由 * @method \think\route\RuleItem post(string $rule, mixed $route, array $option = [], array $pattern = []) static 注册路由 diff --git a/thinkphp/library/think/model/Collection.php b/thinkphp/library/think/model/Collection.php index 34ec067e7..fc0967cfe 100644 --- a/thinkphp/library/think/model/Collection.php +++ b/thinkphp/library/think/model/Collection.php @@ -32,6 +32,22 @@ public function load($relation) return $this; } + /** + * 绑定(一对一)关联属性到当前模型 + * @access protected + * @param string $relation 关联名称 + * @param array $attrs 绑定属性 + * @return $this + */ + public function bindAttr($relation, array $attrs = []) + { + $this->each(function (Model $model) use ($relation, $attrs) { + $model->bindAttr($relation, $attrs); + }); + + return $this; + } + /** * 设置需要隐藏的输出属性 * @access public diff --git a/thinkphp/library/think/model/concern/Conversion.php b/thinkphp/library/think/model/concern/Conversion.php index 28a6f9991..de4db9311 100644 --- a/thinkphp/library/think/model/concern/Conversion.php +++ b/thinkphp/library/think/model/concern/Conversion.php @@ -87,7 +87,7 @@ public function appendRelationAttr($attr, $append) if (isset($this->data[$key])) { throw new Exception('bind attr has exists:' . $key); } else { - $this->data[$key] = $model->$attr; + $this->data[$key] = $model->getAttr($attr); } } } diff --git a/thinkphp/library/think/model/concern/RelationShip.php b/thinkphp/library/think/model/concern/RelationShip.php index 9ca709a5e..48579b700 100644 --- a/thinkphp/library/think/model/concern/RelationShip.php +++ b/thinkphp/library/think/model/concern/RelationShip.php @@ -13,6 +13,7 @@ use think\Collection; use think\db\Query; +use think\Exception; use think\Loader; use think\Model; use think\model\Relation; @@ -115,6 +116,32 @@ public function setRelation($name, $value, $data = []) return $this; } + /** + * 绑定(一对一)关联属性到当前模型 + * @access protected + * @param string $relation 关联名称 + * @param array $attrs 绑定属性 + * @return $this + * @throws Exception + */ + public function bindAttr($relation, array $attrs = []) + { + $relation = $this->getRelation($relation); + + foreach ($attrs as $key => $attr) { + $key = is_numeric($key) ? $attr : $key; + $value = $this->getOrigin($key); + + if (!is_null($value)) { + throw new Exception('bind attr has exists:' . $key); + } + + $this->setAttr($key, $relation ? $relation->getAttr($attr) : null); + } + + return $this; + } + /** * 关联数据写入 * @access public diff --git a/thinkphp/library/think/model/concern/SoftDelete.php b/thinkphp/library/think/model/concern/SoftDelete.php index 679aa34c4..ec866ac06 100644 --- a/thinkphp/library/think/model/concern/SoftDelete.php +++ b/thinkphp/library/think/model/concern/SoftDelete.php @@ -139,6 +139,10 @@ public function delete($force = false) */ public static function destroy($data, $force = false) { + // 传入空不执行删除,但是0可以删除 + if (empty($data) && 0 !== $data) { + return false; + } // 包含软删除数据 $query = (new static())->db(false); diff --git a/thinkphp/library/think/model/relation/BelongsToMany.php b/thinkphp/library/think/model/relation/BelongsToMany.php index 2d64f683c..6105e233c 100644 --- a/thinkphp/library/think/model/relation/BelongsToMany.php +++ b/thinkphp/library/think/model/relation/BelongsToMany.php @@ -19,6 +19,7 @@ use think\Model; use think\model\Pivot; use think\model\Relation; +use think\Paginator; class BelongsToMany extends Relation { @@ -582,7 +583,7 @@ public function attach($data, $pivot = []) * 判断是否存在关联数据 * @access public * @param mixed $data 数据 可以使用关联模型对象 或者 关联对象的主键 - * @return Pivot + * @return Pivot|false * @throws Exception */ public function attached($data) diff --git a/thinkphp/library/think/model/relation/HasManyThrough.php b/thinkphp/library/think/model/relation/HasManyThrough.php index 6e39f2ad5..be0b0cd9a 100644 --- a/thinkphp/library/think/model/relation/HasManyThrough.php +++ b/thinkphp/library/think/model/relation/HasManyThrough.php @@ -81,7 +81,7 @@ public function getRelation($subRelation = '', $closure = null) */ public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') { - $model = App::parseName(App::classBaseName($this->parent)); + $model = Loader::parseName(basename(str_replace('\\', '/', get_class($this->parent)))); $throughTable = $this->through->getTable(); $pk = $this->throughPk; $throughKey = $this->throughKey; @@ -114,7 +114,7 @@ public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER' */ public function hasWhere($where = [], $fields = null) { - $model = App::parseName(App::classBaseName($this->parent)); + $model = Loader::parseName(basename(str_replace('\\', '/', get_class($this->parent)))); $throughTable = $this->through->getTable(); $pk = $this->throughPk; $throughKey = $this->throughKey; @@ -169,7 +169,7 @@ public function eagerlyResultSet(array &$resultSet, $relation, $subRelation = '' ], $foreignKey, $relation, $subRelation, $closure); // 关联属性名 - $attr = App::parseName($relation); + $attr = Loader::parseName($relation); // 关联数据封装 foreach ($resultSet as $result) { @@ -218,7 +218,7 @@ public function eagerlyResult($result, $relation, $subRelation = '', $closure = $relationModel->setParent(clone $result); } - $result->setRelation(App::parseName($relation), $this->resultSetBuild($data[$pk])); + $result->setRelation(Loader::parseName($relation), $this->resultSetBuild($data[$pk])); } /** @@ -279,7 +279,7 @@ public function relationCount($result, $closure, $aggregate = 'count', $field = } } - $alias = App::parseName(App::classBaseName($this->model)); + $alias = Loader::parseName(basename(str_replace('\\', '/', $this->model))); $throughTable = $this->through->getTable(); $pk = $this->throughPk; $throughKey = $this->throughKey; @@ -315,7 +315,7 @@ public function getRelationCountQuery($closure = null, $aggregate = 'count', $fi } } - $alias = App::parseName(App::classBaseName($this->model)); + $alias = Loader::parseName(basename(str_replace('\\', '/', $this->model))); $throughTable = $this->through->getTable(); $pk = $this->throughPk; $throughKey = $this->throughKey; diff --git a/thinkphp/library/think/model/relation/HasOne.php b/thinkphp/library/think/model/relation/HasOne.php index e036bba4e..fe09443c9 100644 --- a/thinkphp/library/think/model/relation/HasOne.php +++ b/thinkphp/library/think/model/relation/HasOne.php @@ -144,7 +144,7 @@ public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER' return $this->parent->db() ->alias($model) - ->whereExists(function ($query) use ($table, $model, $relation, $localKey, $foreignKey) { + ->whereExists(function ($query) use ($table, $model, $relation, $localKey, $foreignKey, $softDelete) { $query->table([$table => $relation]) ->field($relation . '.' . $foreignKey) ->whereExp($model . '.' . $localKey, '=' . $relation . '.' . $foreignKey) diff --git a/thinkphp/library/think/model/relation/MorphTo.php b/thinkphp/library/think/model/relation/MorphTo.php index 17771ce86..0786c2fe0 100644 --- a/thinkphp/library/think/model/relation/MorphTo.php +++ b/thinkphp/library/think/model/relation/MorphTo.php @@ -186,8 +186,16 @@ public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) foreach ($range as $key => $val) { // 多态类型映射 $model = $this->parseModel($key); - $obj = new $model; + $obj = (new $model)->db(); $pk = $obj->getPk(); + // 预载入关联查询 支持嵌套预载入 + if ($closure instanceof \Closure) { + $closure($obj); + + if ($field = $obj->getOptions('with_field')) { + $obj->field($field)->removeOption('with_field'); + } + } $list = $obj->all($val, $subRelation); $data = []; diff --git a/thinkphp/library/think/model/relation/OneToOne.php b/thinkphp/library/think/model/relation/OneToOne.php index a0333c863..5e22b8002 100644 --- a/thinkphp/library/think/model/relation/OneToOne.php +++ b/thinkphp/library/think/model/relation/OneToOne.php @@ -282,20 +282,22 @@ protected function match($model, $relation, &$result) /** * 绑定关联属性到父模型 * @access protected - * @param Model $model 关联模型对象 - * @param Model $result 父模型对象 + * @param Model $result 关联模型对象 + * @param Model $model 父模型对象 * @return void * @throws Exception */ protected function bindAttr($model, &$result) { foreach ($this->bindAttr as $key => $attr) { - $key = is_numeric($key) ? $attr : $key; - if (isset($result->$key)) { + $key = is_numeric($key) ? $attr : $key; + $value = $result->getOrigin($key); + + if (!is_null($value)) { throw new Exception('bind attr has exists:' . $key); - } else { - $result->setAttr($key, $model ? $model->$attr : null); } + + $result->setAttr($key, $model ? $model->getAttr($attr) : null); } } diff --git a/thinkphp/library/think/route/Domain.php b/thinkphp/library/think/route/Domain.php index 80950dc28..923d9b427 100644 --- a/thinkphp/library/think/route/Domain.php +++ b/thinkphp/library/think/route/Domain.php @@ -13,6 +13,7 @@ use think\Container; use think\Loader; +use think\Request; use think\Route; use think\route\dispatch\Callback as CallbackDispatch; use think\route\dispatch\Controller as ControllerDispatch; diff --git a/vendor/aliyuncs/oss-sdk-php/CHANGELOG.md b/vendor/aliyuncs/oss-sdk-php/CHANGELOG.md index d349d907b..eb626b1c7 100644 --- a/vendor/aliyuncs/oss-sdk-php/CHANGELOG.md +++ b/vendor/aliyuncs/oss-sdk-php/CHANGELOG.md @@ -1,6 +1,32 @@ # ChangeLog - Aliyun OSS SDK for PHP -## v2.3.1 / 2019-011-15 +## v2.4.1 / 2020-09-29 +* Fixed: the getBucketPolicy bug. + + +## v2.4.0 / 2020-08-31 + +* Added: disable Expect: 100-continue +* Added: support getBucketInfo +* Added: support getBucketStat +* Added: support bucket policy +* Added: support bucket encryption +* Added: support bucket tagging +* Added: support bucket worm +* Added: support versioning +* Added: support request payment +* Added: support object tagging +* Added: support code archive +* Added: support process object +* Added: support traffic limit paramter +* Added: support upload object from file handle +* Added: support getSimplifiedObjectMeta +* Fixed: the object name can not be '0' stirng. +* Update: endpoint validity check +* Update: add new pre-signed url api + + +## v2.3.1 / 2019-01-15 * translate chinese comments into english * Added: endpoint validity check diff --git a/vendor/aliyuncs/oss-sdk-php/README-CN.md b/vendor/aliyuncs/oss-sdk-php/README-CN.md index 8c0cf8430..89c1e5ae8 100644 --- a/vendor/aliyuncs/oss-sdk-php/README-CN.md +++ b/vendor/aliyuncs/oss-sdk-php/README-CN.md @@ -111,7 +111,7 @@ OssClient提供的接口返回返回数据分为两种: $bucketListInfo = $ossClient->listBuckets(); $bucketList = $bucketListInfo->getBucketList(); foreach($bucketList as $bucket) { - print($bucket->getLocation() . "\t" . $bucket->getName() . "\t" . $bucket->getCreatedate() . "\n"); + print($bucket->getLocation() . "\t" . $bucket->getName() . "\t" . $bucket->getCreateDate() . "\n"); } ``` 上面代码中的$bucketListInfo的数据类型是 `OSS\Model\BucketListInfo` diff --git a/vendor/aliyuncs/oss-sdk-php/README.md b/vendor/aliyuncs/oss-sdk-php/README.md index 3c1da2633..b77a35614 100644 --- a/vendor/aliyuncs/oss-sdk-php/README.md +++ b/vendor/aliyuncs/oss-sdk-php/README.md @@ -1,4 +1,4 @@ -# Alibaba Cloud OSS SDK for PHP +# Alibaba Cloud OSS SDK for PHP [![Latest Stable Version](https://poser.pugx.org/aliyuncs/oss-sdk-php/v/stable)](https://packagist.org/packages/aliyuncs/oss-sdk-php) [![Build Status](https://travis-ci.org/aliyun/aliyun-oss-php-sdk.svg?branch=master)](https://travis-ci.org/aliyun/aliyun-oss-php-sdk) @@ -50,12 +50,12 @@ Tips: | Class | Explanation | |:------------------|:------------------------------------| -|OSS\OSSClient | OSS client class. An OSSClient instance can be used to call the interface. | -|OSS\Core\OSSException |OSS Exception class . You only need to pay attention to this exception when you use the OSSClient. | +|OSS\OssClient | OSS client class. An OssClient instance can be used to call the interface. | +|OSS\Core\OssException |OSS Exception class . You only need to pay attention to this exception when you use the OssClient. | -### Initialize an OSSClient +### Initialize an OssClient -The SDK's operations for the OSS are performed through the OSSClient class. The code below creates an OSSClient object: +The SDK's operations for the OSS are performed through the OssClient class. The code below creates an OssClient object: ```php listBuckets(); $bucketList = $bucketListInfo->getBucketList(); foreach($bucketList as $bucket) { - print($bucket->getLocation() . "\t" . $bucket->getName() . "\t" . $bucket->getCreatedate() . "\n"); + print($bucket->getLocation() . "\t" . $bucket->getName() . "\t" . $bucket->getCreateDate() . "\n"); } ``` In the above code, $bucketListInfo falls into the 'OSS\Model\BucketListInfo' data type. diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Core/OssUtil.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Core/OssUtil.php index 541d2c344..f4cff08ce 100644 --- a/vendor/aliyuncs/oss-sdk-php/src/OSS/Core/OssUtil.php +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Core/OssUtil.php @@ -145,7 +145,7 @@ public static function validateBucket($bucket) public static function validateObject($object) { $pattern = '/^.{1,1023}$/'; - if (empty($object) || !preg_match($pattern, $object) || + if (!preg_match($pattern, $object) || self::startsWith($object, '/') || self::startsWith($object, '\\') ) { return false; @@ -223,6 +223,8 @@ public static function validateContent($content) public static function throwOssExceptionWithMessageIfEmpty($name, $errMsg) { if (empty($name)) { + if (is_string($name) && $name == '0') + return; throw new OssException($errMsg); } } @@ -395,7 +397,11 @@ public static function getHostPortFromEndpoint($endpoint) if ($pos !== false) { $str = substr($str, $pos+1); } - + + if (!preg_match('/^[\w.-]+(:[0-9]+)?$/', $str)) { + throw new OssException("endpoint is invalid:" . $endpoint); + } + return $str; } @@ -418,6 +424,28 @@ public static function createDeleteObjectsXmlBody($objects, $quiet) return $xml->asXML(); } + /** + * Generate the xml message of DeleteMultiObjects. + * + * @param DeleteObjectInfo[] $objects + * @param bool $quiet + * @return string + */ + public static function createDeleteObjectVersionsXmlBody($objects, $quiet) + { + $xml = new \SimpleXMLElement(''); + $xml->addChild('Quiet', $quiet); + foreach ($objects as $object) { + $sub_object = $xml->addChild('Object'); + $key = OssUtil::sReplace($object->getKey()); + $sub_object->addChild('Key', $key); + if (!empty($object->getVersionId())) { + $sub_object->addChild('VersionId', $object->getVersionId()); + } + } + return $xml->asXML(); + } + /** * Generate the xml message of CompleteMultipartUpload. * diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Http/RequestCore.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Http/RequestCore.php index e1d221e25..a78f19be6 100644 --- a/vendor/aliyuncs/oss-sdk-php/src/OSS/Http/RequestCore.php +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Http/RequestCore.php @@ -713,6 +713,8 @@ public function prep_request() $temp_headers[] = $k . ': ' . $v; } + // fix "Expect: 100-continue" + $temp_headers[] = 'Expect:'; curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $temp_headers); } diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/BucketInfo.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/BucketInfo.php index 09e7deafb..e211eed65 100644 --- a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/BucketInfo.php +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/BucketInfo.php @@ -11,20 +11,20 @@ */ class BucketInfo { - /** + /** * BucketInfo constructor. * * @param string $location * @param string $name * @param string $createDate */ - public function __construct($location, $name, $createDate) + public function __construct($location = '', $name = '', $createDate = '') { $this->location = $location; - $this->name = $name; $this->createDate = $createDate; + $this->name = $name; } - + /** * Get bucket location * @@ -55,6 +55,82 @@ public function getCreateDate() return $this->createDate; } + /** + * Get bucket storage class. + * + * @return string + */ + public function getStorageClass() + { + return $this->storageClass; + } + + /** + * Get bucket extranet endpoint. + * + * @return string + */ + public function getExtranetEndpoint() + { + return $this->extranetEndpoint; + } + + /** + * Get bucket intranet endpoint. + * + * @return string + */ + public function getIntranetEndpoint() + { + return $this->intranetEndpoint; + } + + /** + * Get bucket intranet endpoint. + * + * @return string + */ + public function getRegion() + { + return $this->region; + } + + + /** + * Parse bucket information from node. + * + * @param xml $xml + * @throws OssException + * @return null + */ + public function parseFromXmlNode($xml) + { + if (isset($xml->Location)) { + $this->location = strval($xml->Location); + } + if (isset($xml->Name)) { + $this->name = strval($xml->Name); + } + if (isset($xml->CreationDate)) { + $this->createDate = strval($xml->CreationDate); + } + if (isset($xml->StorageClass)) { + $this->storageClass = strval($xml->StorageClass); + } + if (isset($xml->ExtranetEndpoint)) { + $this->extranetEndpoint = strval($xml->ExtranetEndpoint); + } + if (isset($xml->IntranetEndpoint)) { + $this->intranetEndpoint = strval($xml->IntranetEndpoint); + } + if (isset($xml->IntranetEndpoint)) { + $this->intranetEndpoint = strval($xml->IntranetEndpoint); + } + if (isset($xml->Region)) { + $this->region = strval($xml->Region); + } + } + /** * bucket region * @@ -75,4 +151,31 @@ public function getCreateDate() */ private $createDate; + /** + * bucket storage class + * + * @var string + */ + private $storageClass; + + /** + * bucket extranet endpoint + * + * @var string + */ + private $extranetEndpoint; + + /** + * bucket intranet endpoint + * + * @var string + */ + private $intranetEndpoint; + + /** + * bucket region + * + * @var string + */ + private $region; } \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/BucketStat.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/BucketStat.php new file mode 100644 index 000000000..9e2989a76 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/BucketStat.php @@ -0,0 +1,85 @@ +storage; + } + + /** + * Get object count + * + * @return int + */ + public function getObjectCount() + { + return $this->objectCount; + } + + /** + * Get multipart upload count. + * + * @return int + */ + public function getMultipartUploadCount() + { + return $this->multipartUploadCount; + } + + /** + * Parse stat from the xml. + * + * @param string $strXml + * @throws OssException + * @return null + */ + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (isset($xml->Storage) ) { + $this->storage = intval($xml->Storage); + } + if (isset($xml->ObjectCount) ) { + $this->objectCount = intval($xml->ObjectCount); + } + if (isset($xml->MultipartUploadCount) ) { + $this->multipartUploadCount = intval($xml->MultipartUploadCount); + } + } + + /** + * current storage + * + * @var int + */ + private $storage; + /** + * object count + * + * @var int + */ + private $objectCount; + + /** + * multipart upload count + * + * @var int + */ + private $multipartUploadCount; + +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/DeleteMarkerInfo.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/DeleteMarkerInfo.php new file mode 100644 index 000000000..c129e99f5 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/DeleteMarkerInfo.php @@ -0,0 +1,65 @@ +key = $key; + $this->versionId = $versionId; + $this->lastModified = $lastModified; + $this->isLatest = $isLatest; + } + + /** + * @return string + */ + public function getKey() + { + return $this->key; + } + + /** + * @return string + */ + public function getVersionId() + { + return $this->versionId; + } + + /** + * @return string + */ + public function getLastModified() + { + return $this->lastModified; + } + + /** + * @return string + */ + public function getIsLatest() + { + return $this->isLatest; + } + + private $key = ""; + private $versionId = ""; + private $lastModified = ""; + private $isLatest = ""; +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/DeleteObjectInfo.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/DeleteObjectInfo.php new file mode 100644 index 000000000..806eafbec --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/DeleteObjectInfo.php @@ -0,0 +1,41 @@ +key = $key; + $this->versionId = $versionId; + } + + /** + * @return string + */ + public function getKey() + { + return $this->key; + } + + /** + * @return string + */ + public function getVersionId() + { + return $this->versionId; + } + + private $key = ""; + private $versionId = ""; +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/DeletedObjectInfo.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/DeletedObjectInfo.php new file mode 100644 index 000000000..6bba39a46 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/DeletedObjectInfo.php @@ -0,0 +1,63 @@ +key = $key; + $this->versionId = $versionId; + $this->deleteMarker = $deleteMarker; + $this->deleteMarkerVersionId = $deleteMarkerVersionId; + } + + /** + * @return string + */ + public function getKey() + { + return $this->key; + } + + /** + * @return string + */ + public function getVersionId() + { + return $this->versionId; + } + + /** + * @return string + */ + public function getDeleteMarker() + { + return $this->deleteMarker; + } + + /** + * @return string + */ + public function getDeleteMarkerVersionId() + { + return $this->deleteMarkerVersionId; + } + + private $key = ""; + private $versionId = ""; + private $deleteMarker = ""; + private $deleteMarkerVersionId = ""; +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ExtendWormConfig.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ExtendWormConfig.php new file mode 100644 index 000000000..5e62287f4 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ExtendWormConfig.php @@ -0,0 +1,64 @@ +day = $day; + } + + /** + * Parse ExtendWormConfig from the xml. + * + * @param string $strXml + * @throws OssException + * @return null + */ + public function parseFromXml($strXml) + { + throw new OssException("Not implemented."); + } + + /** + * Serialize the object into xml string. + * + * @return string + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement(''); + if (isset($this->day)) { + $xml->addChild('RetentionPeriodInDays', $this->day); + } + return $xml->asXML(); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + /** + * @return int + */ + public function getDay() + { + return $this->day; + } + + private $day = 0; +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/GetLiveChannelHistory.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/GetLiveChannelHistory.php index 6643444aa..e6d518a9c 100644 --- a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/GetLiveChannelHistory.php +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/GetLiveChannelHistory.php @@ -1,6 +1,9 @@ day = $day; + } + + /** + * Parse InitiateWormConfig from the xml. + * + * @param string $strXml + * @throws OssException + * @return null + */ + public function parseFromXml($strXml) + { + throw new OssException("Not implemented."); + } + + /** + * Serialize the object into xml string. + * + * @return string + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement(''); + if (isset($this->day)) { + $xml->addChild('RetentionPeriodInDays', $this->day); + } + return $xml->asXML(); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + /** + * @return int + */ + public function getDay() + { + return $this->day; + } + + private $day = 0; +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ObjectVersionInfo.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ObjectVersionInfo.php new file mode 100644 index 000000000..407315d2a --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ObjectVersionInfo.php @@ -0,0 +1,114 @@ +key = $key; + $this->versionId = $versionId; + $this->lastModified = $lastModified; + $this->eTag = $eTag; + $this->type = $type; + $this->size = $size; + $this->storageClass = $storageClass; + $this->isLatest = $isLatest; + } + + /** + * @return string + */ + public function getKey() + { + return $this->key; + } + + /** + * @return string + */ + public function getVersionId() + { + return $this->versionId; + } + + /** + * @return string + */ + public function getLastModified() + { + return $this->lastModified; + } + + /** + * @return string + */ + public function getETag() + { + return $this->eTag; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @return int + */ + public function getSize() + { + return $this->size; + } + + /** + * @return string + */ + public function getStorageClass() + { + return $this->storageClass; + } + + /** + * @return string + */ + public function getIsLatest() + { + return $this->isLatest; + } + + private $key = ""; + private $versionId = ""; + private $lastModified = ""; + private $eTag = ""; + private $type = ""; + private $size = 0; + private $storageClass = ""; + private $isLatest = ""; +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ObjectVersionListInfo.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ObjectVersionListInfo.php new file mode 100644 index 000000000..c94210d01 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ObjectVersionListInfo.php @@ -0,0 +1,162 @@ +bucketName = $bucketName; + $this->prefix = $prefix; + $this->keyMarker = $keyMarker; + $this->nextKeyMarker = $nextKeyMarker; + $this->versionIdMarker = $versionIdMarker; + $this->nextVersionIdMarker = $nextVersionIdMarker; + $this->maxKeys = $maxKeys; + $this->delimiter = $delimiter; + $this->isTruncated = $isTruncated; + $this->objectVersionList = $objectversionList; + $this->deleteMarkerList = $deleteMarkerList; + $this->prefixList = $prefixList; + } + + /** + * @return string + */ + public function getBucketName() + { + return $this->bucketName; + } + + /** + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + /** + * @return string + */ + public function getKeyMarker() + { + return $this->keyMarker; + } + + /** + * @return string + */ + public function getNextKeyMarker() + { + return $this->nextKeyMarker; + } + + /** + * @return string + */ + public function getVersionIdMarker() + { + return $this->versionIdMarker; + } + + /** + * @return string + */ + public function getNextVersionIdMarker() + { + return $this->nextVersionIdMarker; + } + + /** + * @return int + */ + public function getMaxKeys() + { + return $this->maxKeys; + } + + /** + * @return string + */ + public function getDelimiter() + { + return $this->delimiter; + } + + /** + * @return mixed + */ + public function getIsTruncated() + { + return $this->isTruncated; + } + + /** + * Get the ObjectVersionInfo list. + * + * @return ObjectVersionInfo[] + */ + public function getObjectVersionList() + { + return $this->objectVersionList; + } + + /** + * Get the DeleteMarkerInfo list. + * + * @return DeleteMarkerInfo[] + */ + public function getDeleteMarkerList() + { + return $this->deleteMarkerList; + } + + /** + * Get the PrefixInfo list + * + * @return PrefixInfo[] + */ + public function getPrefixList() + { + return $this->prefixList; + } + + private $bucketName = ""; + private $prefix = ""; + private $keyMarker = ""; + private $nextKeyMarker = ""; + private $versionIdmarker = ""; + private $nextVersionIdMarker = ""; + private $maxKeys = 0; + private $delimiter = ""; + private $isTruncated = null; + private $objectVersionList = array(); + private $deleteMarkerList = array(); + private $prefixList = array(); +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/RequestPaymentConfig.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/RequestPaymentConfig.php new file mode 100644 index 000000000..6b32060d3 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/RequestPaymentConfig.php @@ -0,0 +1,68 @@ +payer = $payer; + } + + /** + * Parse ServerSideEncryptionConfig from the xml. + * + * @param string $strXml + * @throws OssException + * @return null + */ + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (isset($xml->Payer)) { + $this->payer = strval($xml->Payer); + } + } + + /** + * Serialize the object into xml string. + * + * @return string + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement(''); + if (isset($this->payer)) { + $xml->addChild('Payer', $this->payer); + } + return $xml->asXML(); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + /** + * @return string + */ + public function getPayer() + { + return $this->payer; + } + + private $payer = ""; +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/RestoreConfig.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/RestoreConfig.php new file mode 100644 index 000000000..156852a4a --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/RestoreConfig.php @@ -0,0 +1,77 @@ +day = $day; + $this->tier = $tier; + } + + /** + * Parse RestoreConfig from the xml. + * + * @param string $strXml + * @throws OssException + * @return null + */ + public function parseFromXml($strXml) + { + throw new OssException("Not implemented."); + } + + /** + * Serialize the object into xml string. + * + * @return string + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement(''); + $xml->addChild('Days', strval($this->day)); + if (isset($this->tier)) { + $xml_param = $xml->addChild('JobParameters'); + $xml_param->addChild('Tier', $this->tier); + } + return $xml->asXML(); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + /** + * @return int + */ + public function getDay() + { + return $this->day; + } + + /** + * @return string + */ + public function getTier() + { + return $this->tier; + } + + private $day = 1; + private $tier = 'Standard'; +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ServerSideEncryptionConfig.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ServerSideEncryptionConfig.php new file mode 100644 index 000000000..e3a190b8f --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/ServerSideEncryptionConfig.php @@ -0,0 +1,91 @@ +sseAlgorithm = $sseAlgorithm; + $this->kmsMasterKeyID = $kmsMasterKeyID; + } + + /** + * Parse ServerSideEncryptionConfig from the xml. + * + * @param string $strXml + * @throws OssException + * @return null + */ + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (!isset($xml->ApplyServerSideEncryptionByDefault)) return; + foreach ($xml->ApplyServerSideEncryptionByDefault as $default) { + foreach ($default as $key => $value) { + if ($key === 'SSEAlgorithm') { + $this->sseAlgorithm = strval($value); + } elseif ($key === 'KMSMasterKeyID') { + $this->kmsMasterKeyID = strval($value); + } + } + break; + } + } + + /** + * Serialize the object into xml string. + * + * @return string + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement(''); + $default = $xml->addChild('ApplyServerSideEncryptionByDefault'); + if (isset($this->sseAlgorithm)) { + $default->addChild('SSEAlgorithm', $this->sseAlgorithm); + } + if (isset($this->kmsMasterKeyID)) { + $default->addChild('KMSMasterKeyID', $this->kmsMasterKeyID); + } + return $xml->asXML(); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + /** + * @return string + */ + public function getSSEAlgorithm() + { + return $this->sseAlgorithm; + } + + /** + * @return string + */ + public function getKMSMasterKeyID() + { + return $this->kmsMasterKeyID; + } + + private $sseAlgorithm = ""; + private $kmsMasterKeyID = ""; +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/StorageCapacityConfig.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/StorageCapacityConfig.php index 024b5c951..39a9e72b8 100644 --- a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/StorageCapacityConfig.php +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/StorageCapacityConfig.php @@ -2,6 +2,8 @@ namespace OSS\Model; +use OSS\Core\OssException; + /** * Class StorageCapacityConfig * diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/Tag.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/Tag.php new file mode 100644 index 000000000..509bd6e71 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/Tag.php @@ -0,0 +1,41 @@ +key = $key; + $this->value = $value; + } + + /** + * @return string + */ + public function getKey() + { + return $this->key; + } + + /** + * @return string + */ + public function getValue() + { + return $this->value; + } + + private $key = ""; + private $value = ""; +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/TaggingConfig.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/TaggingConfig.php new file mode 100644 index 000000000..09fa32300 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/TaggingConfig.php @@ -0,0 +1,89 @@ +tags = array(); + } + + /** + * Get Tag list + * + * @return Tag[] + */ + public function getTags() + { + return $this->tags; + } + + + /** + * Add a new Tag + * + * @param Tag $tag + * @throws OssException + */ + public function addTag($tag) + { + $this->tags[] = $tag; + } + + /** + * Parse TaggingConfig from the xml. + * + * @param string $strXml + * @throws OssException + * @return null + */ + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (!isset($xml->TagSet) || !isset($xml->TagSet->Tag)) return; + foreach ($xml->TagSet->Tag as $tag) { + $this->addTag(new Tag($tag->Key, $tag->Value)); + } + } + + /** + * Serialize the object into xml string. + * + * @return string + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement(''); + $xmlTagSet = $xml->addChild('TagSet'); + foreach ($this->tags as $tag) { + $xmlTag = $xmlTagSet->addChild('Tag'); + $xmlTag->addChild('Key', strval($tag->getKey())); + $xmlTag->addChild('Value', strval($tag->getValue())); + } + return $xml->asXML(); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + /** + * Tag list + * + * @var Tag[] + */ + private $tags = array(); +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/VersioningConfig.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/VersioningConfig.php new file mode 100644 index 000000000..992a80fea --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/VersioningConfig.php @@ -0,0 +1,67 @@ +status = $status; + } + + /** + * Parse VersioningConfig from the xml. + * + * @param string $strXml + * @throws OssException + * @return null + */ + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (isset($xml->Status)) { + $this->status = strval($xml->Status); + } + } + + /** + * Serialize the object into xml string. + * + * @return string + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement(''); + if (isset($this->status)) { + $xml->addChild('Status', $this->status); + } + return $xml->asXML(); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + /** + * @return string + */ + public function getStatus() + { + return $this->status; + } + + private $status = ""; +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/WormConfig.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/WormConfig.php new file mode 100644 index 000000000..6a489560a --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Model/WormConfig.php @@ -0,0 +1,90 @@ +WormId)) { + $this->wormId = strval($xml->WormId); + } + if (isset($xml->State)) { + $this->state = strval($xml->State); + } + if (isset($xml->RetentionPeriodInDays)) { + $this->day = intval($xml->RetentionPeriodInDays); + } + if (isset($xml->CreationDate)) { + $this->creationDate = strval($xml->CreationDate); + } + } + + /** + * Serialize the object into xml string. + * + * @return string + */ + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + /** + * @return string + */ + public function getWormId() + { + return $this->wormId; + } + + /** + * @return string + */ + public function getState() + { + return $this->state; + } + + /** + * @return int + */ + public function getDay() + { + return $this->day; + } + + /** + * @return string + */ + public function getCreationDate() + { + return $this->creationDate; + } + + private $wormId = ''; + private $state = ''; + private $creationDate = ''; + private $day = 0; +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/OssClient.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/OssClient.php index daae42c70..b741bfbd1 100644 --- a/vendor/aliyuncs/oss-sdk-php/src/OSS/OssClient.php +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/OssClient.php @@ -50,6 +50,28 @@ use OSS\Model\WebsiteConfig; use OSS\Core\OssUtil; use OSS\Model\ListPartsInfo; +use OSS\Result\GetBucketInfoResult; +use OSS\Model\BucketStat; +use OSS\Result\GetBucketStatResult; +use OSS\Model\ServerSideEncryptionConfig; +use OSS\Result\GetBucketEncryptionResult; +use OSS\Model\RequestPaymentConfig; +use OSS\Result\GetBucketRequestPaymentResult; +use OSS\Model\Tag; +use OSS\Model\TaggingConfig; +use OSS\Result\GetBucketTagsResult; +use OSS\Model\VersioningConfig; +use OSS\Result\GetBucketVersioningResult; +use OSS\Model\InitiateWormConfig; +use OSS\Result\InitiateBucketWormResult; +use OSS\Model\ExtendWormConfig; +use OSS\Result\GetBucketWormResult; +use OSS\Model\RestoreConfig; +use OSS\Model\ObjectVersionListInfo; +use OSS\Result\ListObjectVersionsResult; +use OSS\Model\DeleteObjectInfo; +use OSS\Model\DeletedObjectInfo; +use OSS\Result\DeleteObjectVersionsResult; /** * Class OssClient @@ -273,12 +295,12 @@ public function putBucketAcl($bucket, $acl, $options = NULL) * * @param string $bucket * @param string $object + * @param array $options * @throws OssException * @return string */ - public function getObjectAcl($bucket, $object) + public function getObjectAcl($bucket, $object, $options = NULL) { - $options = array(); $this->precheckCommon($bucket, $object, $options, true); $options[self::OSS_METHOD] = self::OSS_HTTP_GET; $options[self::OSS_BUCKET] = $bucket; @@ -295,10 +317,11 @@ public function getObjectAcl($bucket, $object) * @param string $bucket bucket name * @param string $object object name * @param string $acl access permissions, valid values are ['default', 'private', 'public-read', 'public-read-write'] + * @param array $options * @throws OssException * @return null */ - public function putObjectAcl($bucket, $object, $acl) + public function putObjectAcl($bucket, $object, $acl, $options = NULL) { $this->precheckCommon($bucket, $object, $options, true); $options[self::OSS_BUCKET] = $bucket; @@ -685,7 +708,7 @@ public function getLiveChannelStatus($bucket, $channelName, $options = NULL) * @throws OssException * @return GetLiveChannelHistory */ - public function getLiveChannelHistory($bucket, $channelName, $options = NULL) + public function getLiveChannelHistory($bucket, $channelName, $options = NULL) { $this->precheckCommon($bucket, NULL, $options, false); $options[self::OSS_BUCKET] = $bucket; @@ -810,6 +833,41 @@ public function signRtmpUrl($bucket, $channelName, $timeout = 60, $options = NUL return $proto . $hostname . '/live/' . $channelName . '?' . implode('&', $query_items); } + /** + * Generates the signed pushing streaming url + * + * @param string $bucket bucket name + * @param string $channelName channel name + * @param int $expiration expiration time of the Url, unix epoch, since 1970.1.1 00.00.00 UTC + * @param array $options + * @throws OssException + * @return The signed pushing streaming url + */ + public function generatePresignedRtmpUrl($bucket, $channelName, $expiration, $options = NULL) + { + $this->precheckCommon($bucket, $channelName, $options, false); + $proto = 'rtmp://'; + $hostname = $this->generateHostname($bucket); + $cano_params = ''; + $query_items = array(); + $params = isset($options['params']) ? $options['params'] : array(); + uksort($params, 'strnatcasecmp'); + foreach ($params as $key => $value) { + $cano_params = $cano_params . $key . ':' . $value . "\n"; + $query_items[] = rawurlencode($key) . '=' . rawurlencode($value); + } + $resource = '/' . $bucket . '/' . $channelName; + + $string_to_sign = $expiration . "\n" . $cano_params . $resource; + $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->accessKeySecret, true)); + + $query_items[] = 'OSSAccessKeyId=' . rawurlencode($this->accessKeyId); + $query_items[] = 'Expires=' . rawurlencode($expiration); + $query_items[] = 'Signature=' . rawurlencode($signature); + + return $proto . $hostname . '/live/' . $channelName . '?' . implode('&', $query_items); + } + /** * Precheck the CORS request. Before sending a CORS request, a preflight request (OPTIONS) is sent with the specific origin. * HTTP METHOD and headers information are sent to OSS as well for evaluating if the CORS request is allowed. @@ -879,124 +937,562 @@ public function getBucketLifecycle($bucket, $options = NULL) $options[self::OSS_BUCKET] = $bucket; $options[self::OSS_METHOD] = self::OSS_HTTP_GET; $options[self::OSS_OBJECT] = '/'; - $options[self::OSS_SUB_RESOURCE] = 'lifecycle'; + $options[self::OSS_SUB_RESOURCE] = 'lifecycle'; + $response = $this->auth($options); + $result = new GetLifecycleResult($response); + return $result->getData(); + } + + /** + * Deletes the bucket's lifecycle config + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketLifecycle($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'lifecycle'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Sets a bucket's referer, which has a whitelist of referrer and specifies if empty referer is allowed. + * Checks out API document for more details about "Bucket Referer" + * + * @param string $bucket bucket name + * @param RefererConfig $refererConfig + * @param array $options + * @return ResponseCore + * @throws null + */ + public function putBucketReferer($bucket, $refererConfig, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'referer'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $refererConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets the bucket's Referer + * Checks out API document for more details about "Bucket Referer" + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return RefererConfig + */ + public function getBucketReferer($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'referer'; + $response = $this->auth($options); + $result = new GetRefererResult($response); + return $result->getData(); + } + + /** + * Set the size of the bucket,the unit is GB + * When the capacity of the bucket is bigger than the set, it's forbidden to continue writing + * + * @param string $bucket bucket name + * @param int $storageCapacity + * @param array $options + * @return ResponseCore + * @throws null + */ + public function putBucketStorageCapacity($bucket, $storageCapacity, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'qos'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $storageCapacityConfig = new StorageCapacityConfig($storageCapacity); + $options[self::OSS_CONTENT] = $storageCapacityConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Get the capacity of the bucket, the unit is GB + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return int + */ + public function getBucketStorageCapacity($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'qos'; + $response = $this->auth($options); + $result = new GetStorageCapacityResult($response); + return $result->getData(); + } + + /** + * Get the information of the bucket + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return BucketInfo + */ + public function getBucketInfo($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'bucketInfo'; + $response = $this->auth($options); + $result = new GetBucketInfoResult($response); + return $result->getData(); + } + + /** + * Get the stat of the bucket + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return BucketStat + */ + public function getBucketStat($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'stat'; + $response = $this->auth($options); + $result = new GetBucketStatResult($response); + return $result->getData(); + } + + /** + * Sets the bucket's policy + * + * @param string $bucket bucket name + * @param string $policy policy json format content + * @param array $options + * @throws OssException + * @return null + */ + public function putBucketPolicy($bucket, $policy, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'policy'; + $options[self::OSS_CONTENT_TYPE] = 'application/json'; + $options[self::OSS_CONTENT] = $policy; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets bucket's policy + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return string policy json content + */ + public function getBucketPolicy($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'policy'; + $response = $this->auth($options); + $result = new BodyResult($response); + return $result->getData(); + } + + /** + * Deletes the bucket's policy + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketPolicy($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'policy'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Sets the bucket's encryption + * + * @param string $bucket bucket name + * @param ServerSideEncryptionConfig $sseConfig + * @param array $options + * @throws OssException + * @return null + */ + public function putBucketEncryption($bucket, $sseConfig, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'encryption'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $sseConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets bucket's encryption + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return ServerSideEncryptionConfig + */ + public function getBucketEncryption($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'encryption'; + $response = $this->auth($options); + $result = new GetBucketEncryptionResult($response); + return $result->getData(); + } + + /** + * Deletes the bucket's encryption + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketEncryption($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'encryption'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Set the request playment of the bucket, Can be BucketOwner and Requester + * + * @param string $bucket bucket name + * @param string $payer + * @param array $options + * @return ResponseCore + * @throws null + */ + public function putBucketRequestPayment($bucket, $payer, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'requestPayment'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $config = new RequestPaymentConfig($payer); + $options[self::OSS_CONTENT] = $config->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Get the request playment of the bucket + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return string + */ + public function getBucketRequestPayment($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'requestPayment'; + $response = $this->auth($options); + $result = new GetBucketRequestPaymentResult($response); + return $result->getData(); + } + + /** + * Sets the bucket's tags + * + * @param string $bucket bucket name + * @param TaggingConfig $taggingConfig + * @param array $options + * @throws OssException + * @return null + */ + public function putBucketTags($bucket, $taggingConfig, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = self::OSS_TAGGING; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $taggingConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets bucket's tags + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return TaggingConfig + */ + public function getBucketTags($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = self::OSS_TAGGING; + $response = $this->auth($options); + $result = new GetBucketTagsResult($response); + return $result->getData(); + } + + /** + * Deletes the bucket's tags + * If want to delete specified tags for a bucket, please set the $tags + * + * @param string $bucket bucket name + * @param tag[] $tags (optional) + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketTags($bucket, $tags = NULL, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + if (empty($tags)) { + $options[self::OSS_SUB_RESOURCE] = self::OSS_TAGGING; + } else { + $value = ''; + foreach ($tags as $tag ) { + $value .= $tag->getKey().','; + } + $value = rtrim($value, ','); + $options[self::OSS_TAGGING] = $value; + } + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Set the versioning of the bucket, Can be BucketOwner and Requester + * + * @param string $bucket bucket name + * @param string $status + * @param array $options + * @return ResponseCore + * @throws null + */ + public function putBucketVersioning($bucket, $status, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'versioning'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $config = new VersioningConfig($status); + $options[self::OSS_CONTENT] = $config->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Get the versioning of the bucket + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return string + */ + public function getBucketVersioning($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'versioning'; $response = $this->auth($options); - $result = new GetLifecycleResult($response); + $result = new GetBucketVersioningResult($response); return $result->getData(); } /** - * Deletes the bucket's lifecycle config + * Initialize a bucket's worm * * @param string $bucket bucket name + * @param int $day * @param array $options * @throws OssException - * @return null + * @return string returns uploadid */ - public function deleteBucketLifecycle($bucket, $options = NULL) + public function initiateBucketWorm($bucket, $day, $options = NULL) { $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; $options[self::OSS_BUCKET] = $bucket; - $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; $options[self::OSS_OBJECT] = '/'; - $options[self::OSS_SUB_RESOURCE] = 'lifecycle'; + $options[self::OSS_SUB_RESOURCE] = 'worm'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $config = new InitiateWormConfig($day); + $options[self::OSS_CONTENT] = $config->serializeToXml(); $response = $this->auth($options); - $result = new PutSetDeleteResult($response); + $result = new InitiateBucketWormResult($response); return $result->getData(); } /** - * Sets a bucket's referer, which has a whitelist of referrer and specifies if empty referer is allowed. - * Checks out API document for more details about "Bucket Referer" + * Aborts the bucket's worm * * @param string $bucket bucket name - * @param RefererConfig $refererConfig * @param array $options - * @return ResponseCore - * @throws null + * @throws OssException + * @return null */ - public function putBucketReferer($bucket, $refererConfig, $options = NULL) + public function abortBucketWorm($bucket, $options = NULL) { $this->precheckCommon($bucket, NULL, $options, false); $options[self::OSS_BUCKET] = $bucket; - $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; $options[self::OSS_OBJECT] = '/'; - $options[self::OSS_SUB_RESOURCE] = 'referer'; - $options[self::OSS_CONTENT_TYPE] = 'application/xml'; - $options[self::OSS_CONTENT] = $refererConfig->serializeToXml(); + $options[self::OSS_SUB_RESOURCE] = 'worm'; $response = $this->auth($options); $result = new PutSetDeleteResult($response); return $result->getData(); } - /** - * Gets the bucket's Referer - * Checks out API document for more details about "Bucket Referer" + /** + * Complete a bucket's worm * * @param string $bucket bucket name + * @param string $wormId * @param array $options * @throws OssException - * @return RefererConfig + * @return string returns uploadid */ - public function getBucketReferer($bucket, $options = NULL) + public function completeBucketWorm($bucket, $wormId, $options = NULL) { $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; $options[self::OSS_BUCKET] = $bucket; - $options[self::OSS_METHOD] = self::OSS_HTTP_GET; $options[self::OSS_OBJECT] = '/'; - $options[self::OSS_SUB_RESOURCE] = 'referer'; + $options[self::OSS_WORM_ID] = $wormId; + $options[self::OSS_CONTENT] = ''; $response = $this->auth($options); - $result = new GetRefererResult($response); + $result = new PutSetDeleteResult($response); return $result->getData(); } - /** - * Set the size of the bucket,the unit is GB - * When the capacity of the bucket is bigger than the set, it's forbidden to continue writing + * Extend a bucket's worm * * @param string $bucket bucket name - * @param int $storageCapacity + * @param string $wormId + * @param int $day * @param array $options - * @return ResponseCore - * @throws null + * @throws OssException + * @return string returns uploadid */ - public function putBucketStorageCapacity($bucket, $storageCapacity, $options = NULL) + public function extendBucketWorm($bucket, $wormId, $day, $options = NULL) { $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; $options[self::OSS_BUCKET] = $bucket; - $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; $options[self::OSS_OBJECT] = '/'; - $options[self::OSS_SUB_RESOURCE] = 'qos'; + $options[self::OSS_WORM_ID] = $wormId; + $options[self::OSS_SUB_RESOURCE] = 'wormExtend'; $options[self::OSS_CONTENT_TYPE] = 'application/xml'; - $storageCapacityConfig = new StorageCapacityConfig($storageCapacity); - $options[self::OSS_CONTENT] = $storageCapacityConfig->serializeToXml(); + $config = new ExtendWormConfig($day); + $options[self::OSS_CONTENT] = $config->serializeToXml(); $response = $this->auth($options); $result = new PutSetDeleteResult($response); return $result->getData(); } /** - * Get the capacity of the bucket, the unit is GB + * Get a bucket's worm * * @param string $bucket bucket name * @param array $options * @throws OssException - * @return int + * @return string */ - public function getBucketStorageCapacity($bucket, $options = NULL) + public function getBucketWorm($bucket, $options = NULL) { $this->precheckCommon($bucket, NULL, $options, false); $options[self::OSS_BUCKET] = $bucket; $options[self::OSS_METHOD] = self::OSS_HTTP_GET; $options[self::OSS_OBJECT] = '/'; - $options[self::OSS_SUB_RESOURCE] = 'qos'; + $options[self::OSS_SUB_RESOURCE] = 'worm'; $response = $this->auth($options); - $result = new GetStorageCapacityResult($response); + $result = new GetBucketWormResult($response); return $result->getData(); } - /** * Lists the bucket's object list (in ObjectListInfo) * @@ -1018,16 +1514,14 @@ public function listObjects($bucket, $options = NULL) $options[self::OSS_BUCKET] = $bucket; $options[self::OSS_METHOD] = self::OSS_HTTP_GET; $options[self::OSS_OBJECT] = '/'; - $options[self::OSS_HEADERS] = array( - self::OSS_DELIMITER => isset($options[self::OSS_DELIMITER]) ? $options[self::OSS_DELIMITER] : '/', - self::OSS_PREFIX => isset($options[self::OSS_PREFIX]) ? $options[self::OSS_PREFIX] : '', - self::OSS_MAX_KEYS => isset($options[self::OSS_MAX_KEYS]) ? $options[self::OSS_MAX_KEYS] : self::OSS_MAX_KEYS_VALUE, - self::OSS_MARKER => isset($options[self::OSS_MARKER]) ? $options[self::OSS_MARKER] : '', - ); $query = isset($options[self::OSS_QUERY_STRING]) ? $options[self::OSS_QUERY_STRING] : array(); $options[self::OSS_QUERY_STRING] = array_merge( $query, - array(self::OSS_ENCODING_TYPE => self::OSS_ENCODING_TYPE_URL) + array(self::OSS_ENCODING_TYPE => self::OSS_ENCODING_TYPE_URL, + self::OSS_DELIMITER => isset($options[self::OSS_DELIMITER]) ? $options[self::OSS_DELIMITER] : '/', + self::OSS_PREFIX => isset($options[self::OSS_PREFIX]) ? $options[self::OSS_PREFIX] : '', + self::OSS_MAX_KEYS => isset($options[self::OSS_MAX_KEYS]) ? $options[self::OSS_MAX_KEYS] : self::OSS_MAX_KEYS_VALUE, + self::OSS_MARKER => isset($options[self::OSS_MARKER]) ? $options[self::OSS_MARKER] : '') ); $response = $this->auth($options); @@ -1035,6 +1529,45 @@ public function listObjects($bucket, $options = NULL) return $result->getData(); } + /** + * Lists the bucket's object with version information (in ObjectListInfo) + * + * @param string $bucket + * @param array $options are defined below: + * $options = array( + * 'max-keys' => specifies max object count to return. By default is 100 and max value could be 1000. + * 'prefix' => specifies the key prefix the returned objects must have. Note that the returned keys still contain the prefix. + * 'delimiter' => The delimiter of object name for grouping object. When it's specified, listObjectVersions will differeniate the object and folder. And it will return subfolder's objects. + * 'key-marker' => The key of returned object must be greater than the 'key-marker'. + * 'version-id-marker' => The version id of returned object must be greater than the 'version-id-marker'. + *) + * Prefix and marker are for filtering and paging. Their length must be less than 256 bytes + * @throws OssException + * @return ObjectListInfo + */ + public function listObjectVersions($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'versions'; + $query = isset($options[self::OSS_QUERY_STRING]) ? $options[self::OSS_QUERY_STRING] : array(); + $options[self::OSS_QUERY_STRING] = array_merge( + $query, + array(self::OSS_ENCODING_TYPE => self::OSS_ENCODING_TYPE_URL, + self::OSS_DELIMITER => isset($options[self::OSS_DELIMITER]) ? $options[self::OSS_DELIMITER] : '/', + self::OSS_PREFIX => isset($options[self::OSS_PREFIX]) ? $options[self::OSS_PREFIX] : '', + self::OSS_MAX_KEYS => isset($options[self::OSS_MAX_KEYS]) ? $options[self::OSS_MAX_KEYS] : self::OSS_MAX_KEYS_VALUE, + self::OSS_KEY_MARKER => isset($options[self::OSS_KEY_MARKER]) ? $options[self::OSS_KEY_MARKER] : '', + self::OSS_VERSION_ID_MARKER => isset($options[self::OSS_VERSION_ID_MARKER]) ? $options[self::OSS_VERSION_ID_MARKER] : '') + ); + + $response = $this->auth($options); + $result = new ListObjectVersionsResult($response); + return $result->getData(); + } + /** * Creates a virtual 'folder' in OSS. The name should not end with '/' because the method will append the name with a '/' anyway. * @@ -1127,11 +1660,12 @@ public function putSymlink($bucket, $symlink ,$targetObject, $options = NULL) /** * gets symlink - *@param string $bucket bucket name + * @param string $bucket bucket name * @param string $symlink symlink name + * @param array $options * @return null */ - public function getSymlink($bucket, $symlink) + public function getSymlink($bucket, $symlink, $options = NULL) { $this->precheckCommon($bucket, $symlink, $options); @@ -1182,6 +1716,45 @@ public function uploadFile($bucket, $object, $file, $options = NULL) return $result->getData(); } + /** + * Uploads object from file handle + * + * @param string $bucket bucket name + * @param string $object object name + * @param resource $handle file handle + * @param array $options + * @return null + * @throws OssException + */ + public function uploadStream($bucket, $object, $handle, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + if (!is_resource($handle)) { + throw new OssException("The handle must be an opened stream"); + } + $options[self::OSS_FILE_UPLOAD] = $handle; + if ($this->isCheckMD5($options)) { + rewind($handle); + $ctx = hash_init('md5'); + hash_update_stream($ctx, $handle); + $content_md5 = base64_encode(hash_final($ctx, true)); + rewind($handle); + $options[self::OSS_CONTENT_MD5] = $content_md5; + } + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object); + } + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + if (!isset($options[self::OSS_CONTENT_LENGTH])) { + $options[self::OSS_CONTENT_LENGTH] = fstat($handle)[self::OSS_SIZE]; + } + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + /** * Append the object with the content at the specified position. * The specified position is typically the lengh of the current file. @@ -1283,10 +1856,15 @@ public function copyObject($fromBucket, $fromObject, $toBucket, $toObject, $opti $options[self::OSS_BUCKET] = $toBucket; $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; $options[self::OSS_OBJECT] = $toObject; + $param = '/' . $fromBucket . '/' . rawurlencode($fromObject); + if (isset($options[self::OSS_VERSION_ID])) { + $param = $param . '?versionId='.$options[self::OSS_VERSION_ID]; + unset($options[self::OSS_VERSION_ID]); + } if (isset($options[self::OSS_HEADERS])) { - $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE] = '/' . $fromBucket . '/' . $fromObject; + $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE] = $param; } else { - $options[self::OSS_HEADERS] = array(self::OSS_OBJECT_COPY_SOURCE => '/' . $fromBucket . '/' . $fromObject); + $options[self::OSS_HEADERS] = array(self::OSS_OBJECT_COPY_SOURCE => $param); } $response = $this->auth($options); $result = new CopyObjectResult($response); @@ -1312,6 +1890,27 @@ public function getObjectMeta($bucket, $object, $options = NULL) return $result->getData(); } + /** + * Gets the simplified metadata of a object. + * Simplified metadata includes ETag, Size, LastModified. + * + * @param string $bucket bucket name + * @param string $object object name + * @param string $options Checks out the SDK document for the detail + * @return array + */ + public function getSimplifiedObjectMeta($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_HEAD; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_SUB_RESOURCE] = 'objectMeta'; + $response = $this->auth($options); + $result = new HeaderResult($response); + return $result->getData(); + } + /** * Deletes a object * @@ -1366,6 +1965,41 @@ public function deleteObjects($bucket, $objects, $options = null) return $result->getData(); } + /** + * Deletes multiple objects with version id in a bucket + * + * @param string $bucket bucket name + * @param array $objects DeleteObjectInfo list + * @param array $options + * @return ResponseCore + * @throws null + */ + public function deleteObjectVersions($bucket, $objects, $options = null) + { + $this->precheckCommon($bucket, NULL, $options, false); + if (!is_array($objects) || !$objects) { + throw new OssException('objects must be array'); + } + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'delete'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $quiet = 'false'; + if (isset($options['quiet'])) { + if (is_bool($options['quiet'])) { //Boolean + $quiet = $options['quiet'] ? 'true' : 'false'; + } elseif (is_string($options['quiet'])) { // string + $quiet = ($options['quiet'] === 'true') ? 'true' : 'false'; + } + } + $xmlBody = OssUtil::createDeleteObjectVersionsXmlBody($objects, $quiet); + $options[self::OSS_CONTENT] = $xmlBody; + $response = $this->auth($options); + $result = new DeleteObjectVersionsResult($response); + return $result->getData(); + } + /** * Gets Object content * @@ -1434,11 +2068,101 @@ public function restoreObject($bucket, $object, $options = NULL) $options[self::OSS_METHOD] = self::OSS_HTTP_POST; $options[self::OSS_OBJECT] = $object; $options[self::OSS_SUB_RESOURCE] = self::OSS_RESTORE; + if (isset($options[self::OSS_RESTORE_CONFIG])) { + $config = $options[self::OSS_RESTORE_CONFIG]; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $config->serializeToXml(); + } + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Sets the object tagging + * + * @param string $bucket bucket name + * @param string $object object name + * @param TaggingConfig $taggingConfig + * @throws OssException + * @return null + */ + public function putObjectTagging($bucket, $object, $taggingConfig, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options, true); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_SUB_RESOURCE] = self::OSS_TAGGING; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $taggingConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets the object tagging + * + * @param string $bucket + * @param string $object + * @throws OssException + * @return TaggingConfig + */ + public function getObjectTagging($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options, true); + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_SUB_RESOURCE] = self::OSS_TAGGING; + $response = $this->auth($options); + $result = new GetBucketTagsResult($response); + return $result->getData(); + } + + /** + * Deletes the object tagging + * + * @param string $bucket + * @param string $object + * @throws OssException + * @return TaggingConfig + */ + public function deleteObjectTagging($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options, true); + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_SUB_RESOURCE] = self::OSS_TAGGING; $response = $this->auth($options); $result = new PutSetDeleteResult($response); return $result->getData(); } + /** + * Processes the object + * + * @param string $bucket bucket name + * @param string $object object name + * @param string $process process script + * @return string process result, json format + */ + public function processObject($bucket, $object, $process, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_SUB_RESOURCE] = 'x-oss-process'; + $options[self::OSS_CONTENT_TYPE] = 'application/octet-stream'; + $options[self::OSS_CONTENT] = 'x-oss-process='.$process; + $response = $this->auth($options); + $result = new BodyResult($response); + return $result->getData(); + } + /** * Gets the part size according to the preferred part size. * If the specified part size is too small or too big, it will return a min part or max part size instead. @@ -1693,7 +2417,13 @@ public function uploadPartCopy($fromBucket, $fromObject, $toBucket, $toObject, $ $options[self::OSS_HEADERS] = array(); } - $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE] = '/' . $fromBucket . '/' . $fromObject; + $param = '/' . $fromBucket . '/' . rawurlencode($fromObject); + if (isset($options[self::OSS_VERSION_ID])) { + $param = $param . '?versionId='.$options[self::OSS_VERSION_ID]; + unset($options[self::OSS_VERSION_ID]); + } + + $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE] = $param; $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE_RANGE] = "bytes=" . $start_range . "-" . $end_range; $response = $this->auth($options); $result = new UploadPartResult($response); @@ -1732,7 +2462,7 @@ public function multiuploadFile($bucket, $object, $file, $options = null) } else { $upload_file_size = filesize($uploadFile); if ($upload_file_size !== false) { - $upload_file_size -= $upload_position; + $upload_file_size -= $upload_position; } } @@ -1787,7 +2517,16 @@ public function multiuploadFile($bucket, $object, $file, $options = null) 'ETag' => $etag, ); } - return $this->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts); + + //build complete options + $cmp_options = null; + if (isset($options[self::OSS_HEADERS]) && isset($options[self::OSS_HEADERS][self::OSS_REQUEST_PAYER])) { + $cmp_options = array( + OssClient::OSS_HEADERS => array( + OssClient::OSS_REQUEST_PAYER => $options[self::OSS_HEADERS][self::OSS_REQUEST_PAYER], + )); + } + return $this->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts, $cmp_options); } /** @@ -1871,6 +2610,37 @@ public function signUrl($bucket, $object, $timeout = 60, $method = self::OSS_HTT return $this->auth($options); } + /** + * Sign URL with specified expiration time in seconds and HTTP method. + * The signed URL could be used to access the object directly. + * + * @param string $bucket + * @param string $object + * @param int $expiration expiration time of the Url, unix epoch, since 1970.1.1 00.00.00 UTC + * @param string $method + * @param array $options Key-Value array + * @return string + * @throws OssException + */ + public function generatePresignedUrl($bucket, $object, $expiration, $method = self::OSS_HTTP_GET, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + //method + if (self::OSS_HTTP_GET !== $method && self::OSS_HTTP_PUT !== $method) { + throw new OssException("method is invalid"); + } + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_METHOD] = $method; + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = ''; + } + $options[self::OSS_PREAUTH] = $expiration; + $options[self::OSS_DATE] = $expiration; + $this->setSignStsInUrl(true); + return $this->auth($options); + } + /** * validates options. Create a empty array if it's NULL. * @@ -1924,6 +2694,8 @@ private function precheckStorage($storage) return; case self::OSS_STORAGE_STANDARD: return; + case self::OSS_STORAGE_COLDARCHIVE: + return; default: break; } @@ -2159,10 +2931,13 @@ private function auth($options) } // Generates the signable_resource $signable_resource = $this->generateSignableResource($options); - $string_to_sign .= rawurldecode($signable_resource) . urldecode($signable_query_string); + $signable_resource = rawurldecode($signable_resource) . urldecode($signable_query_string); + $string_to_sign_ordered = $string_to_sign; + $string_to_sign .= $signable_resource; // Sort the strings to be signed. - $string_to_sign_ordered = $this->stringToSignSorted($string_to_sign); + $string_to_sign_ordered .= $this->stringToSignSorted($signable_resource); + $signature = base64_encode(hash_hmac('sha1', $string_to_sign_ordered, $this->accessKeySecret, true)); $request->add_header('Authorization', 'OSS ' . $this->accessKeyId . ':' . $signature); @@ -2400,6 +3175,10 @@ private function generateSignableQueryStringParam($options) self::OSS_POSITION, self::OSS_SYMLINK, self::OSS_RESTORE, + self::OSS_TAGGING, + self::OSS_WORM_ID, + self::OSS_TRAFFIC_LIMIT, + self::OSS_VERSION_ID, ); foreach ($signableList as $item) { @@ -2670,6 +3449,14 @@ public function setConnectTimeout($connectTimeout) const OSS_STORAGE_STANDARD = 'Standard'; const OSS_STORAGE_IA = 'IA'; const OSS_STORAGE_ARCHIVE = 'Archive'; + const OSS_STORAGE_COLDARCHIVE = 'ColdArchive'; + const OSS_TAGGING = 'tagging'; + const OSS_WORM_ID = 'wormId'; + const OSS_RESTORE_CONFIG = 'restore-config'; + const OSS_KEY_MARKER = 'key-marker'; + const OSS_VERSION_ID_MARKER = 'version-id-marker'; + const OSS_VERSION_ID = 'versionId'; + const OSS_HEADER_VERSION_ID = 'x-oss-version-id'; //private URLs const OSS_URL_ACCESS_KEY_ID = 'OSSAccessKeyId'; @@ -2693,6 +3480,8 @@ public function setConnectTimeout($connectTimeout) const OSS_PROCESS = "x-oss-process"; const OSS_CALLBACK = "x-oss-callback"; const OSS_CALLBACK_VAR = "x-oss-callback-var"; + const OSS_REQUEST_PAYER = "x-oss-request-payer"; + const OSS_TRAFFIC_LIMIT = "x-oss-traffic-limit"; //Constants for STS SecurityToken const OSS_SECURITY_TOKEN = "x-oss-security-token"; const OSS_ACL_TYPE_PRIVATE = 'private'; @@ -2714,8 +3503,8 @@ public function setConnectTimeout($connectTimeout) ); // OssClient version information const OSS_NAME = "aliyun-sdk-php"; - const OSS_VERSION = "2.3.1"; - const OSS_BUILD = "20191115"; + const OSS_VERSION = "2.4.1"; + const OSS_BUILD = "20200929"; const OSS_AUTHOR = ""; const OSS_OPTIONS_ORIGIN = 'Origin'; const OSS_OPTIONS_REQUEST_METHOD = 'Access-Control-Request-Method'; diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/CopyObjectResult.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/CopyObjectResult.php index 498723e1b..6ed67c612 100644 --- a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/CopyObjectResult.php +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/CopyObjectResult.php @@ -25,6 +25,6 @@ protected function parseDataFromResponse() $result[] = $xml->ETag; } - return $result; + return array_merge($result, $this->rawResponse->header); } } diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/DeleteObjectVersionsResult.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/DeleteObjectVersionsResult.php new file mode 100644 index 000000000..69f52a735 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/DeleteObjectVersionsResult.php @@ -0,0 +1,39 @@ +rawResponse->body); + $encodingType = isset($xml->EncodingType) ? strval($xml->EncodingType) : ""; + return $this->parseDeletedList($xml, $encodingType); + } + + private function parseDeletedList($xml, $encodingType) + { + $retList = array(); + if (isset($xml->Deleted)) { + foreach ($xml->Deleted as $content) { + $key = isset($content->Key) ? strval($content->Key) : ""; + $key = OssUtil::decodeKey($key, $encodingType); + $versionId = isset($content->VersionId) ? strval($content->VersionId) : ""; + $deleteMarker = isset($content->DeleteMarker) ? strval($content->DeleteMarker) : ""; + $deleteMarkerVersionId = isset($content->DeleteMarkerVersionId) ? strval($content->DeleteMarkerVersionId) : ""; + $retList[] = new DeletedObjectInfo($key, $versionId, $deleteMarker, $deleteMarkerVersionId); + } + } + return $retList; + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketEncryptionResult.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketEncryptionResult.php new file mode 100644 index 000000000..3987cc927 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketEncryptionResult.php @@ -0,0 +1,26 @@ +rawResponse->body; + $config = new ServerSideEncryptionConfig(); + $config->parseFromXml($content); + return $config; + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketInfoResult.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketInfoResult.php new file mode 100644 index 000000000..ad55e95bc --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketInfoResult.php @@ -0,0 +1,37 @@ +rawResponse->body; + if (empty($content)) { + throw new OssException("body is null"); + } + $xml = simplexml_load_string($content); + if (isset($xml->Bucket)) { + $info = new BucketInfo(); + $info->parseFromXmlNode($xml->Bucket); + return $info; + } else { + throw new OssException("xml format exception"); + } + } +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketRequestPaymentResult.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketRequestPaymentResult.php new file mode 100644 index 000000000..5107de3f6 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketRequestPaymentResult.php @@ -0,0 +1,26 @@ +rawResponse->body; + $config = new RequestPaymentConfig(); + $config->parseFromXml($content); + return $config->getPayer(); + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketStatResult.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketStatResult.php new file mode 100644 index 000000000..aa310cf1f --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketStatResult.php @@ -0,0 +1,26 @@ +rawResponse->body; + $stat = new BucketStat(); + $stat->parseFromXml($content); + return $stat; + } +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketTagsResult.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketTagsResult.php new file mode 100644 index 000000000..59b4dd790 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketTagsResult.php @@ -0,0 +1,26 @@ +rawResponse->body; + $config = new TaggingConfig(); + $config->parseFromXml($content); + return $config; + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketVersioningResult.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketVersioningResult.php new file mode 100644 index 000000000..225190c21 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketVersioningResult.php @@ -0,0 +1,26 @@ +rawResponse->body; + $config = new VersioningConfig(); + $config->parseFromXml($content); + return $config->getStatus(); + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketWormResult.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketWormResult.php new file mode 100644 index 000000000..958720417 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/GetBucketWormResult.php @@ -0,0 +1,26 @@ +rawResponse->body; + $config = new WormConfig(); + $config->parseFromXml($content); + return $config; + } +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/InitiateBucketWormResult.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/InitiateBucketWormResult.php new file mode 100644 index 000000000..1cd7a0200 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/InitiateBucketWormResult.php @@ -0,0 +1,27 @@ +rawResponse->header; + if (isset($header["x-oss-worm-id"])) { + return strval($header["x-oss-worm-id"]); + } + throw new OssException("cannot get worm-id"); + } +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/ListBucketsResult.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/ListBucketsResult.php index a58fb2d61..1dd037b70 100644 --- a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/ListBucketsResult.php +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/ListBucketsResult.php @@ -22,9 +22,8 @@ protected function parseDataFromResponse() $xml = new \SimpleXMLElement($content); if (isset($xml->Buckets) && isset($xml->Buckets->Bucket)) { foreach ($xml->Buckets->Bucket as $bucket) { - $bucketInfo = new BucketInfo(strval($bucket->Location), - strval($bucket->Name), - strval($bucket->CreationDate)); + $bucketInfo = new BucketInfo(); + $bucketInfo->parseFromXmlNode($bucket); $bucketList[] = $bucketInfo; } } diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/ListObjectVersionsResult.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/ListObjectVersionsResult.php new file mode 100644 index 000000000..5f18c4df6 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Result/ListObjectVersionsResult.php @@ -0,0 +1,96 @@ +rawResponse->body); + $encodingType = isset($xml->EncodingType) ? strval($xml->EncodingType) : ""; + $objectVersionList = $this->parseObjecVersionList($xml, $encodingType); + $deleteMarkerList = $this->parseDeleteMarkerList($xml, $encodingType); + $prefixList = $this->parsePrefixList($xml, $encodingType); + $bucketName = isset($xml->Name) ? strval($xml->Name) : ""; + $prefix = isset($xml->Prefix) ? strval($xml->Prefix) : ""; + $prefix = OssUtil::decodeKey($prefix, $encodingType); + $keyMarker = isset($xml->KeyMarker) ? strval($xml->KeyMarker) : ""; + $keyMarker = OssUtil::decodeKey($keyMarker, $encodingType); + $nextKeyMarker = isset($xml->NextKeyMarker) ? strval($xml->NextKeyMarker) : ""; + $nextKeyMarker = OssUtil::decodeKey($nextKeyMarker, $encodingType); + $versionIdMarker = isset($xml->VersionIdMarker) ? strval($xml->VersionIdMarker) : ""; + $nextVersionIdMarker = isset($xml->NextVersionIdMarker) ? strval($xml->NextVersionIdMarker) : ""; + $maxKeys = isset($xml->MaxKeys) ? intval($xml->MaxKeys) : 0; + $delimiter = isset($xml->Delimiter) ? strval($xml->Delimiter) : ""; + $delimiter = OssUtil::decodeKey($delimiter, $encodingType); + $isTruncated = isset($xml->IsTruncated) ? strval($xml->IsTruncated) : ""; + + return new ObjectVersionListInfo($bucketName, $prefix, $keyMarker, $nextKeyMarker, + $versionIdMarker, $nextVersionIdMarker,$maxKeys, $delimiter, $isTruncated, + $objectVersionList, $deleteMarkerList, $prefixList); + } + + private function parseObjecVersionList($xml, $encodingType) + { + $retList = array(); + if (isset($xml->Version)) { + foreach ($xml->Version as $content) { + $key = isset($content->Key) ? strval($content->Key) : ""; + $key = OssUtil::decodeKey($key, $encodingType); + $versionId = isset($content->VersionId) ? strval($content->VersionId) : ""; + $lastModified = isset($content->LastModified) ? strval($content->LastModified) : ""; + $eTag = isset($content->ETag) ? strval($content->ETag) : ""; + $type = isset($content->Type) ? strval($content->Type) : ""; + $size = isset($content->Size) ? intval($content->Size) : 0; + $storageClass = isset($content->StorageClass) ? strval($content->StorageClass) : ""; + $isLatest = isset($content->IsLatest) ? strval($content->IsLatest) : ""; + $retList[] = new ObjectVersionInfo($key, $versionId, $lastModified, $eTag, $type, $size, $storageClass, $isLatest); + } + } + return $retList; + } + + private function parseDeleteMarkerList($xml, $encodingType) + { + $retList = array(); + if (isset($xml->DeleteMarker)) { + foreach ($xml->DeleteMarker as $content) { + $key = isset($content->Key) ? strval($content->Key) : ""; + $key = OssUtil::decodeKey($key, $encodingType); + $versionId = isset($content->VersionId) ? strval($content->VersionId) : ""; + $lastModified = isset($content->LastModified) ? strval($content->LastModified) : ""; + $isLatest = isset($content->IsLatest) ? strval($content->IsLatest) : ""; + $retList[] = new DeleteMarkerInfo($key, $versionId, $lastModified, $isLatest); + } + } + return $retList; + } + + private function parsePrefixList($xml, $encodingType) + { + $retList = array(); + if (isset($xml->CommonPrefixes)) { + foreach ($xml->CommonPrefixes as $commonPrefix) { + $prefix = isset($commonPrefix->Prefix) ? strval($commonPrefix->Prefix) : ""; + $prefix = OssUtil::decodeKey($prefix, $encodingType); + $retList[] = new PrefixInfo($prefix); + } + } + return $retList; + } +} \ No newline at end of file diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/BucketLiveChannelTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/BucketLiveChannelTest.php index bed68b036..aaebadb1e 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/BucketLiveChannelTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/BucketLiveChannelTest.php @@ -195,6 +195,39 @@ public function testSignRtmpUrl() $this->assertEquals('playlist.m3u8', $query['playlistName']); } + public function testGetgenPreSignedRtmpUrlVsSignedRtmpUrl() + { + $channelName = '90475'; + $bucket = 'douyu'; + $url1 = '245'; + $url2 = '123'; + $expiration = 0; + + do { + $begin = time(); + $expiration = time() + 900; + $url1 = $this->client->generatePresignedRtmpUrl($bucket, $channelName, $expiration, array( + 'params' => array( + 'playlistName' => 'playlist.m3u8' + ) + )); + + $url2 = $this->client->signRtmpUrl($bucket, $channelName, 900, array( + 'params' => array( + 'playlistName' => 'playlist.m3u8' + ) + )); + + $end = time(); + + if ($begin == $end) + break; + usleep(500000); + } while (true); + $this->assertEquals($url1, $url1); + $this->assertTrue(strpos($url1, 'Expires='.$expiration) !== false); + } + public function testLiveChannelInfo() { $channelName = 'live-to-put-status'; diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ContentTypeTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ContentTypeTest.php index 606c81041..66b405775 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ContentTypeTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ContentTypeTest.php @@ -4,7 +4,7 @@ require_once __DIR__ . '/Common.php'; -class ContentTypeTest extends \PHPUnit_Framework_TestCase +class ContentTypeTest extends TestOssClientBase { private function runCmd($cmd) { @@ -17,15 +17,15 @@ private function runCmd($cmd) private function getContentType($bucket, $object) { - $client = Common::getOssClient(); + $client = $this->ossClient; $headers = $client->getObjectMeta($bucket, $object); return $headers['content-type']; } public function testByFileName() { - $client = Common::getOssClient(); - $bucket = Common::getBucketName(); + $client = $this->ossClient; + $bucket = $this->bucket; $file = '/tmp/x.html'; $object = 'test/x'; @@ -48,8 +48,8 @@ public function testByFileName() public function testByObjectKey() { - $client = Common::getOssClient(); - $bucket = Common::getBucketName(); + $client = $this->ossClient; + $bucket = $this->bucket; $object = "test/x.txt"; $client->putObject($bucket, $object, "hello world"); @@ -96,8 +96,8 @@ public function testByObjectKey() public function testByUser() { - $client = Common::getOssClient(); - $bucket = Common::getBucketName(); + $client = $this->ossClient; + $bucket = $this->bucket; $object = "test/x.txt"; $client->putObject($bucket, $object, "hello world", array( diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/DeleteObjectVersionsResultTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/DeleteObjectVersionsResultTest.php new file mode 100644 index 000000000..ed6b95e1c --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/DeleteObjectVersionsResultTest.php @@ -0,0 +1,187 @@ + + + + demo.jpg + CAEQNRiBgICEoPiC0BYiIGMxZWJmYmMzYjE0OTQ0ZmZhYjgzNzkzYjc2NjZk**** + true + 111111 + + + BBBB; + + private $validXml1 = << + + + multipart.data + CAEQNRiBgIDyz.6C0BYiIGQ2NWEwNmVhNTA3ZTQ3MzM5ODliYjM1ZTdjYjA4**** + + + BBBB; + + private $validXml2 = << + + + multipart.data + true + CAEQMhiBgIDXiaaB0BYiIGQzYmRkZGUxMTM1ZDRjOTZhNjk4YjRjMTAyZjhl**** + + + test.jpg + true + CAEQMhiBgIDB3aWB0BYiIGUzYTA3YzliMzVmNzRkZGM5NjllYTVlMjYyYWEy**** + + + BBBB; + + private $validXml3 = << + + + multipart.data + + + test.jpg + + + demo.jpg + + + BBBB; + + private $validXml4 = << + + url + + multipart%2F.data + + + test%2F.jpg + + + demo%2F.jpg + + + BBBB; + + private $invalidXml = << + + + BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new DeleteObjectVersionsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $list = $result->getData(); + $this->assertEquals(1, count($list)); + $this->assertEquals('demo.jpg', $list[0]->getKey()); + $this->assertEquals('CAEQNRiBgICEoPiC0BYiIGMxZWJmYmMzYjE0OTQ0ZmZhYjgzNzkzYjc2NjZk****', $list[0]->getVersionId()); + $this->assertEquals('true', $list[0]->getDeleteMarker()); + $this->assertEquals('111111', $list[0]->getDeleteMarkerVersionId()); + + + $response = new ResponseCore(array(), $this->validXml1, 200); + $result = new DeleteObjectVersionsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $list = $result->getData(); + $this->assertEquals(1, count($list)); + $this->assertEquals('multipart.data', $list[0]->getKey()); + $this->assertEquals('CAEQNRiBgIDyz.6C0BYiIGQ2NWEwNmVhNTA3ZTQ3MzM5ODliYjM1ZTdjYjA4****', $list[0]->getVersionId()); + $this->assertEquals('', $list[0]->getDeleteMarker()); + $this->assertEquals('', $list[0]->getDeleteMarkerVersionId()); + + $response = new ResponseCore(array(), $this->validXml2, 200); + $result = new DeleteObjectVersionsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $list = $result->getData(); + $this->assertEquals(2, count($list)); + $this->assertEquals('multipart.data', $list[0]->getKey()); + $this->assertEquals('', $list[0]->getVersionId()); + $this->assertEquals('true', $list[0]->getDeleteMarker()); + $this->assertEquals('CAEQMhiBgIDXiaaB0BYiIGQzYmRkZGUxMTM1ZDRjOTZhNjk4YjRjMTAyZjhl****', $list[0]->getDeleteMarkerVersionId()); + $this->assertEquals('test.jpg', $list[1]->getKey()); + $this->assertEquals('', $list[1]->getVersionId()); + $this->assertEquals('true', $list[1]->getDeleteMarker()); + $this->assertEquals('CAEQMhiBgIDB3aWB0BYiIGUzYTA3YzliMzVmNzRkZGM5NjllYTVlMjYyYWEy****', $list[1]->getDeleteMarkerVersionId()); + + + $response = new ResponseCore(array(), $this->validXml3, 200); + $result = new DeleteObjectVersionsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $list = $result->getData(); + $this->assertEquals(3, count($list)); + $this->assertEquals('multipart.data', $list[0]->getKey()); + $this->assertEquals('', $list[0]->getVersionId()); + $this->assertEquals('', $list[0]->getDeleteMarker()); + $this->assertEquals('', $list[0]->getDeleteMarkerVersionId()); + $this->assertEquals('test.jpg', $list[1]->getKey()); + $this->assertEquals('', $list[1]->getVersionId()); + $this->assertEquals('', $list[1]->getDeleteMarker()); + $this->assertEquals('', $list[1]->getDeleteMarkerVersionId()); + $this->assertEquals('demo.jpg', $list[2]->getKey()); + $this->assertEquals('', $list[2]->getVersionId()); + $this->assertEquals('', $list[2]->getDeleteMarker()); + $this->assertEquals('', $list[2]->getDeleteMarkerVersionId()); + + $response = new ResponseCore(array(), $this->validXml4, 200); + $result = new DeleteObjectVersionsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $list = $result->getData(); + $this->assertEquals(3, count($list)); + $this->assertEquals('multipart/.data', $list[0]->getKey()); + $this->assertEquals('', $list[0]->getVersionId()); + $this->assertEquals('', $list[0]->getDeleteMarker()); + $this->assertEquals('', $list[0]->getDeleteMarkerVersionId()); + $this->assertEquals('test/.jpg', $list[1]->getKey()); + $this->assertEquals('', $list[1]->getVersionId()); + $this->assertEquals('', $list[1]->getDeleteMarker()); + $this->assertEquals('', $list[1]->getDeleteMarkerVersionId()); + $this->assertEquals('demo/.jpg', $list[2]->getKey()); + $this->assertEquals('', $list[2]->getVersionId()); + $this->assertEquals('', $list[2]->getDeleteMarker()); + $this->assertEquals('', $list[2]->getDeleteMarkerVersionId()); + } + + public function testParseNullXml() + { + $response = new ResponseCore(array(), "", 200); + $result = new DeleteObjectVersionsResult($response); + $list = $result->getData(); + $this->assertEquals(0, count($list)); + } + + public function testParseInvalidXml() + { + $response = new ResponseCore(array(), $this->invalidXml, 200); + $result = new DeleteObjectVersionsResult($response); + $list = $result->getData(); + $this->assertEquals(0, count($list)); + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketEncryptionResultTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketEncryptionResultTest.php new file mode 100644 index 000000000..4512eb4d5 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketEncryptionResultTest.php @@ -0,0 +1,95 @@ + + + + AES256 + + + + BBBB; + + private $validXml1 = << + + + KMS + kms-id + + + BBBB; + + private $validXml2 = << + + + KMS + + + BBBB; + + private $invalidXml = << + + + BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new GetBucketEncryptionResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $config = $result->getData(); + $this->assertEquals("AES256", $config->getSSEAlgorithm()); + $this->assertEquals("", $config->getKMSMasterKeyID()); + + + $response = new ResponseCore(array(), $this->validXml1, 200); + $result = new GetBucketEncryptionResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $config = $result->getData(); + $this->assertEquals("KMS", $config->getSSEAlgorithm()); + $this->assertEquals("kms-id", $config->getKMSMasterKeyID()); + + $response = new ResponseCore(array(), $this->validXml2, 200); + $result = new GetBucketEncryptionResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $config = $result->getData(); + $this->assertEquals("KMS", $config->getSSEAlgorithm()); + $this->assertEquals(null, $config->getKMSMasterKeyID()); + } + + public function testParseNullXml() + { + $response = new ResponseCore(array(), "", 200); + $result = new GetBucketEncryptionResult($response); + $config = $result->getData(); + $this->assertEquals(null, $config->getSSEAlgorithm()); + $this->assertEquals(null, $config->getKMSMasterKeyID()); + } + + public function testParseInvalidXml() + { + $response = new ResponseCore(array(), $this->invalidXml, 200); + $result = new GetBucketEncryptionResult($response); + $config = $result->getData(); + $this->assertEquals(null, $config->getSSEAlgorithm()); + $this->assertEquals(null, $config->getKMSMasterKeyID()); + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketRequestPaymentResultTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketRequestPaymentResultTest.php new file mode 100644 index 000000000..85f575add --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketRequestPaymentResultTest.php @@ -0,0 +1,66 @@ + + + Requester + + BBBB; + + private $validXml2 = << + + BucketOwner + + BBBB; + + private $invalidXml = << + + + BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new GetBucketRequestPaymentResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $payer = $result->getData(); + $this->assertEquals("Requester", $payer); + + $response = new ResponseCore(array(), $this->validXml2, 200); + $result = new GetBucketRequestPaymentResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $payer = $result->getData(); + $this->assertEquals("BucketOwner", $payer); + } + + public function testParseNullXml() + { + $response = new ResponseCore(array(), "", 200); + $result = new GetBucketRequestPaymentResult($response); + $payer = $result->getData(); + $this->assertEquals(null, $payer); + } + + public function testParseInvalidXml() + { + $response = new ResponseCore(array(), $this->invalidXml, 200); + $result = new GetBucketRequestPaymentResult($response); + $payer = $result->getData(); + $this->assertEquals(null, $payer); + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketStatResultTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketStatResultTest.php new file mode 100644 index 000000000..f6138e97e --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketStatResultTest.php @@ -0,0 +1,59 @@ + + + 100 + 200 + 10 + + BBBB; + + private $invalidXml = << + + + BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new GetBucketStatResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $stat = $result->getData(); + $this->assertEquals(100, $stat->getStorage()); + $this->assertEquals(200, $stat->getObjectCount()); + $this->assertEquals(10, $stat->getMultipartUploadCount()); + } + + public function testParseNullXml() + { + $response = new ResponseCore(array(), "", 200); + $result = new GetBucketStatResult($response); + $stat = $result->getData(); + $this->assertEquals(0, $stat->getStorage()); + $this->assertEquals(0, $stat->getObjectCount()); + $this->assertEquals(0, $stat->getMultipartUploadCount()); + } + + public function testParseInvalidXml() + { + $response = new ResponseCore(array(), $this->invalidXml, 200); + $result = new GetBucketStatResult($response); + $stat = $result->getData(); + $this->assertEquals(0, $stat->getStorage()); + $this->assertEquals(0, $stat->getObjectCount()); + $this->assertEquals(0, $stat->getMultipartUploadCount()); + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketTagsResultTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketTagsResultTest.php new file mode 100644 index 000000000..c820e4107 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketTagsResultTest.php @@ -0,0 +1,77 @@ + + + + + testa + value1-test + + + testb + value2-test + + + + BBBB; + + private $invalidXml = << + + + BBBB; + + private $invalidXml2 = << + + + + + BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new GetBucketTagsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $config = $result->getData(); + $this->assertEquals(2, count($config->getTags())); + $this->assertEquals("testa", $config->getTags()[0]->getKey()); + $this->assertEquals("value1-test", $config->getTags()[0]->getValue()); + $this->assertEquals("testb", $config->getTags()[1]->getKey()); + $this->assertEquals("value2-test", $config->getTags()[1]->getValue()); + } + + public function testParseNullXml() + { + $response = new ResponseCore(array(), "", 200); + $result = new GetBucketTagsResult($response); + $config = $result->getData(); + $this->assertEquals(0, count($config->getTags())); + + } + + public function testParseInvalidXml() + { + $response = new ResponseCore(array(), $this->invalidXml, 200); + $result = new GetBucketTagsResult($response); + $config = $result->getData(); + $this->assertEquals(0, count($config->getTags())); + + $response = new ResponseCore(array(), $this->invalidXml2, 200); + $result = new GetBucketTagsResult($response); + $config = $result->getData(); + $this->assertEquals(0, count($config->getTags())); + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketWormResultTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketWormResultTest.php new file mode 100644 index 000000000..aefc8ab6b --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketWormResultTest.php @@ -0,0 +1,84 @@ + + + ID1 + Locked + 1 + 2018-08-14T15:50:32 + + BBBB; + + private $validXml2 = << + + ID2 + InProgress + 10 + 2018-09-14T15:50:32 + + BBBB; + + private $invalidXml = << + + + BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new GetBucketWormResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $config = $result->getData(); + $this->assertEquals("ID1", $config->getWormId()); + $this->assertEquals("Locked", $config->getState()); + $this->assertEquals(1, $config->getDay()); + $this->assertEquals("2018-08-14T15:50:32", $config->getCreationDate()); + + $response = new ResponseCore(array(), $this->validXml2, 200); + $result = new GetBucketWormResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $config = $result->getData(); + $this->assertEquals("ID2", $config->getWormId()); + $this->assertEquals("InProgress", $config->getState()); + $this->assertEquals(10, $config->getDay()); + $this->assertEquals("2018-09-14T15:50:32", $config->getCreationDate()); + } + + public function testParseNullXml() + { + $response = new ResponseCore(array(), "", 200); + $result = new GetBucketWormResult($response); + $config = $result->getData(); + $this->assertEquals("", $config->getWormId()); + $this->assertEquals("", $config->getState()); + $this->assertEquals(0, $config->getDay()); + $this->assertEquals("", $config->getCreationDate()); + } + + public function testParseInvalidXml() + { + $response = new ResponseCore(array(), $this->invalidXml, 200); + $result = new GetBucketWormResult($response); + $config = $result->getData(); + $this->assertEquals("", $config->getWormId()); + $this->assertEquals("", $config->getState()); + $this->assertEquals(0, $config->getDay()); + $this->assertEquals("", $config->getCreationDate()); + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ListBucketsResultTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ListBucketsResultTest.php index 1abe1f503..f4b13aebf 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ListBucketsResultTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ListBucketsResultTest.php @@ -71,15 +71,15 @@ public function test403() ); $errorBody = <<< BBBB - - - NoSuchBucket - The specified bucket does not exist. - 566B870D207FB3044302EB0A - hello.oss-test.aliyun-inc.com - hello - -BBBB; + + + NoSuchBucket + The specified bucket does not exist. + 566B870D207FB3044302EB0A + hello.oss-test.aliyun-inc.com + hello + + BBBB; $response = new ResponseCore($errorHeader, $errorBody, 403); try { new ListBucketsResult($response); @@ -94,4 +94,74 @@ public function test403() $this->assertEquals($e->getDetails(), $errorBody); } } + + public function testParseXml2() + { + $xml = << + + + ut_test_put_bucket + ut_test_put_bucket + + + + 2015-12-17T18:12:43.000Z + oss-cn-shanghai.aliyuncs.com + oss-cn-shanghai-internal.aliyuncs.com + oss-cn-shanghai + app-base-oss + cn-shanghai + Standard + + + 2014-12-25T11:21:04.000Z + oss-cn-hangzhou.aliyuncs.com + oss-cn-hangzhou-internal.aliyuncs.com + oss-cn-hangzhou + atestleo23 + cn-hangzhou + IA + + + 2014-12-25T11:21:04.000Z + oss-cn-hangzhou + atestleo23 + + + + BBBB; + + $response = new ResponseCore(array(), $xml, 200); + $result = new ListBucketsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $bucketListInfo = $result->getData(); + $this->assertEquals(3, count($bucketListInfo->getBucketList())); + $this->assertEquals("2015-12-17T18:12:43.000Z", $bucketListInfo->getBucketList()[0]->getCreateDate()); + $this->assertEquals("oss-cn-shanghai", $bucketListInfo->getBucketList()[0]->getLocation()); + $this->assertEquals("app-base-oss", $bucketListInfo->getBucketList()[0]->getName()); + $this->assertEquals("oss-cn-shanghai.aliyuncs.com", $bucketListInfo->getBucketList()[0]->getExtranetEndpoint()); + $this->assertEquals("oss-cn-shanghai-internal.aliyuncs.com", $bucketListInfo->getBucketList()[0]->getIntranetEndpoint()); + $this->assertEquals("cn-shanghai", $bucketListInfo->getBucketList()[0]->getRegion()); + $this->assertEquals("Standard", $bucketListInfo->getBucketList()[0]->getStorageClass()); + + $this->assertEquals("2014-12-25T11:21:04.000Z", $bucketListInfo->getBucketList()[1]->getCreateDate()); + $this->assertEquals("oss-cn-hangzhou", $bucketListInfo->getBucketList()[1]->getLocation()); + $this->assertEquals("atestleo23", $bucketListInfo->getBucketList()[1]->getName()); + $this->assertEquals("oss-cn-hangzhou.aliyuncs.com", $bucketListInfo->getBucketList()[1]->getExtranetEndpoint()); + $this->assertEquals("oss-cn-hangzhou-internal.aliyuncs.com", $bucketListInfo->getBucketList()[1]->getIntranetEndpoint()); + $this->assertEquals("cn-hangzhou", $bucketListInfo->getBucketList()[1]->getRegion()); + $this->assertEquals("IA", $bucketListInfo->getBucketList()[1]->getStorageClass()); + + $this->assertEquals("2014-12-25T11:21:04.000Z", $bucketListInfo->getBucketList()[2]->getCreateDate()); + $this->assertEquals("oss-cn-hangzhou", $bucketListInfo->getBucketList()[2]->getLocation()); + $this->assertEquals("atestleo23", $bucketListInfo->getBucketList()[2]->getName()); + $this->assertEquals(null, $bucketListInfo->getBucketList()[2]->getExtranetEndpoint()); + $this->assertEquals(null, $bucketListInfo->getBucketList()[2]->getIntranetEndpoint()); + $this->assertEquals(null, $bucketListInfo->getBucketList()[2]->getRegion()); + $this->assertEquals(null, $bucketListInfo->getBucketList()[2]->getStorageClass()); + + } } diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ListObjectVersionsResultTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ListObjectVersionsResultTest.php new file mode 100644 index 000000000..f386c68e4 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ListObjectVersionsResultTest.php @@ -0,0 +1,213 @@ + + + oss-example + + example + CAEQMxiBgICbof2D0BYiIGRhZjgwMzJiMjA3MjQ0ODE5MWYxZDYwMzJlZjU1**** + 100 + + false + + example + CAEQMxiBgICAof2D0BYiIDJhMGE3N2M1YTI1NDQzOGY5NTkyNTI3MGYyMzJm**** + false + 2019-04-09T07:27:28.000Z + + 1234512528586**** + 12345125285864390 + + + + example + CAEQMxiBgMDNoP2D0BYiIDE3MWUxNzgxZDQxNTRiODI5OGYwZGMwNGY3MzZjN**** + false + 2019-04-09T07:27:28.000Z + "250F8A0AE989679A22926A875F0A2****" + Normal + 93731 + Standard + + 1234512528586**** + 12345125285864390 + + + + pic.jpg + CAEQMxiBgMCZov2D0BYiIDY4MDllOTc2YmY5MjQxMzdiOGI3OTlhNTU0ODIx**** + true + 2019-04-09T07:27:28.000Z + "3663F7B0B9D3153F884C821E7CF4****" + Normal + 574768 + IA + + 1234512528586**** + 12345125285864390 + + + + BBBB; + + private $validXml1 = << + + oss-example + + example + CAEQMxiBgICbof2D0BYiIGRhZjgwMzJiMjA3MjQ0ODE5MWYxZDYwMzJlZjU1**** + 100 + + false + + example + CAEQMxiBgICAof2D0BYiIDJhMGE3N2M1YTI1NDQzOGY5NTkyNTI3MGYyMzJm**** + true + 2019-04-09T07:27:28.000Z + + 1234512528586**** + 12345125285864390 + + + + example-1 + CAEQMxiBgICAof2D0BYiIDJhMGE3N2M1YTI1NDQzOGY5NTkyNTI3MGYyMzJm**** + 2019-04-09T07:27:28.000Z + + 1234512528586**** + 12345125285864390 + + + + example-2 + CAEQMxiBgMDNoP2D0BYiIDE3MWUxNzgxZDQxNTRiODI5OGYwZGMwNGY3MzZjN**** + 2019-04-09T07:27:28.000Z + "250F8A0AE989679A22926A875F0A2****" + Normal + 93731 + Standard + + 1234512528586**** + 12345125285864390 + + + + BBBB; + + private $invalidXml = << + + + BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new ListObjectVersionsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $list = $result->getData(); + $this->assertEquals(0, count($list->getPrefixList())); + $this->assertEquals(1, count($list->getDeleteMarkerList())); + $this->assertEquals(2, count($list->getObjectVersionList())); + + $this->assertEquals('oss-example', $list->getBucketName()); + $this->assertEquals('', $list->getPrefix()); + $this->assertEquals('example', $list->getKeyMarker()); + $this->assertEquals('CAEQMxiBgICbof2D0BYiIGRhZjgwMzJiMjA3MjQ0ODE5MWYxZDYwMzJlZjU1****', $list->getVersionIdMarker()); + $this->assertEquals(100, $list->getMaxKeys()); + $this->assertEquals('', $list->getDelimiter()); + $this->assertEquals('false', $list->getIsTruncated()); + + $deleteMarkerList = $list->getDeleteMarkerList(); + $this->assertEquals('example', $deleteMarkerList[0]->getKey()); + $this->assertEquals('CAEQMxiBgICAof2D0BYiIDJhMGE3N2M1YTI1NDQzOGY5NTkyNTI3MGYyMzJm****', $deleteMarkerList[0]->getVersionId()); + $this->assertEquals('false', $deleteMarkerList[0]->getIsLatest()); + $this->assertEquals('2019-04-09T07:27:28.000Z', $deleteMarkerList[0]->getLastModified()); + + $objectVersionList = $list->getObjectVersionList(); + $this->assertEquals('example', $objectVersionList[0]->getKey()); + $this->assertEquals('CAEQMxiBgMDNoP2D0BYiIDE3MWUxNzgxZDQxNTRiODI5OGYwZGMwNGY3MzZjN****', $objectVersionList[0]->getVersionId()); + $this->assertEquals('false', $objectVersionList[0]->getIsLatest()); + $this->assertEquals('2019-04-09T07:27:28.000Z', $objectVersionList[0]->getLastModified()); + $this->assertEquals('"250F8A0AE989679A22926A875F0A2****"', $objectVersionList[0]->getETag()); + $this->assertEquals('Normal', $objectVersionList[0]->getType()); + $this->assertEquals(93731, $objectVersionList[0]->getSize()); + $this->assertEquals('Standard', $objectVersionList[0]->getStorageClass()); + + $this->assertEquals('pic.jpg', $objectVersionList[1]->getKey()); + $this->assertEquals('CAEQMxiBgMCZov2D0BYiIDY4MDllOTc2YmY5MjQxMzdiOGI3OTlhNTU0ODIx****', $objectVersionList[1]->getVersionId()); + $this->assertEquals('true', $objectVersionList[1]->getIsLatest()); + $this->assertEquals('2019-04-09T07:27:28.000Z', $objectVersionList[1]->getLastModified()); + $this->assertEquals('"3663F7B0B9D3153F884C821E7CF4****"', $objectVersionList[1]->getETag()); + $this->assertEquals('Normal', $objectVersionList[1]->getType()); + $this->assertEquals(574768, $objectVersionList[1]->getSize()); + $this->assertEquals('IA', $objectVersionList[1]->getStorageClass()); + + + $response = new ResponseCore(array(), $this->validXml1, 200); + $result = new ListObjectVersionsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $list = $result->getData(); + $this->assertEquals(0, count($list->getPrefixList())); + $this->assertEquals(2, count($list->getDeleteMarkerList())); + $this->assertEquals(1, count($list->getObjectVersionList())); + + $this->assertEquals('oss-example', $list->getBucketName()); + $this->assertEquals('', $list->getPrefix()); + $this->assertEquals('example', $list->getKeyMarker()); + $this->assertEquals('CAEQMxiBgICbof2D0BYiIGRhZjgwMzJiMjA3MjQ0ODE5MWYxZDYwMzJlZjU1****', $list->getVersionIdMarker()); + $this->assertEquals(100, $list->getMaxKeys()); + $this->assertEquals('', $list->getDelimiter()); + $this->assertEquals('false', $list->getIsTruncated()); + + $deleteMarkerList = $list->getDeleteMarkerList(); + $this->assertEquals('example', $deleteMarkerList[0]->getKey()); + $this->assertEquals('CAEQMxiBgICAof2D0BYiIDJhMGE3N2M1YTI1NDQzOGY5NTkyNTI3MGYyMzJm****', $deleteMarkerList[0]->getVersionId()); + $this->assertEquals('true', $deleteMarkerList[0]->getIsLatest()); + $this->assertEquals('2019-04-09T07:27:28.000Z', $deleteMarkerList[0]->getLastModified()); + + $this->assertEquals('example-1', $deleteMarkerList[1]->getKey()); + $this->assertEquals('CAEQMxiBgICAof2D0BYiIDJhMGE3N2M1YTI1NDQzOGY5NTkyNTI3MGYyMzJm****', $deleteMarkerList[1]->getVersionId()); + $this->assertEquals('', $deleteMarkerList[1]->getIsLatest()); + $this->assertEquals('2019-04-09T07:27:28.000Z', $deleteMarkerList[1]->getLastModified()); + + $objectVersionList = $list->getObjectVersionList(); + $this->assertEquals('example-2', $objectVersionList[0]->getKey()); + $this->assertEquals('CAEQMxiBgMDNoP2D0BYiIDE3MWUxNzgxZDQxNTRiODI5OGYwZGMwNGY3MzZjN****', $objectVersionList[0]->getVersionId()); + $this->assertEquals('', $objectVersionList[0]->getIsLatest()); + $this->assertEquals('2019-04-09T07:27:28.000Z', $objectVersionList[0]->getLastModified()); + $this->assertEquals('"250F8A0AE989679A22926A875F0A2****"', $objectVersionList[0]->getETag()); + $this->assertEquals('Normal', $objectVersionList[0]->getType()); + $this->assertEquals(93731, $objectVersionList[0]->getSize()); + $this->assertEquals('Standard', $objectVersionList[0]->getStorageClass()); + } + + public function testParseNullXml() + { + $response = new ResponseCore(array(), "", 200); + $result = new ListObjectVersionsResult($response); + $list = $result->getData(); + } + + public function testParseInvalidXml() + { + $response = new ResponseCore(array(), $this->invalidXml, 200); + $result = new ListObjectVersionsResult($response); + $stat = $result->getData(); + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/LiveChannelXmlTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/LiveChannelXmlTest.php index cc3e2199b..5fb5d6e7b 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/LiveChannelXmlTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/LiveChannelXmlTest.php @@ -4,11 +4,13 @@ require_once __DIR__ . '/Common.php'; +use OSS\Core\OssException; use OSS\Model\LiveChannelInfo; use OSS\Model\LiveChannelListInfo; use OSS\Model\LiveChannelConfig; use OSS\Model\GetLiveChannelStatus; use OSS\Model\GetLiveChannelHistory; +use OSS\Model\LiveChannelHistory; class LiveChannelXmlTest extends \PHPUnit_Framework_TestCase { @@ -139,7 +141,7 @@ public function testLiveChannelStatus() } - public function testLiveChannelHistory() + public function testGetLiveChannelHistory() { $history = new GetLiveChannelHistory(); $history->parseFromXml($this->history); @@ -246,4 +248,30 @@ public function testLiveChannelList() $this->assertEquals('http://bucket.oss-cn-hangzhou.aliyuncs.com/2/播放列表.m3u8', $plays[0]); } + public function testLiveChannelHistory() + { + $xml = "2013-11-24T14:25:31.000Z2013-11-24T15:25:31.000Z10.101.194.148:56861"; + $history = new LiveChannelHistory(); + $history->parseFromXml($xml); + + $this->assertEquals('2013-11-24T14:25:31.000Z', $history->getStartTime()); + $this->assertEquals('2013-11-24T15:25:31.000Z', $history->getEndTime()); + $this->assertEquals('10.101.194.148:56861', $history->getRemoteAddr()); + } + + public function testGetLiveChannelHistorySerializeToXml() + { + try { + $history = new GetLiveChannelHistory (); + $history->serializeToXml(); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + if (strpos($e, "Not implemented.") == false) + { + $this->assertTrue(false); + } + } + } + } diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ObjectAclTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ObjectAclTest.php index d39728814..9260a6a5d 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ObjectAclTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/ObjectAclTest.php @@ -4,12 +4,12 @@ require_once __DIR__ . '/Common.php'; -class ObjectAclTest extends \PHPUnit_Framework_TestCase +class ObjectAclTest extends TestOssClientBase { public function testGetSet() { - $client = Common::getOssClient(); - $bucket = Common::getBucketName(); + $client = $this->ossClient; + $bucket = $this->bucket; $object = 'test/object-acl'; $client->deleteObject($bucket, $object); diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketEncryptionTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketEncryptionTest.php new file mode 100644 index 000000000..42c51b29a --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketEncryptionTest.php @@ -0,0 +1,63 @@ +ossClient->putBucketEncryption($this->bucket, $config); + } catch (OssException $e) { + var_dump($e->getMessage()); + $this->assertTrue(false); + } + try { + Common::waitMetaSync(); + $config2 = $this->ossClient->getBucketEncryption($this->bucket); + $this->assertEquals($config->serializeToXml(), $config2->serializeToXml()); + $this->assertEquals("AES256", $config2->getSSEAlgorithm()); + $this->assertEquals(null, $config2->getKMSMasterKeyID()); + } catch (OssException $e) { + $this->assertTrue(false); + } + + $config = new ServerSideEncryptionConfig("KMS", "kms-id"); + try { + $this->ossClient->putBucketEncryption($this->bucket, $config); + } catch (OssException $e) { + var_dump($e->getMessage()); + $this->assertTrue(false); + } + try { + Common::waitMetaSync(); + $config2 = $this->ossClient->getBucketEncryption($this->bucket); + $this->assertEquals($config->serializeToXml(), $config2->serializeToXml()); + $this->assertEquals("KMS", $config2->getSSEAlgorithm()); + $this->assertEquals("kms-id", $config2->getKMSMasterKeyID()); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + Common::waitMetaSync(); + $this->ossClient->deleteBucketEncryption($this->bucket); + } catch (OssException $e) { + $this->assertTrue(false); + } + try { + Common::waitMetaSync(); + $config2 = $this->ossClient->getBucketEncryption($this->bucket); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals("NoSuchServerSideEncryptionRule", $e->getErrorCode()); + } + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketInfoTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketInfoTest.php new file mode 100644 index 000000000..759e536cc --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketInfoTest.php @@ -0,0 +1,20 @@ +ossClient->getBucketInfo($this->bucket); + $this->assertEquals($this->bucket, $info->getName()); + $this->assertEquals("Standard", $info->getStorageClass()); + } catch (OssException $e) { + $this->assertTrue(false); + } + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketPolicyTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketPolicyTest.php new file mode 100644 index 000000000..4f0c5ee66 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketPolicyTest.php @@ -0,0 +1,47 @@ +ossClient->deleteBucketPolicy($this->bucket); + $policy = $this->ossClient->getBucketPolicy($this->bucket); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + $this->assertEquals("NoSuchBucketPolicy", $e->getErrorCode()); + } + + try { + $this->ossClient->putBucketPolicy($this->bucket, $policy_str); + $policy = $this->ossClient->getBucketPolicy($this->bucket); + $this->assertEquals($policy_str, $policy); + $this->ossClient->deleteBucketPolicy($this->bucket); + } catch (OssException $e) { + $this->assertTrue(false); + } + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketRequestPaymentTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketRequestPaymentTest.php new file mode 100644 index 000000000..9a4b412e2 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketRequestPaymentTest.php @@ -0,0 +1,51 @@ +ossClient->getBucketRequestPayment($this->bucket); + $this->assertEquals("BucketOwner", $payer); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->ossClient->putBucketRequestPayment($this->bucket, "Requester"); + } catch (OssException $e) { + var_dump($e->getMessage()); + $this->assertTrue(false); + } + try { + Common::waitMetaSync(); + $payer = $this->ossClient->getBucketRequestPayment($this->bucket); + $this->assertEquals("Requester", $payer); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->ossClient->putBucketRequestPayment($this->bucket, "BucketOwner"); + } catch (OssException $e) { + var_dump($e->getMessage()); + $this->assertTrue(false); + } + try { + Common::waitMetaSync(); + $payer = $this->ossClient->getBucketRequestPayment($this->bucket); + $this->assertEquals("BucketOwner", $payer); + } catch (OssException $e) { + $this->assertTrue(false); + } + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketStatTestTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketStatTestTest.php new file mode 100644 index 000000000..7f847d8eb --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketStatTestTest.php @@ -0,0 +1,34 @@ +ossClient->putObject($this->bucket, "name-1.txt", $content); + $this->ossClient->putObject($this->bucket, "name-2.txt", $content); + $this->ossClient->putObject($this->bucket, "name-3.txt", $content); + + $object = "multipart-test.txt"; + $upload_id = $this->ossClient->initiateMultipartUpload($this->bucket, $object); + + Common::waitMetaSync(); + Common::waitMetaSync(); + Common::waitMetaSync(); + $stat = $this->ossClient->getBucketStat($this->bucket); + $this->assertEquals(3, $stat->getObjectCount()); + $this->assertEquals(15, $stat->getStorage()); + $this->assertEquals(1, $stat->getMultipartUploadCount()); + + } catch (OssException $e) { + $this->assertTrue(false); + } + } + +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketTagsTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketTagsTest.php new file mode 100644 index 000000000..bafa64b5f --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketTagsTest.php @@ -0,0 +1,76 @@ +ossClient->getBucketTags($this->bucket); + $this->assertEquals(0, count($config->getTags())); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $config = new TaggingConfig(); + $config->addTag(new Tag("key1", "value1")); + $config->addTag(new Tag("key2", "value2")); + $config->addTag(new Tag("key3", "value3")); + $this->ossClient->putBucketTags($this->bucket, $config); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + Common::waitMetaSync(); + $config2 = $this->ossClient->getBucketTags($this->bucket); + $this->assertEquals(3, count($config2->getTags())); + $this->assertEquals("key1", $config2->getTags()[0]->getKey()); + $this->assertEquals("value1", $config2->getTags()[0]->getValue()); + $this->assertEquals("key2", $config2->getTags()[1]->getKey()); + $this->assertEquals("value2", $config2->getTags()[1]->getValue()); + $this->assertEquals("key3", $config2->getTags()[2]->getKey()); + $this->assertEquals("value3", $config2->getTags()[2]->getValue()); + } catch (OssException $e) { + $this->assertTrue(false); + } + + + try { + Common::waitMetaSync(); + //del key1, key3 + $tags = array(); + $tags[] = new Tag("key1", "value1"); + $tags[] = new Tag("key3", "value3"); + + $this->ossClient->deleteBucketTags($this->bucket, $tags); + $config2 = $this->ossClient->getBucketTags($this->bucket); + $this->assertEquals(1, count($config2->getTags())); + $this->assertEquals("key2", $config2->getTags()[0]->getKey()); + $this->assertEquals("value2", $config2->getTags()[0]->getValue()); + } catch (OssException $e) { + $this->assertTrue(false); + } + + + try { + Common::waitMetaSync(); + //del all + $this->ossClient->deleteBucketTags($this->bucket); + $config2 = $this->ossClient->getBucketTags($this->bucket); + $this->assertEquals(0, count($config2->getTags())); + } catch (OssException $e) { + $this->assertTrue(false); + } + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketTest.php index d0a2a225f..df44fbaf6 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketTest.php @@ -10,6 +10,7 @@ class OssClientBucketTest extends TestOssClientBase { + private $standardBucket; private $iaBucket; private $archiveBucket; @@ -80,12 +81,31 @@ public function testCreateBucketWithStorageType() $this->assertEquals($result, 'testcontent'); } + public function testCreateBucketWithInvalidStorageType() + { + try { + $options = array( + OssClient::OSS_STORAGE => 'unknown' + ); + $this->ossClient->createBucket('bucket-name', OssClient::OSS_ACL_TYPE_PRIVATE, $options); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + if (strpos($e, "storage name is invalid") == false) + { + $this->assertTrue(false); + } + } + } + public function setUp() { parent::setUp(); $this->iaBucket = 'ia-' . $this->bucket; $this->archiveBucket = 'archive-' . $this->bucket; + $this->standardBucket = 'standard-' . $this->bucket; + $options = array( OssClient::OSS_STORAGE => OssClient::OSS_STORAGE_IA ); @@ -97,6 +117,12 @@ public function setUp() ); $this->ossClient->createBucket($this->archiveBucket, OssClient::OSS_ACL_TYPE_PRIVATE, $options); + + $options = array( + OssClient::OSS_STORAGE => OssClient::OSS_STORAGE_STANDARD + ); + + $this->ossClient->createBucket($this->standardBucket, OssClient::OSS_ACL_TYPE_PRIVATE, $options); } public function tearDown() @@ -109,5 +135,6 @@ public function tearDown() $this->ossClient->deleteObject($this->archiveBucket, $object); $this->ossClient->deleteBucket($this->iaBucket); $this->ossClient->deleteBucket($this->archiveBucket); + $this->ossClient->deleteBucket($this->standardBucket); } } diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketVersioningTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketVersioningTest.php new file mode 100644 index 000000000..d9aa5a4ad --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketVersioningTest.php @@ -0,0 +1,40 @@ +ossClient->getBucketVersioning($this->bucket); + $this->assertEquals(null, $status); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->ossClient->putBucketVersioning($this->bucket, "Enabled"); + Common::waitMetaSync(); + $status = $this->ossClient->getBucketVersioning($this->bucket); + $this->assertEquals("Enabled", $status); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->ossClient->putBucketVersioning($this->bucket, "Suspended"); + Common::waitMetaSync(); + $status = $this->ossClient->getBucketVersioning($this->bucket); + $this->assertEquals("Suspended", $status); + } catch (OssException $e) { + $this->assertTrue(false); + } + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketWormTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketWormTest.php new file mode 100644 index 000000000..85df4174f --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientBucketWormTest.php @@ -0,0 +1,36 @@ +ossClient->initiateBucketWorm($this->bucket, 30); + $config = $this->ossClient->getBucketWorm($this->bucket); + $this->assertEquals($wormId, $config->getWormId()); + $this->assertEquals("InProgress", $config->getState()); + $this->assertEquals(30, $config->getDay()); + $this->ossClient->abortBucketWorm($this->bucket); + + $wormId = $this->ossClient->initiateBucketWorm($this->bucket, 60); + $this->ossClient->completeBucketWorm($this->bucket, $wormId); + $config = $this->ossClient->getBucketWorm($this->bucket); + + $this->ossClient->ExtendBucketWorm($this->bucket, $wormId, 120); + $config = $this->ossClient->getBucketWorm($this->bucket); + $this->assertEquals($wormId, $config->getWormId()); + $this->assertEquals("Locked", $config->getState()); + $this->assertEquals(120, $config->getDay()); + + } catch (OssException $e) { + $this->assertTrue(false); + } + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientImageTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientImageTest.php index df8bd6c25..17b9b9836 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientImageTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientImageTest.php @@ -6,7 +6,7 @@ use OSS\OssClient; -class OssClinetImageTest extends \PHPUnit_Framework_TestCase +class OssClinetImageTest extends TestOssClientBase { private $bucketName; private $client; @@ -16,21 +16,22 @@ class OssClinetImageTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->client = Common::getOssClient(); - $this->bucketName = 'php-sdk-test-bucket-image-' . strval(rand(0, 10000)); - $this->client->createBucket($this->bucketName); - Common::waitMetaSync(); + parent::setUp(); + + $this->client = $this->ossClient; + $this->bucketName = $this->bucket; $this->local_file = "example.jpg"; $this->object = "oss-example.jpg"; $this->download_file = "image.jpg"; + Common::waitMetaSync(); $this->client->uploadFile($this->bucketName, $this->object, $this->local_file); } public function tearDown() { - $this->client->deleteObject($this->bucketName, $this->object); - $this->client->deleteBucket($this->bucketName); + parent::tearDown(); + unlink($this->download_file); } public function testImageResize() @@ -89,6 +90,47 @@ public function testImageTofile() $this->check($options, 100, 100, 3267, 'jpg'); } + public function testProcesObject() + { + $object = 'process-object.jpg'; + $process = 'image/resize,m_fixed,w_100,h_100'. + '|sys/saveas'. + ',o_'.$this->base64url_encode($object). + ',b_'.$this->base64url_encode($this->bucketName); + $result = $this->client->processObject($this->bucketName, $this->object, $process); + $this->assertTrue(stripos($result, '"object": "process-object.jpg",') > 0); + $this->assertTrue(stripos($result, '"status": "OK"') > 0); + + + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + ); + $this->client->getObject($this->bucketName, $object, $options); + $array = getimagesize($this->download_file); + $this->assertEquals(100, $array[0]); + $this->assertEquals(100, $array[1]); + $this->assertEquals(2, $array[2]); + + //without bucket + $object = 'process-object-1.jpg'; + $process = 'image/watermark,text_SGVsbG8g5Zu-54mH5pyN5YqhIQ'. + '|sys/saveas'. + ',o_'.$this->base64url_encode($object); + $result = $this->client->processObject($this->bucketName, $this->object, $process); + $this->assertTrue(stripos($result, '"object": "process-object-1.jpg",') > 0); + $this->assertTrue(stripos($result, '"status": "OK"') > 0); + + + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + ); + $this->client->getObject($this->bucketName, $object, $options); + $array = getimagesize($this->download_file); + $this->assertEquals(400, $array[0]); + $this->assertEquals(267, $array[1]); + $this->assertEquals(2, $array[2]); + } + private function check($options, $width, $height, $size, $type) { $this->client->getObject($this->bucketName, $this->object, $options); @@ -97,4 +139,9 @@ private function check($options, $width, $height, $size, $type) $this->assertEquals($height, $array[1]); $this->assertEquals($type === 'jpg' ? 2 : 3, $array[2]);//2 <=> jpg } + + private function base64url_encode($data) + { + return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); + } } diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientListObjectsTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientListObjectsTest.php new file mode 100644 index 000000000..de4735b2d --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientListObjectsTest.php @@ -0,0 +1,184 @@ +ossClient->listObjects($this->bucket); + $objectList = $listObjectInfo->getObjectList(); + $prefixList = $listObjectInfo->getPrefixList(); + $this->assertNotNull($objectList); + $this->assertNotNull($prefixList); + $this->assertTrue(is_array($objectList)); + $this->assertTrue(is_array($prefixList)); + $this->assertEquals((2), count($objectList)); + $this->assertEquals(4, count($prefixList)); + + $this->assertEquals('file++00', $objectList[0]->getKey()); + $this->assertEquals('file++01', $objectList[1]->getKey()); + + $this->assertEquals('folder/', $prefixList[0]->getPrefix()); + $this->assertEquals('sub++/', $prefixList[1]->getPrefix()); + $this->assertEquals('test/', $prefixList[2]->getPrefix()); + $this->assertEquals('work/', $prefixList[3]->getPrefix()); + + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + public function testListObjectsWithPrefix() + { + /** + * List the files in your bucket. + */ + $prefix = 'folder/'; + $delimiter = ''; + $next_marker = ''; + $maxkeys = 1000; + $options = array( + 'delimiter' => $delimiter, + 'prefix' => $prefix, + 'max-keys' => $maxkeys, + 'marker' => $next_marker, + ); + + try { + $listObjectInfo = $this->ossClient->listObjects($this->bucket, $options); + $objectList = $listObjectInfo->getObjectList(); + $prefixList = $listObjectInfo->getPrefixList(); + $this->assertNotNull($objectList); + $this->assertNotNull($prefixList); + $this->assertTrue(is_array($objectList)); + $this->assertTrue(is_array($prefixList)); + $this->assertEquals(12, count($objectList)); + $this->assertEquals(0, count($prefixList)); + + $this->assertEquals('folder/00', $objectList[0]->getKey()); + $this->assertEquals('folder/01', $objectList[1]->getKey()); + $this->assertEquals('folder/11', $objectList[11]->getKey()); + + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + public function testListObjectsWithMaxKeysAndMarker() + { + $count = 0; + $nextMarker = ''; + + while (true) { + try { + $options = array( + 'delimiter' => '', + 'marker' => $nextMarker, + 'max-keys' => 2, + ); + $listObjectInfo = $this->ossClient->listObjects($this->bucket, $options); + } catch (OssException $e) { + $this->assertTrue(false); + } + $nextMarker = $listObjectInfo->getNextMarker(); + $listObject = $listObjectInfo->getObjectList(); + $count += count($listObject); + $this->assertEquals(2, count($listObject)); + if ($listObjectInfo->getIsTruncated() !== "true") { + break; + } + } + $this->assertEquals(12 + 8 + 5 + 3 + 2, $count); + } + + public function testListObjectsWithMarker() + { + $count = 0; + $nextMarker = 'h'; + + while (true) { + try { + $options = array( + 'delimiter' => '', + 'marker' => $nextMarker, + 'max-keys' => 1, + ); + $listObjectInfo = $this->ossClient->listObjects($this->bucket, $options); + } catch (OssException $e) { + $this->assertTrue(false); + } + $nextMarker = $listObjectInfo->getNextMarker(); + $listObject = $listObjectInfo->getObjectList(); + $count += count($listObject); + $this->assertEquals(1, count($listObject)); + if ($listObjectInfo->getIsTruncated() !== "true") { + break; + } + } + $this->assertEquals(8 + 5 + 3, $count); + + + $nextMarker = 'h'; + + try { + $options = array( + 'delimiter' => '', + 'marker' => $nextMarker, + 'max-keys' => 5, + ); + $listObjectInfo = $this->ossClient->listObjects($this->bucket, $options); + } catch (OssException $e) { + $this->assertTrue(false); + } + $nextMarker = $listObjectInfo->getNextMarker(); + $listObject = $listObjectInfo->getObjectList(); + $this->assertEquals('test/01', $nextMarker); + $this->assertEquals(5, count($listObject)); + $this->assertEquals("true", $listObjectInfo->getIsTruncated()); + } + + public function setUp() + { + parent::setUp(); + //folder + for ($i = 0; $i < 12; $i++) { + $key = 'folder/'. sprintf("%02d",$i); + $this->ossClient->putObject($this->bucket, $key, "content"); + } + //test + for ($i = 0; $i < 8; $i++) { + $key = 'test/'. sprintf("%02d",$i); + $this->ossClient->putObject($this->bucket, $key, "content"); + } + //work + for ($i = 0; $i < 5; $i++) { + $key = 'work/'. sprintf("%02d",$i); + $this->ossClient->putObject($this->bucket, $key, "content"); + } + //sub++ + for ($i = 0; $i < 3; $i++) { + $key = 'sub++/'. sprintf("%02d",$i); + $this->ossClient->putObject($this->bucket, $key, "content"); + } + + //file++ + for ($i = 0; $i < 2; $i++) { + $key = 'file++'. sprintf("%02d",$i); + $this->ossClient->putObject($this->bucket, $key, "content"); + } + + } + + public function tearDown() + { + parent::tearDown(); + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientMultipartUploadTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientMultipartUploadTest.php index a95f412d3..b7d0e26d0 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientMultipartUploadTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientMultipartUploadTest.php @@ -108,6 +108,54 @@ public function testCopyPart() $this->assertEquals($this->ossClient->getObject($this->bucket, $copiedObject), file_get_contents(__FILE__)); } + public function testCopyPartWithRange() + { + $object = "mpu/multipart-test.txt"; + $copiedObject = "mpu/multipart-test.txt.range.copied"; + $this->ossClient->putObject($this->bucket, $copiedObject, file_get_contents(__FILE__)); + /** + * step 1. 初始化一个分块上传事件, 也就是初始化上传Multipart, 获取upload id + */ + try { + $upload_id = $this->ossClient->initiateMultipartUpload($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + /* + * step 2. uploadPartCopy + */ + $copyId = 1; + $options = array( + 'start' => 0, + 'end' => 3, + ); + $eTag = $this->ossClient->uploadPartCopy($this->bucket, $copiedObject, $this->bucket, $object, $copyId, $upload_id, $options); + $upload_parts[] = array( + 'PartNumber' => $copyId, + 'ETag' => $eTag, + ); + + try { + $listPartsInfo = $this->ossClient->listParts($this->bucket, $object, $upload_id); + $this->assertNotNull($listPartsInfo); + } catch (OssException $e) { + $this->assertTrue(false); + } + + /** + * step 3. + */ + try { + $this->ossClient->completeMultipartUpload($this->bucket, $object, $upload_id, $upload_parts); + } catch (OssException $e) { + var_dump($e->getMessage()); + $this->assertTrue(false); + } + + $this->assertEquals($this->ossClient->getObject($this->bucket, $copiedObject), file_get_contents(__FILE__)); + $this->assertEquals($this->ossClient->getObject($this->bucket, $object), 'ossClient->listParts($this->bucket, $object, $upload_id); + $listPartsInfo = $this->ossClient->listParts($this->bucket, $object, $upload_id, array('max-parts' => 100)); $this->assertNotNull($listPartsInfo); } catch (OssException $e) { $this->assertTrue(false); @@ -184,7 +232,7 @@ public function testAbortMultipartUpload() $numOfMultipartUpload2 = 0; try { - $listMultipartUploadInfo = $listMultipartUploadInfo = $this->ossClient->listMultipartUploads($this->bucket, $options); + $listMultipartUploadInfo = $listMultipartUploadInfo = $this->ossClient->listMultipartUploads($this->bucket, array('max-uploads' => 1000)); $this->assertNotNull($listMultipartUploadInfo); $numOfMultipartUpload2 = count($listMultipartUploadInfo->getUploads()); } catch (OssException $e) { @@ -300,6 +348,52 @@ public function testPutObjectByMultipartUploadWithMD5Check() } } + public function testPutObjectByMultipartUploadWithOSS_LENGTH() + { + $object = "mpu/multipart-test-length.txt"; + $file = __FILE__; + + try { + $upload_id = $this->ossClient->initiateMultipartUpload($this->bucket, $object); + $options = array(OssClient::OSS_LENGTH => 4, OssClient::OSS_UPLOAD_ID => $upload_id); + $this->ossClient->multiuploadFile($this->bucket, $object, $file, $options); + $this->assertEquals($this->ossClient->getObject($this->bucket, $object), 'assertFalse(true); + } + } + + public function testPutObjectByMultipartUploadWithOSS_CONTENT_LENGTH() + { + $object = "mpu/multipart-test-content-length.txt"; + $file = __FILE__; + + try { + $upload_id = $this->ossClient->initiateMultipartUpload($this->bucket, $object); + $options = array(OssClient::OSS_CONTENT_LENGTH => 4, OssClient::OSS_UPLOAD_ID => $upload_id); + $this->ossClient->multiuploadFile($this->bucket, $object, $file, $options); + $this->assertEquals($this->ossClient->getObject($this->bucket, $object), 'assertFalse(true); + } + } + + public function testPutObjectByMultipartUploadWithException() + { + $object = "mpu/multipart-test-exception.txt"; + $file = ""; + + try { + $this->ossClient->multiuploadFile($this->bucket, $object, $file); + } catch (OssException $e) { + $this->assertTrue(true); + if (strpos($e, "parameter invalid, file is empty") == false) + { + $this->assertTrue(true); + } + } + } + public function testListMultipartUploads() { $options = null; @@ -310,4 +404,20 @@ public function testListMultipartUploads() $this->assertFalse(true); } } + + public function testCompleteMultipartUploadWithException() + { + $object = "mpu/multipart-test-complete.txt"; + $uploadId = "uploadId"; + try { + $listMultipartUploadInfo = $this->ossClient->completeMultipartUpload($this->bucket, $object, $uploadId, null); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + if (strpos($e, "listParts must be array type") == false) + { + $this->assertTrue(false); + } + } + } } diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectRequestPaymentTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectRequestPaymentTest.php new file mode 100644 index 000000000..d9b8d060d --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectRequestPaymentTest.php @@ -0,0 +1,471 @@ +payerClient->listObjects($this->bucket); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->createObjectDir($this->bucket, 'folder/'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->putObject($this->bucket, 'object', 'content'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->putSymlink($this->bucket, 'symlink', 'default-object'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->getSymlink($this->bucket, 'default-symlink'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->uploadFile($this->bucket, 'file-object', __FILE__); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->appendObject($this->bucket, 'append-object', 'content', 0); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->appendObject($this->bucket, 'append-file', __FILE__, 0); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->copyObject($this->bucket, 'default-object', $this->bucket, 'copy-object'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->getObjectMeta($this->bucket, 'default-object'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + } + + try { + $this->payerClient->getSimplifiedObjectMeta($this->bucket, 'default-object'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + } + + try { + $this->payerClient->deleteObject($this->bucket, 'default-object'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->getObject($this->bucket, 'default-object'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->doesObjectExist($this->bucket, 'default-object'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + } + + try { + $this->payerClient->restoreObject($this->bucket, 'default-ia-object'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $config = new TaggingConfig(); + $config->addTag(new Tag("key1", "value1")); + $this->payerClient->putObjectTagging($this->bucket, 'default-object', $config); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->getObjectTagging($this->bucket, 'default-object'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->deleteObjectTagging($this->bucket, 'default-object'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->initiateMultipartUpload($this->bucket, 'mup-object'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + $uploadId= $this->ossClient->initiateMultipartUpload($this->bucket, 'mup-object'); + + try { + $this->payerClient->listParts($this->bucket, 'mup-object', $uploadId); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->abortMultipartUpload($this->bucket, 'mup-object', $uploadId); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->listMultipartUploads($this->bucket); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + + try { + $this->payerClient->multiuploadFile($this->bucket, 'mup-file', __FILE__); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('AccessDenied', $e->getErrorCode()); + } + } + + public function testObjectOperationsWithRequester() + { + $options = array( + OssClient::OSS_HEADERS => array( + OssClient::OSS_REQUEST_PAYER => 'requester', + )); + + try { + $this->payerClient->listObjects($this->bucket, $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->createObjectDir($this->bucket, 'folder/', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->putObject($this->bucket, 'object', 'content', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->putSymlink($this->bucket, 'symlink', 'default-object', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->getSymlink($this->bucket, 'default-symlink', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->uploadFile($this->bucket, 'file-object', __FILE__, $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->appendObject($this->bucket, 'append-object', 'content', 0, $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->appendObject($this->bucket, 'append-file', __FILE__, 0, $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->copyObject($this->bucket, 'default-object', $this->bucket, 'copy-object', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->getObjectMeta($this->bucket, 'default-object', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->getSimplifiedObjectMeta($this->bucket, 'default-object', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->getObject($this->bucket, 'default-object', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->putObject($this->bucket, 'test-object', 'content', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->deleteObject($this->bucket, 'test-object', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->doesObjectExist($this->bucket, 'default-object', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + $ia_options = array( + OssClient::OSS_HEADERS => array( + 'x-oss-storage-class' => 'Archive', + )); + $this->ossClient->putObject($this->bucket, 'default-Archive-object', 'content', $ia_options); + try { + $this->payerClient->restoreObject($this->bucket, 'default-Archive-object', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $config = new TaggingConfig(); + $config->addTag(new Tag("key1", "value1")); + $this->payerClient->putObjectTagging($this->bucket, 'default-object', $config, $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->getObjectTagging($this->bucket, 'default-object', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->payerClient->deleteObjectTagging($this->bucket, 'default-object', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + public function testMultipartOperationsWithRequester() + { + $options = array( + OssClient::OSS_HEADERS => array( + OssClient::OSS_REQUEST_PAYER => 'requester', + )); + + $object = "mpu/multipart-test.txt"; + /** + * step 1. 初始化一个分块上传事件, 也就是初始化上传Multipart, 获取upload id + */ + try { + $upload_id = $this->payerClient->initiateMultipartUpload($this->bucket, $object, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /* + * step 2. 上传分片 + */ + $part_size = 1 * 1024 * 1024; + $upload_file = __FILE__; + $upload_filesize = filesize($upload_file); + $pieces = $this->payerClient->generateMultiuploadParts($upload_filesize, $part_size); + $response_upload_part = array(); + $upload_position = 0; + $is_check_md5 = false; + foreach ($pieces as $i => $piece) { + $from_pos = $upload_position + (integer)$piece[OssClient::OSS_SEEK_TO]; + $to_pos = (integer)$piece[OssClient::OSS_LENGTH] + $from_pos - 1; + $up_options = array( + OssClient::OSS_FILE_UPLOAD => $upload_file, + OssClient::OSS_PART_NUM => ($i + 1), + OssClient::OSS_SEEK_TO => $from_pos, + OssClient::OSS_LENGTH => $to_pos - $from_pos + 1, + OssClient::OSS_CHECK_MD5 => $is_check_md5, + OssClient::OSS_HEADERS => array( + OssClient::OSS_REQUEST_PAYER => 'requester', + ), + ); + + //2. 将每一分片上传到OSS + try { + $response_upload_part[] = $this->ossClient->uploadPart($this->bucket, $object, $upload_id, $up_options); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + $upload_parts = array(); + foreach ($response_upload_part as $i => $eTag) { + $upload_parts[] = array( + 'PartNumber' => ($i + 1), + 'ETag' => $eTag, + ); + } + + try { + $listPartsInfo = $this->payerClient->listParts($this->bucket, $object, $upload_id, $options); + $this->assertNotNull($listPartsInfo); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $uploads = $this->payerClient->listMultipartUploads($this->bucket, $options); + $this->assertNotNull($uploads); + } catch (OssException $e) { + $this->assertTrue(false); + } + + /** + * step 3. + */ + try { + $this->payerClient->completeMultipartUpload($this->bucket, $object, $upload_id, $upload_parts, $options); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + public function testMiscOperationsWithRequester() + { + //use multipart + $options = array( + OssClient::OSS_PART_SIZE => 1, + OssClient::OSS_HEADERS => array( + OssClient::OSS_REQUEST_PAYER => 'requester', + )); + + $bigFileName = __DIR__ . DIRECTORY_SEPARATOR . "/bigfile.tmp"; + OssUtil::generateFile($bigFileName, 256 * 1024); + $object = 'mpu/multipart-bigfile-test.tmp'; + try { + $this->ossClient->multiuploadFile($this->bucket, $object, $bigFileName, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + + //use uploadfile + $options = array( + OssClient::OSS_PART_SIZE => 1024*1024, + OssClient::OSS_HEADERS => array( + OssClient::OSS_REQUEST_PAYER => 'requester', + )); + + try { + $this->ossClient->multiuploadFile($this->bucket, $object, $bigFileName, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + + unlink($bigFileName); + } + + public function setUp() + { + parent::setUp(); + $this->payerClient = new OssClient( + getenv('OSS_PAYER_ACCESS_KEY_ID'), + getenv('OSS_PAYER_ACCESS_KEY_SECRET'), + getenv('OSS_ENDPOINT'), false); + + $policy = '{"Version":"1","Statement":[{"Action":["oss:*"],"Effect": "Allow",'. + '"Principal":["' . getenv('OSS_PAYER_UID') . '"],'. + '"Resource": ["acs:oss:*:*:' . $this->bucket . '","acs:oss:*:*:' . $this->bucket . '/*"]}]}'; + + $this->ossClient->putBucketPolicy($this->bucket, $policy); + $this->ossClient->putBucketRequestPayment($this->bucket, 'Requester'); + $this->ossClient->putObject($this->bucket, "default-object", ""); + $this->ossClient->putSymlink($this->bucket, "default-symlink", "default-object"); + } + + public function tearDown() + { + parent::tearDown(); + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectTaggingTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectTaggingTest.php new file mode 100644 index 000000000..401d1b7c4 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectTaggingTest.php @@ -0,0 +1,160 @@ +ossClient->putObject($this->bucket, $object, $content); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $config = $this->ossClient->getObjectTagging($this->bucket, $object); + $this->assertEquals(0, count($config->getTags())); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $config = new TaggingConfig(); + $config->addTag(new Tag("key1", "value1")); + $config->addTag(new Tag("key2", "value2")); + $config->addTag(new Tag("key3", "value3")); + $this->ossClient->putObjectTagging($this->bucket, $object, $config); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $config2 = $this->ossClient->getObjectTagging($this->bucket, $object); + $this->assertEquals(3, count($config2->getTags())); + $this->assertEquals("key1", $config2->getTags()[0]->getKey()); + $this->assertEquals("value1", $config2->getTags()[0]->getValue()); + $this->assertEquals("key2", $config2->getTags()[1]->getKey()); + $this->assertEquals("value2", $config2->getTags()[1]->getValue()); + $this->assertEquals("key3", $config2->getTags()[2]->getKey()); + $this->assertEquals("value3", $config2->getTags()[2]->getValue()); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->ossClient->deleteObjectTagging($this->bucket, $object); + $config2 = $this->ossClient->getObjectTagging($this->bucket, $object); + $this->assertEquals(0, count($config2->getTags())); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + public function testPutObjectTaggingFromHeader() + { + $object = "object-tagging-header.txt"; + $content = "hello world"; + + try { + $options = array( + OssClient::OSS_HEADERS => array( + 'x-oss-tagging' => 'key1=value1&key2=value2&key3=value3', + )); + + $this->ossClient->putObject($this->bucket, $object, $content, $options); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + + $config2 = $this->ossClient->getObjectTagging($this->bucket, $object); + $this->assertEquals(3, count($config2->getTags())); + $this->assertEquals("key1", $config2->getTags()[0]->getKey()); + $this->assertEquals("value1", $config2->getTags()[0]->getValue()); + $this->assertEquals("key2", $config2->getTags()[1]->getKey()); + $this->assertEquals("value2", $config2->getTags()[1]->getValue()); + $this->assertEquals("key3", $config2->getTags()[2]->getKey()); + $this->assertEquals("value3", $config2->getTags()[2]->getValue()); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + public function testAppendObjectTaggingFromHeader() + { + $object = "append-object-tagging-header.txt"; + $content_array = array('Hello OSS', 'Hi OSS', 'OSS OK'); + + try { + $options = array( + OssClient::OSS_HEADERS => array( + 'x-oss-tagging' => 'key1=value1&key2=value2&key3=value3', + )); + + $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[0], 0, $options); + $this->assertEquals($position, strlen($content_array[0])); + $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[1], $position); + $this->assertEquals($position, strlen($content_array[0]) + strlen($content_array[1])); + $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[2], $position, array(OssClient::OSS_LENGTH => strlen($content_array[2]))); + $this->assertEquals($position, strlen($content_array[0]) + strlen($content_array[1]) + strlen($content_array[2])); + + $config2 = $this->ossClient->getObjectTagging($this->bucket, $object); + $this->assertEquals(3, count($config2->getTags())); + $this->assertEquals("key1", $config2->getTags()[0]->getKey()); + $this->assertEquals("value1", $config2->getTags()[0]->getValue()); + $this->assertEquals("key2", $config2->getTags()[1]->getKey()); + $this->assertEquals("value2", $config2->getTags()[1]->getValue()); + $this->assertEquals("key3", $config2->getTags()[2]->getKey()); + $this->assertEquals("value3", $config2->getTags()[2]->getValue()); + + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testMultipartUploadTaggingFromHeader() + { + $file = __DIR__ . DIRECTORY_SEPARATOR . "/bigfile.tmp"; + OssUtil::generateFile($file, 110 * 1024); + + $object = "mpu-object-tagging-header.txt"; + $options = array( + OssClient::OSS_CHECK_MD5 => true, + OssClient::OSS_PART_SIZE => 1, + OssClient::OSS_HEADERS => array( + 'x-oss-tagging' => 'key1=value1&key2=value2&key3=value3', + ), + ); + try { + $this->ossClient->multiuploadFile($this->bucket, $object, $file, $options); + + $config2 = $this->ossClient->getObjectTagging($this->bucket, $object); + $this->assertEquals(3, count($config2->getTags())); + $this->assertEquals("key1", $config2->getTags()[0]->getKey()); + $this->assertEquals("value1", $config2->getTags()[0]->getValue()); + $this->assertEquals("key2", $config2->getTags()[1]->getKey()); + $this->assertEquals("value2", $config2->getTags()[1]->getValue()); + $this->assertEquals("key3", $config2->getTags()[2]->getKey()); + $this->assertEquals("value3", $config2->getTags()[2]->getValue()); + } catch (OssException $e) { + $this->assertFalse(true); + } + + unlink($file); + } + +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectTest.php index 2f1201bb5..2d3880598 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectTest.php @@ -88,7 +88,6 @@ public function testObject() 'Expires' => 'Fri, 28 Feb 2020 05:38:42 GMT', 'Cache-Control' => 'no-cache', 'Content-Disposition' => 'attachment;filename=oss_download.log', - 'Content-Encoding' => 'utf-8', 'Content-Language' => 'zh-CN', 'x-oss-server-side-encryption' => 'AES256', 'x-oss-meta-self-define-title' => 'user define meta info', @@ -328,12 +327,18 @@ public function testObject() $this->assertTrue($this->ossClient->doesObjectExist($this->bucket, $object2)); $result = $this->ossClient->deleteObjects($this->bucket, $list); - $this->assertEquals($list[1], $result[0]); - $this->assertEquals($list[0], $result[1]); + $this->assertEquals($list[0], $result[0]); + $this->assertEquals($list[1], $result[1]); $result = $this->ossClient->deleteObjects($this->bucket, $list, array('quiet' => 'true')); $this->assertEquals(array(), $result); $this->assertFalse($this->ossClient->doesObjectExist($this->bucket, $object2)); + + $this->ossClient->putObject($this->bucket, $object, $content); + $this->assertTrue($this->ossClient->doesObjectExist($this->bucket, $object)); + $result = $this->ossClient->deleteObjects($this->bucket, $list, array('quiet' => true)); + $this->assertEquals(array(), $result); + $this->assertFalse($this->ossClient->doesObjectExist($this->bucket, $object)); } catch (OssException $e) { $this->assertFalse(true); } @@ -352,8 +357,8 @@ public function testAppendObject() $this->assertEquals($position, strlen($content_array[0])); $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[1], $position); $this->assertEquals($position, strlen($content_array[0]) + strlen($content_array[1])); - $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[2], $position); - $this->assertEquals($position, strlen($content_array[0]) + strlen($content_array[1]) + strlen($content_array[1])); + $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[2], $position, array(OssClient::OSS_LENGTH => strlen($content_array[2]))); + $this->assertEquals($position, strlen($content_array[0]) + strlen($content_array[1]) + strlen($content_array[2])); } catch (OssException $e) { $this->assertFalse(true); } @@ -378,6 +383,16 @@ public function testAppendObject() $this->assertFalse(true); } + /** + * Append the upload of invalid local files + */ + try { + $position = $this->ossClient->appendFile($this->bucket, $object, "invalid-file-path", 0); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + } + /** * Append the upload of local files */ @@ -590,6 +605,65 @@ public function testWithInvalidBucketName() } } + public function testGetSimplifiedObjectMeta() + { + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + + try { + $objectMeta = $this->ossClient->getSimplifiedObjectMeta($this->bucket, $object); + $this->assertEquals(false, array_key_exists(strtolower('Content-Disposition'), $objectMeta)); + $this->assertEquals(strlen(file_get_contents(__FILE__)), $objectMeta[strtolower('Content-Length')]); + $this->assertEquals(true, array_key_exists(strtolower('ETag'), $objectMeta)); + $this->assertEquals(true, array_key_exists(strtolower('Last-Modified'), $objectMeta)); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testUploadStream() + { + $object = "oss-php-sdk-test/put-from-stream.txt"; + $options = array(OssClient::OSS_CHECK_MD5 => true); + $handle = fopen(__FILE__, 'rb'); + /** + * Upload data to start MD5 + */ + try { + $this->ossClient->uploadStream($this->bucket, $object, $handle, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Check if the replication is the same + */ + try { + $content = $this->ossClient->getObject($this->bucket, $object); + $this->assertEquals($content, file_get_contents(__FILE__)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + $object = "oss-php-sdk-test/put-from-stream-without-md5.txt"; + $handle = fopen(__FILE__, 'rb'); + try { + $this->ossClient->uploadStream($this->bucket, $object, $handle); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Check if the replication is the same + */ + try { + $content = $this->ossClient->getObject($this->bucket, $object); + $this->assertEquals($content, file_get_contents(__FILE__)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + } + public function setUp() { parent::setUp(); diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectVersioningTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectVersioningTest.php new file mode 100644 index 000000000..f13ca01dd --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientObjectVersioningTest.php @@ -0,0 +1,610 @@ +ossClient->putObject($this->bucket, $object, $content1, array(OssClient::OSS_HEADERS => array('x-oss-object-acl' => 'public-read', 'x-oss-tagging' => 'key1=value1'))); + $ret2 = $this->ossClient->putObject($this->bucket, $object, $content2, array(OssClient::OSS_HEADERS => array('x-oss-object-acl' => 'private', 'x-oss-tagging' => 'key2=value2'))); + + $this->assertTrue(isset($ret1[OssClient::OSS_HEADER_VERSION_ID])); + $this->assertTrue(isset($ret2[OssClient::OSS_HEADER_VERSION_ID])); + + $versionId1 = $ret1[OssClient::OSS_HEADER_VERSION_ID]; + $versionId2 = $ret2[OssClient::OSS_HEADER_VERSION_ID]; + + //get object + $res = $this->ossClient->getObject($this->bucket, $object); + $res1 = $this->ossClient->getObject($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1)); + $res2 = $this->ossClient->getObject($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId2)); + $this->assertEquals($content1, $res1); + $this->assertEquals($content2, $res2); + $this->assertEquals($content2, $res); + + //meta + $headers = $this->ossClient->getObjectMeta($this->bucket, $object); + $headers1 = $this->ossClient->getObjectMeta($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1)); + $headers2 = $this->ossClient->getObjectMeta($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId2)); + + $this->assertTrue(isset($headers[OssClient::OSS_HEADER_VERSION_ID])); + $this->assertTrue(isset($headers1[OssClient::OSS_HEADER_VERSION_ID])); + $this->assertTrue(isset($headers2[OssClient::OSS_HEADER_VERSION_ID])); + $this->assertEquals($versionId1, $headers1[OssClient::OSS_HEADER_VERSION_ID]); + $this->assertEquals($versionId2, $headers2[OssClient::OSS_HEADER_VERSION_ID]); + $this->assertEquals($versionId2, $headers[OssClient::OSS_HEADER_VERSION_ID]); + + + $sheaders = $this->ossClient->getSimplifiedObjectMeta($this->bucket, $object); + $sheaders1 = $this->ossClient->getSimplifiedObjectMeta($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1)); + $sheaders2 = $this->ossClient->getSimplifiedObjectMeta($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId2)); + + $this->assertTrue(isset($sheaders[OssClient::OSS_HEADER_VERSION_ID])); + $this->assertTrue(isset($sheaders1[OssClient::OSS_HEADER_VERSION_ID])); + $this->assertTrue(isset($sheaders2[OssClient::OSS_HEADER_VERSION_ID])); + $this->assertEquals($versionId1, $sheaders1[OssClient::OSS_HEADER_VERSION_ID]); + $this->assertEquals($versionId2, $sheaders2[OssClient::OSS_HEADER_VERSION_ID]); + $this->assertEquals($versionId2, $sheaders[OssClient::OSS_HEADER_VERSION_ID]); + + //acl + $acl = $this->ossClient->getObjectAcl($this->bucket, $object); + $acl1 = $this->ossClient->getObjectAcl($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1)); + $acl2 = $this->ossClient->getObjectAcl($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId2)); + + $this->assertEquals('public-read', $acl1); + $this->assertEquals('private', $acl2); + $this->assertEquals('private', $acl); + + $this->ossClient->putObjectAcl($this->bucket, $object, 'public-read-write', array(OssClient::OSS_VERSION_ID => $versionId1)); + $acl = $this->ossClient->getObjectAcl($this->bucket, $object); + $acl1 = $this->ossClient->getObjectAcl($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1)); + $this->assertEquals('public-read-write', $acl1); + $this->assertEquals('private', $acl); + + //tagging + $tag = $this->ossClient->getObjectTagging($this->bucket, $object); + $tag1 = $this->ossClient->getObjectTagging($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1)); + $tag2 = $this->ossClient->getObjectTagging($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId2)); + $this->assertEquals(1, count($tag1->getTags())); + $this->assertEquals("key1", $tag1->getTags()[0]->getKey()); + $this->assertEquals("value1", $tag1->getTags()[0]->getValue()); + $this->assertEquals(1, count($tag2->getTags())); + $this->assertEquals("key2", $tag2->getTags()[0]->getKey()); + $this->assertEquals("value2", $tag2->getTags()[0]->getValue()); + $this->assertEquals(1, count($tag->getTags())); + $this->assertEquals("key2", $tag->getTags()[0]->getKey()); + $this->assertEquals("value2", $tag->getTags()[0]->getValue()); + + $config = new TaggingConfig(); + $config->addTag(new Tag("key11", "value11")); + $this->ossClient->putObjectTagging($this->bucket, $object, $config, array(OssClient::OSS_VERSION_ID => $versionId1)); + $tag = $this->ossClient->getObjectTagging($this->bucket, $object); + $tag1 = $this->ossClient->getObjectTagging($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1)); + $this->assertEquals(1, count($tag1->getTags())); + $this->assertEquals("key11", $tag1->getTags()[0]->getKey()); + $this->assertEquals("value11", $tag1->getTags()[0]->getValue()); + $this->assertEquals(1, count($tag->getTags())); + $this->assertEquals("key2", $tag->getTags()[0]->getKey()); + $this->assertEquals("value2", $tag->getTags()[0]->getValue()); + + $this->ossClient->deleteObjectTagging($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1)); + $tag = $this->ossClient->getObjectTagging($this->bucket, $object); + $tag1 = $this->ossClient->getObjectTagging($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1)); + $this->assertEquals(0, count($tag1->getTags())); + $this->assertEquals(1, count($tag->getTags())); + $this->assertEquals("key2", $tag->getTags()[0]->getKey()); + $this->assertEquals("value2", $tag->getTags()[0]->getValue()); + + //delete + $dret = $this->ossClient->deleteObject($this->bucket, $object); + $this->assertTrue(isset($dret['x-oss-delete-marker'])); + $this->assertTrue(isset($dret['x-oss-version-id'])); + $this->assertEquals("true", $dret['x-oss-delete-marker']); + $this->assertFalse($this->ossClient->doesObjectExist($this->bucket, $object)); + $this->assertTrue($this->ossClient->doesObjectExist($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1))); + $this->assertTrue($this->ossClient->doesObjectExist($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId2))); + + $dret1 = $this->ossClient->deleteObject($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1)); + $this->assertFalse(isset($dret1['x-oss-delete-marker'])); + $this->assertTrue(isset($dret1['x-oss-version-id'])); + $this->assertEquals($versionId1, $dret1['x-oss-version-id']); + $this->assertFalse($this->ossClient->doesObjectExist($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1))); + + + $dret_ = $this->ossClient->deleteObject($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $dret['x-oss-version-id'])); + $this->assertTrue(isset($dret_['x-oss-delete-marker'])); + $this->assertTrue(isset($dret_['x-oss-version-id'])); + $this->assertEquals($dret['x-oss-version-id'], $dret_['x-oss-version-id']); + $this->assertTrue($this->ossClient->doesObjectExist($this->bucket, $object)); + + } + + public function testObjectSymlink() + { + $object1 = 'object-target-1'; + $object2 = 'object-target-2'; + $symlink = 'object-symlink'; + $content1 = 'hello'; + $content2 = 'hello world'; + + + $ret1 = $this->ossClient->putObject($this->bucket, $object1, $content1); + $sym1 = $this->ossClient->putSymlink($this->bucket, $symlink, $object1); + + $ret2 = $this->ossClient->putObject($this->bucket, $object2, $content2); + $sym2 = $this->ossClient->putSymlink($this->bucket, $symlink, $object2); + + $this->assertTrue(isset($ret1[OssClient::OSS_HEADER_VERSION_ID])); + $this->assertTrue(isset($ret2[OssClient::OSS_HEADER_VERSION_ID])); + + $this->assertTrue(isset($sym1[OssClient::OSS_HEADER_VERSION_ID])); + $this->assertTrue(isset($sym2[OssClient::OSS_HEADER_VERSION_ID])); + + $versionId1 = $ret1[OssClient::OSS_HEADER_VERSION_ID]; + $versionId2 = $ret2[OssClient::OSS_HEADER_VERSION_ID]; + + $sym_versionId1 = $sym1[OssClient::OSS_HEADER_VERSION_ID]; + $sym_versionId2 = $sym2[OssClient::OSS_HEADER_VERSION_ID]; + + + $sym_ret = $this->ossClient->getSymlink($this->bucket, $symlink); + $sym_ret1 = $this->ossClient->getSymlink($this->bucket, $symlink, array(OssClient::OSS_VERSION_ID => $sym_versionId1)); + $sym_ret2 = $this->ossClient->getSymlink($this->bucket, $symlink, array(OssClient::OSS_VERSION_ID => $sym_versionId2)); + + $this->assertTrue(isset($sym_ret['x-oss-version-id'])); + $this->assertTrue(isset($sym_ret1['x-oss-version-id'])); + $this->assertTrue(isset($sym_ret2['x-oss-version-id'])); + + $this->assertEquals($sym_versionId1, $sym_ret1['x-oss-version-id']); + $this->assertEquals($sym_versionId2, $sym_ret2['x-oss-version-id']); + $this->assertEquals($sym_versionId2, $sym_ret['x-oss-version-id']); + + + $res = $this->ossClient->getObject($this->bucket, $symlink); + $res1 = $this->ossClient->getObject($this->bucket, $symlink, array(OssClient::OSS_VERSION_ID => $sym_versionId1)); + $res2 = $this->ossClient->getObject($this->bucket, $symlink, array(OssClient::OSS_VERSION_ID => $sym_versionId2)); + $this->assertEquals($content1, $res1); + $this->assertEquals($content2, $res2); + $this->assertEquals($content2, $res); + } + + public function testObjectCopy() + { + $object = 'copy-= +object'; + $content1 = 'hello'; + $content2 = 'hello world'; + $to_bucket = $this->bucket; + $to_object = $object . '.copy'; + $to_object1 = $object . '.copy1'; + $to_object2 = $object . '.copy2'; + + $ret1 = $this->ossClient->putObject($this->bucket, $object, $content1); + $ret2 = $this->ossClient->putObject($this->bucket, $object, $content2); + + $versionId1 = $ret1[OssClient::OSS_HEADER_VERSION_ID]; + $versionId2 = $ret2[OssClient::OSS_HEADER_VERSION_ID]; + + $cret = $this->ossClient->copyObject($this->bucket, $object, $to_bucket, $to_object); + $cret1 = $this->ossClient->copyObject($this->bucket, $object, $to_bucket, $to_object1, array(OssClient::OSS_VERSION_ID => $versionId1)); + $cret2 = $this->ossClient->copyObject($this->bucket, $object, $to_bucket, $to_object2, array(OssClient::OSS_VERSION_ID => $versionId2)); + $this->assertFalse(empty($cret1)); + $this->assertEquals(strlen("2016-11-21T03:46:58.000Z"), strlen($cret1[0])); + $this->assertEquals(trim($ret1['etag'], '"'), trim($cret1[1], '"')); + $this->assertTrue(isset($cret1['x-oss-version-id'])); + $this->assertEquals($versionId1, $cret1['x-oss-copy-source-version-id']); + + $this->assertFalse(empty($cret2)); + $this->assertEquals(strlen("2016-11-21T03:46:58.000Z"), strlen($cret2[0])); + $this->assertEquals(trim($ret2['etag'], '"'), trim($cret2[1], '"')); + $this->assertTrue(isset($cret2['x-oss-version-id'])); + $this->assertEquals($versionId2, $cret2['x-oss-copy-source-version-id']); + + $this->assertFalse(empty($cret)); + $this->assertEquals(strlen("2016-11-21T03:46:58.000Z"), strlen($cret[0])); + $this->assertEquals(trim($ret2['etag'], '"'), trim($cret[1], '"')); + $this->assertTrue(isset($cret2['x-oss-version-id'])); + $this->assertEquals($versionId2, $cret['x-oss-copy-source-version-id']); + + $res = $this->ossClient->getObject($this->bucket, $to_object); + $res1 = $this->ossClient->getObject($this->bucket, $to_object1); + $res2 = $this->ossClient->getObject($this->bucket, $to_object2); + $this->assertEquals($content1, $res1); + $this->assertEquals($content2, $res2); + $this->assertEquals($content2, $res); + } + + public function testObjectRestore() + { + $object = 'retore-object'; + $content1 = 'hello'; + $content2 = 'hello world'; + $ret1 = $this->ossClient->putObject($this->bucket, $object, $content1, array(OssClient::OSS_HEADERS => array('x-oss-storage-class' => 'Archive'))); + $ret2 = $this->ossClient->putObject($this->bucket, $object, $content2); + + $versionId1 = $ret1[OssClient::OSS_HEADER_VERSION_ID]; + $versionId2 = $ret2[OssClient::OSS_HEADER_VERSION_ID]; + + try{ + $this->ossClient->getObject($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1)); + $this->assertTrue(false); + }catch (OssException $e){ + $this->assertEquals('403', $e->getHTTPStatus()); + $this->assertEquals('InvalidObjectState', $e->getErrorCode()); + } + + try{ + $this->ossClient->restoreObject($this->bucket, $object); + $this->assertTrue(false); + }catch(OssException $e){ + $this->assertEquals('400', $e->getHTTPStatus()); + $this->assertEquals('OperationNotSupported', $e->getErrorCode()); + } + + $result = $this->ossClient->restoreObject($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1)); + common::waitMetaSync(); + $this->assertEquals('202', $result['info']['http_code']); + + try{ + $this->ossClient->restoreObject($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $versionId1)); + }catch(OssException $e){ + $this->assertEquals('409', $e->getHTTPStatus()); + $this->assertEquals('RestoreAlreadyInProgress', $e->getErrorCode()); + } + } + + public function testObjectMultiPart() + { + $object_src = 'multi-= +object.src'; + $content1 = 'hello'; + $content2 = 'hello world'; + $ret1 = $this->ossClient->putObject($this->bucket, $object_src, $content1); + $ret2 = $this->ossClient->putObject($this->bucket, $object_src, $content2); + + $this->assertTrue(isset($ret1[OssClient::OSS_HEADER_VERSION_ID])); + $this->assertTrue(isset($ret2[OssClient::OSS_HEADER_VERSION_ID])); + + $versionId1 = $ret1[OssClient::OSS_HEADER_VERSION_ID]; + $versionId2 = $ret2[OssClient::OSS_HEADER_VERSION_ID]; + + //object + $object = "multi-object"; + $upload_id = $this->ossClient->initiateMultipartUpload($this->bucket, $object); + $copyId = 1; + $eTag = $this->ossClient->uploadPartCopy($this->bucket, $object_src, $this->bucket, $object, $copyId, $upload_id); + $upload_parts[] = array( + 'PartNumber' => $copyId, + 'ETag' => $eTag, + ); + $ret = $this->ossClient->completeMultipartUpload($this->bucket, $object, $upload_id, $upload_parts); + + //object-1 + $object1 = "multi-object-1"; + $upload_id = $this->ossClient->initiateMultipartUpload($this->bucket, $object1); + $copyId = 1; + $eTag = $this->ossClient->uploadPartCopy($this->bucket, $object_src, $this->bucket, $object1, $copyId, $upload_id, array(OssClient::OSS_VERSION_ID => $versionId1)); + $upload_parts1[] = array( + 'PartNumber' => $copyId, + 'ETag' => $eTag, + ); + $ret1 = $this->ossClient->completeMultipartUpload($this->bucket, $object1, $upload_id, $upload_parts1); + + //object-2 + $object2 = "multi-object-2"; + $upload_id = $this->ossClient->initiateMultipartUpload($this->bucket, $object2); + $copyId = 1; + $eTag = $this->ossClient->uploadPartCopy($this->bucket, $object_src, $this->bucket, $object2, $copyId, $upload_id, array(OssClient::OSS_VERSION_ID => $versionId2)); + $upload_parts2[] = array( + 'PartNumber' => $copyId, + 'ETag' => $eTag, + ); + $ret2 = $this->ossClient->completeMultipartUpload($this->bucket, $object2, $upload_id, $upload_parts2); + + $res = $this->ossClient->getObject($this->bucket, $object); + $res1 = $this->ossClient->getObject($this->bucket, $object1); + $res2 = $this->ossClient->getObject($this->bucket, $object2); + + $this->assertEquals($content1, $res1); + $this->assertEquals($content2, $res2); + $this->assertEquals($content2, $res); + } + + public function testObjectMisc() + { + //use multipart + $options = array( + OssClient::OSS_PART_SIZE => 1, + ); + + $object = 'misc-object'; + + $smallFile1 = __DIR__ . DIRECTORY_SEPARATOR . "/smallfile1.tmp"; + $smallFile2 = __DIR__ . DIRECTORY_SEPARATOR . "/smallfile2.tmp"; + $bigFile1 = __DIR__ . DIRECTORY_SEPARATOR . "/bigfile1.tmp"; + $bigFile2 = __DIR__ . DIRECTORY_SEPARATOR . "/bigfile2.tmp"; + + OssUtil::generateFile($smallFile1, 5); + OssUtil::generateFile($smallFile2, 10); + OssUtil::generateFile($bigFile1, 128 * 1024); + OssUtil::generateFile($bigFile2, 256 * 1024); + + $sret1 = $this->ossClient->multiuploadFile($this->bucket, $object, $smallFile1, $options); + $sret2 = $this->ossClient->multiuploadFile($this->bucket, $object, $smallFile2, $options); + $bret1 = $this->ossClient->multiuploadFile($this->bucket, $object, $bigFile1, $options); + $bret2 = $this->ossClient->multiuploadFile($this->bucket, $object, $bigFile2, $options); + + + $res = $this->ossClient->getObject($this->bucket, $object); + $sres1 = $this->ossClient->getObject($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $sret1['x-oss-version-id'])); + $sres2 = $this->ossClient->getObject($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $sret2['x-oss-version-id'])); + $bres1 = $this->ossClient->getObject($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $bret1['x-oss-version-id'])); + $bres2 = $this->ossClient->getObject($this->bucket, $object, array(OssClient::OSS_VERSION_ID => $bret2['x-oss-version-id'])); + + + $this->assertEquals(file_get_contents($smallFile1), $sres1); + $this->assertEquals(file_get_contents($smallFile2), $sres2); + $this->assertEquals(file_get_contents($bigFile1), $bres1); + $this->assertEquals(file_get_contents($bigFile2), $bres2); + $this->assertEquals(file_get_contents($bigFile2), $res); + + + unlink($smallFile1); + unlink($smallFile2); + unlink($bigFile1); + unlink($bigFile2); + } + + public function testListObjects() + { + //folder + for ($i = 0; $i < 12; $i++) { + $key = 'folder/'. sprintf("%02d",$i); + $this->ossClient->putObject($this->bucket, $key, "content"); + $this->ossClient->putObject($this->bucket, $key, "content"); + $this->ossClient->deleteObject($this->bucket, $key); + } + + //test + for ($i = 0; $i < 8; $i++) { + $key = 'test/'. sprintf("%02d",$i); + $this->ossClient->putObject($this->bucket, $key, "content"); + $this->ossClient->deleteObject($this->bucket, $key); + $this->ossClient->putObject($this->bucket, $key, "content"); + } + //work + for ($i = 0; $i < 5; $i++) { + $key = 'work/'. sprintf("%02d",$i); + $this->ossClient->putObject($this->bucket, $key, "content"); + } + //sub++ + for ($i = 0; $i < 3; $i++) { + $key = 'sub++/'. sprintf("%02d",$i); + $this->ossClient->putObject($this->bucket, $key, "content"); + $this->ossClient->putObject($this->bucket, $key, "content"); + $this->ossClient->putObject($this->bucket, $key, "content"); + } + //file++ + for ($i = 0; $i < 2; $i++) { + $key = 'file++'. sprintf("%02d",$i); + $this->ossClient->putObject($this->bucket, $key, "content"); + $this->ossClient->deleteObject($this->bucket, $key); + } + + //list default + $result = $this->ossClient->listObjectVersions($this->bucket); + $versionList = $result->getObjectVersionList(); + $deleteMarkerList = $result->getDeleteMarkerList(); + $prefixList = $result->getPrefixList(); + + $this->assertNotNull($versionList); + $this->assertNotNull($deleteMarkerList); + $this->assertNotNull($prefixList); + $this->assertTrue(is_array($versionList)); + $this->assertTrue(is_array($deleteMarkerList)); + $this->assertTrue(is_array($prefixList)); + $this->assertEquals(2, count($versionList)); + $this->assertEquals(2, count($deleteMarkerList)); + $this->assertEquals(4, count($prefixList)); + + $this->assertEquals('file++00', $versionList[0]->getKey()); + $this->assertEquals('false', $versionList[0]->getIsLatest()); + $this->assertEquals('file++01', $versionList[1]->getKey()); + $this->assertEquals('false', $versionList[1]->getIsLatest()); + + $this->assertEquals('file++00', $deleteMarkerList[0]->getKey()); + $this->assertEquals('true', $deleteMarkerList[0]->getIsLatest()); + $this->assertEquals('file++01', $deleteMarkerList[1]->getKey()); + $this->assertEquals('true', $deleteMarkerList[1]->getIsLatest()); + + + $this->assertEquals('folder/', $prefixList[0]->getPrefix()); + $this->assertEquals('sub++/', $prefixList[1]->getPrefix()); + $this->assertEquals('test/', $prefixList[2]->getPrefix()); + $this->assertEquals('work/', $prefixList[3]->getPrefix()); + + //list by prefix + $prefix = 'folder/'; + $delimiter = ''; + $next_marker = ''; + $maxkeys = 1000; + $options = array( + 'delimiter' => $delimiter, + 'prefix' => $prefix, + 'max-keys' => $maxkeys, + 'key-marker' => $next_marker, + ); + + $result = $this->ossClient->listObjectVersions($this->bucket, $options); + $versionList = $result->getObjectVersionList(); + $deleteMarkerList = $result->getDeleteMarkerList(); + $prefixList = $result->getPrefixList(); + + $this->assertEquals(24, count($versionList)); + $this->assertEquals(12, count($deleteMarkerList)); + $this->assertEquals(0, count($prefixList)); + + $this->assertEquals('folder/00', $versionList[0]->getKey()); + $this->assertEquals('folder/00', $versionList[1]->getKey()); + $this->assertEquals('folder/00', $deleteMarkerList[0]->getKey()); + $this->assertEquals('folder/01', $deleteMarkerList[1]->getKey()); + + + //max-key & key-marker & version-id-marker + $count = 0; + $markerCount = 0; + $nextMarker = ''; + $nextVersionIdMarker = ''; + + while (true) { + $options = array( + 'delimiter' => '', + 'key-marker' => $nextMarker, + 'max-keys' => 1, + 'version-id-marker' => $nextVersionIdMarker, + ); + $result = $this->ossClient->listObjectVersions($this->bucket, $options); + + $nextMarker = $result->getNextKeyMarker(); + $nextVersionIdMarker = $result->getNextVersionIdMarker(); + $count += count($result->getObjectVersionList()); + $markerCount += count($result->getDeleteMarkerList()); + $this->assertEquals(1, count($result->getObjectVersionList()) + count($result->getDeleteMarkerList())); + if ($result->getIsTruncated() !== "true") { + break; + } + } + $this->assertEquals(12*3 + 8*3 + 5 + 3*3 + 2*2, $count + $markerCount); + } + + public function testDeleteObjects() + { + //deletes + for ($i = 0; $i < 5; $i++) { + $key = 'deletes/'. sprintf("%02d",$i); + $this->ossClient->putObject($this->bucket, $key, "content"); + $this->ossClient->putObject($this->bucket, $key, "content"); + } + + $options = array( + 'delimiter' => '', + 'prefix' => 'deletes/', + 'max-keys' => 1000, + ); + $result = $this->ossClient->listObjects($this->bucket, $options); + $this->assertEquals(5, count($result->getObjectList())); + + //delete without version-id + $objects = array(); + for ($i = 0; $i < 5; $i++) { + $key = 'deletes/'. sprintf("%02d",$i); + $objects[] = new DeleteObjectInfo($key); + } + $dresult = $this->ossClient->deleteObjectVersions($this->bucket, $objects); + $this->assertEquals(5, count($dresult)); + $this->assertEquals('deletes/00', $dresult[0]->getKey()); + $this->assertEquals('true', $dresult[0]->getDeleteMarker()); + $this->assertEquals('', $dresult[0]->getVersionId()); + $this->assertFalse(empty($dresult[0]->getDeleteMarkerVersionId())); + + $result = $this->ossClient->listObjects($this->bucket, $options); + $this->assertEquals(0, count($result->getObjectList())); + + //delete by version-id + $vresult = $this->ossClient->listObjectVersions($this->bucket, $options); + $versions = $vresult->getObjectVersionList(); + $deleteMarkerList = $vresult->getDeleteMarkerList(); + $this->assertEquals(10, count($versions)); + $this->assertEquals(5, count($deleteMarkerList)); + + $objects = array(); + foreach ($versions as $obj) { + $objects[] = new DeleteObjectInfo($obj->getKey(), $obj->getVersionId()); + } + $dresult = $this->ossClient->deleteObjectVersions($this->bucket, $objects); + $this->assertEquals(10, count($dresult)); + $this->assertEquals('deletes/00', $dresult[0]->getKey()); + $this->assertEquals('', $dresult[0]->getDeleteMarker()); + $this->assertFalse(empty($dresult[0]->getVersionId())); + $this->assertTrue(empty($dresult[0]->getDeleteMarkerVersionId())); + $this->assertEquals('deletes/00', $dresult[1]->getKey()); + $this->assertEquals('', $dresult[1]->getDeleteMarker()); + $this->assertFalse(empty($dresult[1]->getVersionId())); + $this->assertTrue(empty($dresult[1]->getDeleteMarkerVersionId())); + + + $vresult = $this->ossClient->listObjectVersions($this->bucket, $options); + $versions = $vresult->getObjectVersionList(); + $deleteMarkerList = $vresult->getDeleteMarkerList(); + $this->assertEquals(0, count($versions)); + $this->assertEquals(5, count($deleteMarkerList)); + + $objects = array(); + foreach ($deleteMarkerList as $obj) { + $objects[] = new DeleteObjectInfo($obj->getKey(), $obj->getVersionId()); + } + $dresult = $this->ossClient->deleteObjectVersions($this->bucket, $objects); + $this->assertEquals(5, count($dresult)); + $this->assertEquals('deletes/00', $dresult[0]->getKey()); + $this->assertEquals('true', $dresult[0]->getDeleteMarker()); + $this->assertFalse(empty($dresult[1]->getVersionId())); + $this->assertFalse(empty($dresult[1]->getDeleteMarkerVersionId())); + + $vresult = $this->ossClient->listObjectVersions($this->bucket, $options); + $versions = $vresult->getObjectVersionList(); + $deleteMarkerList = $vresult->getDeleteMarkerList(); + $this->assertEquals(0, count($versions)); + $this->assertEquals(0, count($deleteMarkerList)); + } + + public function setUp() + { + parent::setUp(); + + $this->ossClient->putBucketVersioning($this->bucket, "Enabled"); + + } + + public function tearDown() + { + if (!$this->ossClient->doesBucketExist($this->bucket)) { + return; + } + + $this->ossClient->putBucketVersioning($this->bucket, "Suspended"); + + $result = $this->ossClient->listObjectVersions( + $this->bucket, array('max-keys' => 1000, 'delimiter' => '')); + + $versions = $result->getObjectVersionList(); + $deleteMarkers = $result->getDeleteMarkerList(); + + foreach ($versions as $obj) { + $options = array( + OssClient::OSS_VERSION_ID => $obj->getVersionId(), + ); + $this->ossClient->deleteObject($this->bucket, $obj->getKey(), $options); + } + + foreach ($deleteMarkers as $del) { + $options = array( + OssClient::OSS_VERSION_ID => $del->getVersionId(), + ); + $this->ossClient->deleteObject($this->bucket, $del->getKey(), $options); + } + + parent::tearDown(); + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientRestoreObjectTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientRestoreObjectTest.php index cc1412f80..6840813be 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientRestoreObjectTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientRestoreObjectTest.php @@ -4,6 +4,7 @@ use OSS\Core\OssException; use OSS\OssClient; +use OSS\Model\RestoreConfig; require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; @@ -63,6 +64,83 @@ public function testArchiveRestoreObject() } } + public function testColdArchiveRestoreObject() + { + $client = new OssClient( + getenv('OSS_ACCESS_KEY_ID'), + getenv('OSS_ACCESS_KEY_SECRET'), + 'oss-ap-southeast-1.aliyuncs.com', false); + + $bucket = $this->bucket . 'cold-archive'; + $object = 'storage-object'; + + //create bucket + $options = array( + OssClient::OSS_STORAGE => OssClient::OSS_STORAGE_COLDARCHIVE + ); + $client->createBucket($bucket, OssClient::OSS_ACL_TYPE_PRIVATE, $options); + + //test with days + $client->putObject($bucket, $object,'testcontent'); + + try{ + $client->getObject($bucket, $object); + $this->assertTrue(false); + }catch (OssException $e){ + $this->assertEquals('403', $e->getHTTPStatus()); + $this->assertEquals('InvalidObjectState', $e->getErrorCode()); + } + + $config = new RestoreConfig(5); + $resoptions = array( + OssClient::OSS_RESTORE_CONFIG => $config + ); + try{ + $client->restoreObject($bucket, $object, $resoptions); + }catch(OssException $e){ + $this->assertTrue(false); + } + + try{ + $client->restoreObject($bucket, $object, $resoptions); + }catch(OssException $e){ + $this->assertEquals('409', $e->getHTTPStatus()); + $this->assertEquals('RestoreAlreadyInProgress', $e->getErrorCode()); + } + + //test with days & tier + $client->putObject($bucket, $object,'testcontent'); + + try{ + $client->getObject($bucket, $object); + $this->assertTrue(false); + }catch (OssException $e){ + $this->assertEquals('403', $e->getHTTPStatus()); + $this->assertEquals('InvalidObjectState', $e->getErrorCode()); + } + + $config = new RestoreConfig(5, "Expedited"); + $resoptions = array( + OssClient::OSS_RESTORE_CONFIG => $config + ); + try{ + $client->restoreObject($bucket, $object, $resoptions); + }catch(OssException $e){ + $this->assertTrue(false); + } + + try{ + $client->restoreObject($bucket, $object, $resoptions); + }catch(OssException $e){ + $this->assertEquals('409', $e->getHTTPStatus()); + $this->assertEquals('RestoreAlreadyInProgress', $e->getErrorCode()); + } + + $client->deleteObject($bucket, $object); + $client->deleteBucket($bucket); + } + + public function setUp() { parent::setUp(); diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientSignatureTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientSignatureTest.php index 109121d0f..2b72253c7 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientSignatureTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientSignatureTest.php @@ -75,6 +75,62 @@ public function testGetSignedUrlForPuttingObjectFromFile() } + public function testSignedUrlWithException() + { + $file = __FILE__; + $object = "a.file"; + $timeout = 3600; + $options = array('Content-Type' => 'txt'); + try { + $signedUrl = $this->ossClient->signUrl($this->bucket, $object, $timeout, "POST", $options); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + if (strpos($e, "method is invalid") == false) + { + $this->assertTrue(false); + } + } + } + + function testGetgenPreSignedUrlForGettingObject() + { + $object = "a.file"; + $this->ossClient->putObject($this->bucket, $object, file_get_contents(__FILE__)); + $expires = time() + 3600; + try { + $signedUrl = $this->ossClient->generatePresignedUrl($this->bucket, $object, $expires); + } catch (OssException $e) { + $this->assertFalse(true); + } + + $request = new RequestCore($signedUrl); + $request->set_method('GET'); + $request->add_header('Content-Type', ''); + $request->send_request(); + $res = new ResponseCore($request->get_response_header(), $request->get_response_body(), $request->get_response_code()); + $this->assertEquals(file_get_contents(__FILE__), $res->body); + } + + function testGetgenPreSignedUrlVsSignedUrl() + { + $object = "object-vs.file"; + $signedUrl1 = '245'; + $signedUrl2 = '123'; + $expiration = 0; + + do { + usleep(500000); + $begin = time(); + $expiration = time() + 3600; + $signedUrl1 = $this->ossClient->generatePresignedUrl($this->bucket, $object, $expiration); + $signedUrl2 = $this->ossClient->signUrl($this->bucket, $object, 3600); + $end = time(); + } while ($begin != $end); + $this->assertEquals($signedUrl1, $signedUrl2); + $this->assertTrue(strpos($signedUrl1, 'Expires='.$expiration) !== false); + } + public function tearDown() { $this->ossClient->deleteObject($this->bucket, "a.file"); diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientTest.php index f92b3461f..f850f7ab8 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientTest.php @@ -6,7 +6,7 @@ use OSS\OssClient; -class OssClientTest extends \PHPUnit_Framework_TestCase +class OssClientTest extends TestOssClientBase { public function testConstrunct() { @@ -60,6 +60,7 @@ public function testConstrunct5() { try { $ossClient = new OssClient('id', 'key', "123.123.123.1"); + $this->assertTrue(true); } catch (OssException $e) { $this->assertTrue(false); } @@ -70,6 +71,15 @@ public function testConstrunct6() try { $ossClient = new OssClient('id', 'key', "https://123.123.123.1"); $this->assertTrue($ossClient->isUseSSL()); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $ossClient = new OssClient('id', 'key', "https://123.123.123.1:3128"); + $this->assertTrue($ossClient->isUseSSL()); + $this->assertTrue(true); } catch (OssException $e) { $this->assertTrue(false); } @@ -80,6 +90,15 @@ public function testConstrunct7() try { $ossClient = new OssClient('id', 'key', "http://123.123.123.1"); $this->assertFalse($ossClient->isUseSSL()); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $ossClient = new OssClient('id', 'key', "http://123.123.123.1:3128"); + $this->assertFalse($ossClient->isUseSSL()); + $this->assertTrue(true); } catch (OssException $e) { $this->assertTrue(false); } @@ -109,33 +128,86 @@ public function testConstrunct9() } } + public function testConstrunct10() + { + try { + $ossClient = new OssClient('id', 'key', "http://ABC-COM.TEST.123.cn", true); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + public function testConstrunct11() + { + try { + $ossClient = new OssClient('id', 'key', "oss-test.com\\aliyuncs.com"); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals('endpoint is invalid:'."oss-test.com\\aliyuncs.com", $e->getMessage()); + } + } + + public function testConstrunct12() + { + try { + $ossClient = new OssClient('id', 'key', "192.168.1.0:abc123"); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals('endpoint is invalid:'."192.168.1.0:abc123", $e->getMessage()); + } + } + public function testSupportPutEmptyObject() { try { $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ '; - $bucket = getenv('OSS_BUCKET'); + $bucket = $this->bucket; $ossClient = new OssClient($accessKeyId, $accessKeySecret , $endpoint, false); $ossClient->putObject($bucket,'test_emptybody',''); } catch (OssException $e) { $this->assertFalse(true); } - } - public function testCreateObjectDir() - { + //use invalid sts-token, should fail. try { $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ '; - $bucket = getenv('OSS_BUCKET'); + $bucket = $this->bucket; + $ossClient = new OssClient($accessKeyId, $accessKeySecret , $endpoint, false, "invalid-sts-token"); + $ossClient->putObject($bucket,'test_emptybody',''); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('InvalidAccessKeyId', $e->getErrorCode()); + } + } + + public function testCreateObjectDir() + { + $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; + $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; + $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ '; + $bucket = $this->bucket; + $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false); + + try { $object='test-dir'; - $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false); $ossClient->createObjectDir($bucket,$object); } catch (OssException $e) { $this->assertFalse(true); } + + try { + $object='0'; + $ossClient->createObjectDir($bucket,$object); + $ossClient->putObject($bucket,$object, ''); + } catch (OssException $e) { + var_dump($e); + $this->assertFalse(true); + } } public function testGetBucketCors() @@ -158,7 +230,7 @@ public function testGetBucketCname() $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ '; - $bucket = getenv('OSS_BUCKET'); + $bucket = $this->bucket; $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false); $ossClient->getBucketCname($bucket); } catch (OssException $e) { @@ -213,4 +285,57 @@ private function checkProxy($result, $proxys) $this->assertTrue(array_key_exists('via', $result)); } + public function testIpEndpoint() + { + try { + $accessKeyId = 'sk' . getenv('OSS_ACCESS_KEY_ID') . ' '; + $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; + $endpoint = '192.168.1.1'; + $bucket = getenv('OSS_BUCKET'); + $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false); + $object = "a.file"; + $timeout = 3600; + $options = array('Content-Type' => 'txt'); + $signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "PUT", $options); + $this->assertTrue(strpos($signedUrl, '192.168.1.1/skyranch-php-test/a.file?') != false); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testCnameEndpoint() + { + try { + $accessKeyId = 'sk' . getenv('OSS_ACCESS_KEY_ID') . ' '; + $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; + $endpoint = 'cname.endpoint'; + $bucket = getenv('OSS_BUCKET'); + $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, true); + $object = "a.file"; + $timeout = 3600; + $options = array('Content-Type' => 'txt'); + $signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "PUT", $options); + $this->assertTrue(strpos($signedUrl, 'cname.endpoint/a.file?') != false); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testStsToken() + { + try { + $accessKeyId = 'sk' . getenv('OSS_ACCESS_KEY_ID') . ' '; + $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; + $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ '; + $bucket = getenv('OSS_BUCKET'); + $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false, "test-token"); + $object = "a.file"; + $timeout = 3600; + $options = array('Content-Type' => 'txt'); + $signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "PUT", $options); + $this->assertTrue(strpos($signedUrl, 'security-token=test-token') != false); + } catch (OssException $e) { + $this->assertFalse(true); + } + } } diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssTrafficLimitTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssTrafficLimitTest.php new file mode 100644 index 000000000..5aeb0ea62 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssTrafficLimitTest.php @@ -0,0 +1,96 @@ + array( + OssClient::OSS_TRAFFIC_LIMIT => 819200, + )); + + try { + $result = $this->ossClient->putObject($this->bucket, 'default-object', 'content', $options); + $this->assertTrue(true); + $this->assertTrue(isset($result["x-oss-qos-delay-time"])); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $result = $this->ossClient->appendObject($this->bucket, 'append-object', 'content', 0, $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $result = $this->ossClient->copyObject($this->bucket, 'default-object', $this->bucket, 'copy-object', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $result = $this->ossClient->getObject($this->bucket, 'default-object', $options); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + function testTrafficLimitInQuery() + { + $options = array( + OssClient::OSS_TRAFFIC_LIMIT => 819200, + ); + + $object = "get.file"; + $content = 'hello world'; + $this->ossClient->putObject($this->bucket, $object, $content); + $timeout = 3600; + try { + $signedUrl = $this->ossClient->signUrl($this->bucket, $object, $timeout, "GET", $options); + $this->assertTrue(stripos($signedUrl, 'x-oss-traffic-limit=819200') > 0); + } catch (OssException $e) { + $this->assertFalse(true); + } + + $request = new RequestCore($signedUrl); + $request->set_method('GET'); + $request->add_header('Content-Type', ''); + $request->send_request(); + $res = new ResponseCore($request->get_response_header(), $request->get_response_body(), $request->get_response_code()); + $this->assertEquals($content, $res->body); + + + $object = "put.file"; + $timeout = 3600; + try { + $signedUrl = $this->ossClient->signUrl($this->bucket, $object, $timeout, "PUT", $options); + $this->assertTrue(stripos($signedUrl, 'x-oss-traffic-limit=819200') > 0); + + $request = new RequestCore($signedUrl); + $request->set_method('PUT'); + $request->add_header('Content-Type', ''); + $request->add_header('Content-Length', strlen($content)); + $request->set_body($content); + $request->send_request(); + $res = new ResponseCore($request->get_response_header(), + $request->get_response_body(), $request->get_response_code()); + $this->assertTrue($res->isOK()); + } catch (OssException $e) { + $this->assertFalse(true); + } + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssUtilTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssUtilTest.php index c56524967..ba2f1a006 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssUtilTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssUtilTest.php @@ -155,6 +155,10 @@ public function testIsWin() public function testGetMd5SumForFile() { $this->assertEquals(OssUtil::getMd5SumForFile(__FILE__, 0, filesize(__FILE__) - 1), base64_encode(md5(file_get_contents(__FILE__), true))); + // false case + $this->assertEquals(OssUtil::getMd5SumForFile(__FILE__, 0, OssClient::OSS_MAX_PART_SIZE + 1), ""); + $this->assertEquals(OssUtil::getMd5SumForFile(__FILE__, 0, filesize(__FILE__) + 1), ""); + } public function testGenerateFile() @@ -242,10 +246,55 @@ public function testGetHostPortFromEndpoint() $str = OssUtil::getHostPortFromEndpoint('192.168.1.10:8080'); $this->assertEquals('192.168.1.10:8080', $str); - $str = OssUtil::getHostPortFromEndpoint('http:///path?arg=value#anchor'); - $this->assertEquals('', $str); - $str = OssUtil::getHostPortFromEndpoint('file://username:password@hostname:80/path?arg=value#anchor'); $this->assertEquals('hostname:80', $str); + + $str = OssUtil::getHostPortFromEndpoint('https://WWW.hostname.com-_www.test.com'); + $this->assertEquals('WWW.hostname.com-_www.test.com', $str); + + try { + $str = OssUtil::getHostPortFromEndpoint('http:///path?arg=value#anchor'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + } + + try { + $str = OssUtil::getHostPortFromEndpoint('https://www.hostname.com\www.test.com'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + } + + try { + $str = OssUtil::getHostPortFromEndpoint('www.hostname.com-_*www.test.com'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + } + + try { + $str = OssUtil::getHostPortFromEndpoint('www.hostname.com:ab123'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + } + + try { + $str = OssUtil::getHostPortFromEndpoint('www.hostname.com:'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + } + } + + public function testDecodeKey() + { + try { + OssUtil::decodeKey("key", "unknown"); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + } } } diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/StorageCapacityConfigTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/StorageCapacityConfigTest.php new file mode 100644 index 000000000..8a1f42e81 --- /dev/null +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/StorageCapacityConfigTest.php @@ -0,0 +1,58 @@ + + +10 + +BBBB; + +private $validXml_20 = << + +20 + +BBBB; + + public function testConstruct() + { + $config = new StorageCapacityConfig(10); + $this->assertEquals($config->getStorageCapacity(), 10); + $this->assertEquals($this->cleanXml($this->validXml_10), $this->cleanXml($config->serializeToXml())); + } + + public function testSetStorageCapacity() + { + $config = new StorageCapacityConfig(2); + $config->setStorageCapacity(20); + $this->assertEquals($this->cleanXml($this->validXml_20), $this->cleanXml($config->serializeToXml())); + $this->assertEquals($this->cleanXml($this->validXml_20), $this->cleanXml($config->__toString())); + } + + public function testParseFromXml() + { + try { + $config = new StorageCapacityConfig(10); + $config->parseFromXml('invaide xml'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + if (strpos($e, "Not implemented.") == false) + { + $this->assertTrue(false); + } + } + } + + private function cleanXml($xml) + { + return str_replace("\n", "", str_replace("\r", "", $xml)); + } +} diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/SymlinkTest.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/SymlinkTest.php index 4a39dfa97..c43639184 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/SymlinkTest.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/SymlinkTest.php @@ -13,7 +13,7 @@ class SymlinkTest extends TestOssClientBase { public function testPutSymlink() { - $bucket = getenv('OSS_BUCKET'); + $bucket = $this->bucket; $symlink = 'test-link'; $special_object = 'exist_object^$#!~'; $object = 'exist_object'; @@ -31,10 +31,13 @@ public function testPutSymlink() public function testGetSymlink() { - $bucket = getenv('OSS_BUCKET'); + $bucket = $this->bucket; $symlink = 'test-link'; $object = 'exist_object^$#!~'; + $this->ossClient ->putObject($bucket, $object, 'test_content'); + $this->ossClient->putSymlink($bucket, $symlink, $object); + $result = $this->ossClient->getSymlink($bucket, $symlink); $this->assertEquals($result[OssClient::OSS_SYMLINK_TARGET], $object); $this->assertEquals('200', $result[OssClient::OSS_INFO][OssClient::OSS_HTTP_CODE]); @@ -44,7 +47,7 @@ public function testGetSymlink() public function testPutNullSymlink() { - $bucket = getenv('OSS_BUCKET'); + $bucket = $this->bucket; $symlink = 'null-link'; $object_not_exist = 'not_exist_object+$#!b不'; $this->ossClient->putSymlink($bucket, $symlink, $object_not_exist); @@ -53,13 +56,13 @@ public function testPutNullSymlink() $this->ossClient->getObject($bucket, $symlink); $this->assertTrue(false); }catch (OssException $e){ - $this->assertEquals('The specified key does not exist.', $e->getErrorMessage()); + $this->assertEquals('The symlink target object does not exist', $e->getErrorMessage()); } } public function testGetNullSymlink() { - $bucket = getenv('OSS_BUCKET'); + $bucket = $this->bucket; $symlink = 'null-link-new'; try{ diff --git a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/TestOssClientBase.php b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/TestOssClientBase.php index 4abd31f92..233568a39 100644 --- a/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/TestOssClientBase.php +++ b/vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/TestOssClientBase.php @@ -20,10 +20,10 @@ class TestOssClientBase extends \PHPUnit_Framework_TestCase public function setUp() { - $this->bucket = Common::getBucketName() . rand(100000, 999999); + $this->bucket = Common::getBucketName() .'-'. time(); $this->ossClient = Common::getOssClient(); $this->ossClient->createBucket($this->bucket); - Common::waitMetaSync(); + Common::waitMetaSync(); } public function tearDown() diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index fce8549f0..1a58957d2 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -37,8 +37,8 @@ * * @author Fabien Potencier * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { @@ -60,7 +60,7 @@ class ClassLoader public function getPrefixes() { if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', $this->prefixesPsr0); + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); } return array(); diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php new file mode 100644 index 000000000..29a737095 --- /dev/null +++ b/vendor/composer/InstalledVersions.php @@ -0,0 +1,550 @@ + + array ( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'aliases' => + array ( + ), + 'reference' => '1a4a317fafac750db4742672a1501a2476d219c9', + 'name' => 'wisp-x/lsky-pro', + ), + 'versions' => + array ( + 'aliyuncs/oss-sdk-php' => + array ( + 'pretty_version' => 'v2.4.1', + 'version' => '2.4.1.0', + 'aliases' => + array ( + ), + 'reference' => '492866331b7bafaac09506cf42f351b7e9e63766', + ), + 'guzzle/batch' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/cache' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/common' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/guzzle' => + array ( + 'pretty_version' => 'v3.9.3', + 'version' => '3.9.3.0', + 'aliases' => + array ( + ), + 'reference' => '0645b70d953bc1c067bbc8d5bc53194706b628d9', + ), + 'guzzle/http' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/inflection' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/iterator' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/log' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/parser' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-async' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-backoff' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-cache' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-cookie' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-curlauth' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-error-response' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-history' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-log' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-md5' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-mock' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-oauth' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/service' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/stream' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzlehttp/guzzle' => + array ( + 'pretty_version' => '6.5.5', + 'version' => '6.5.5.0', + 'aliases' => + array ( + ), + 'reference' => '9d4290de1cfd701f38099ef7e183b64b4b7b0c5e', + ), + 'guzzlehttp/promises' => + array ( + 'pretty_version' => '1.4.1', + 'version' => '1.4.1.0', + 'aliases' => + array ( + ), + 'reference' => '8e7d04f1f6450fef59366c399cfad4b9383aa30d', + ), + 'guzzlehttp/psr7' => + array ( + 'pretty_version' => '1.8.1', + 'version' => '1.8.1.0', + 'aliases' => + array ( + ), + 'reference' => '35ea11d335fd638b5882ff1725228b3d35496ab1', + ), + 'nicolab/php-ftp-client' => + array ( + 'pretty_version' => 'v1.5.5', + 'version' => '1.5.5.0', + 'aliases' => + array ( + ), + 'reference' => '3c34d6beb4e31f29756ab92bc8436cd761f345d3', + ), + 'phpmailer/phpmailer' => + array ( + 'pretty_version' => 'v6.4.0', + 'version' => '6.4.0.0', + 'aliases' => + array ( + ), + 'reference' => '050d430203105c27c30efd1dce7aa421ad882d01', + ), + 'psr/http-message' => + array ( + 'pretty_version' => '1.0.1', + 'version' => '1.0.1.0', + 'aliases' => + array ( + ), + 'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363', + ), + 'psr/http-message-implementation' => + array ( + 'provided' => + array ( + 0 => '1.0', + ), + ), + 'qcloud/cos-sdk-v5' => + array ( + 'pretty_version' => 'v1.3.4', + 'version' => '1.3.4.0', + 'aliases' => + array ( + ), + 'reference' => '1b32aa422f6dffe4ea411e5095e4b0da9135551b', + ), + 'qiniu/php-sdk' => + array ( + 'pretty_version' => 'v7.3.0', + 'version' => '7.3.0.0', + 'aliases' => + array ( + ), + 'reference' => '0a461e13b09545b23df361843c6a65fdd3a26426', + ), + 'ralouphie/getallheaders' => + array ( + 'pretty_version' => '3.0.3', + 'version' => '3.0.3.0', + 'aliases' => + array ( + ), + 'reference' => '120b605dfeb996808c31b6477290a714d356e822', + ), + 'symfony/event-dispatcher' => + array ( + 'pretty_version' => 'v2.8.52', + 'version' => '2.8.52.0', + 'aliases' => + array ( + ), + 'reference' => 'a77e974a5fecb4398833b0709210e3d5e334ffb0', + ), + 'symfony/polyfill-intl-idn' => + array ( + 'pretty_version' => 'v1.22.1', + 'version' => '1.22.1.0', + 'aliases' => + array ( + ), + 'reference' => '2d63434d922daf7da8dd863e7907e67ee3031483', + ), + 'symfony/polyfill-intl-normalizer' => + array ( + 'pretty_version' => 'v1.22.1', + 'version' => '1.22.1.0', + 'aliases' => + array ( + ), + 'reference' => '43a0283138253ed1d48d352ab6d0bdb3f809f248', + ), + 'symfony/polyfill-php72' => + array ( + 'pretty_version' => 'v1.22.1', + 'version' => '1.22.1.0', + 'aliases' => + array ( + ), + 'reference' => 'cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9', + ), + 'topthink/framework' => + array ( + 'pretty_version' => 'v5.1.41', + 'version' => '5.1.41.0', + 'aliases' => + array ( + ), + 'reference' => '7137741a323a4a60cfca334507cd1812fac91bb2', + ), + 'topthink/think-captcha' => + array ( + 'pretty_version' => 'v2.0.2', + 'version' => '2.0.2.0', + 'aliases' => + array ( + ), + 'reference' => '54c8a51552f99ff9ea89ea9c272383a8f738ceee', + ), + 'topthink/think-image' => + array ( + 'pretty_version' => 'v1.0.7', + 'version' => '1.0.7.0', + 'aliases' => + array ( + ), + 'reference' => '8586cf47f117481c6d415b20f7dedf62e79d5512', + ), + 'topthink/think-installer' => + array ( + 'pretty_version' => 'v2.0.5', + 'version' => '2.0.5.0', + 'aliases' => + array ( + ), + 'reference' => '38ba647706e35d6704b5d370c06f8a160b635f88', + ), + 'upyun/sdk' => + array ( + 'pretty_version' => '3.5.0', + 'version' => '3.5.0.0', + 'aliases' => + array ( + ), + 'reference' => 'c9f824626552c32b987de4ac7f136e0e21cca962', + ), + 'wisp-x/lsky-pro' => + array ( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'aliases' => + array ( + ), + 'reference' => '1a4a317fafac750db4742672a1501a2476d219c9', + ), + ), +); + + + + + + + +public static function getInstalledPackages() +{ +return array_keys(self::$installed['versions']); +} + + + + + + + + + +public static function isInstalled($packageName) +{ +return isset(self::$installed['versions'][$packageName]); +} + + + + + + + + + + + + + + +public static function satisfies(VersionParser $parser, $packageName, $constraint) +{ +$constraint = $parser->parseConstraints($constraint); +$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + +return $provided->matches($constraint); +} + + + + + + + + + + +public static function getVersionRanges($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +$ranges = array(); +if (isset(self::$installed['versions'][$packageName]['pretty_version'])) { +$ranges[] = self::$installed['versions'][$packageName]['pretty_version']; +} +if (array_key_exists('aliases', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']); +} +if (array_key_exists('replaced', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']); +} +if (array_key_exists('provided', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']); +} + +return implode(' || ', $ranges); +} + + + + + +public static function getVersion($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['version'])) { +return null; +} + +return self::$installed['versions'][$packageName]['version']; +} + + + + + +public static function getPrettyVersion($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) { +return null; +} + +return self::$installed['versions'][$packageName]['pretty_version']; +} + + + + + +public static function getReference($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['reference'])) { +return null; +} + +return self::$installed['versions'][$packageName]['reference']; +} + + + + + +public static function getRootPackage() +{ +return self::$installed['root']; +} + + + + + + + +public static function getRawData() +{ +return self::$installed; +} + + + + + + + + + + + + + + + + + + + +public static function reload($data) +{ +self::$installed = $data; +} +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 7a91153b0..fd407a3a1 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -6,4 +6,6 @@ $baseDir = dirname($vendorDir); return array( + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', + 'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', ); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index 0ac17271d..5ba89e06c 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -7,12 +7,12 @@ return array( '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', + 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', - '841780ea2e1d6545ea3a253239d59c05' => $vendorDir . '/qiniu/php-sdk/src/Qiniu/functions.php', '1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php', + '841780ea2e1d6545ea3a253239d59c05' => $vendorDir . '/qiniu/php-sdk/src/Qiniu/functions.php', ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 15a0d516c..acef2f65b 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -12,7 +12,7 @@ 'app\\' => array($baseDir . '/application'), 'Upyun\\' => array($vendorDir . '/upyun/sdk/src/Upyun'), 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), - 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), + 'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'), 'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'), 'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'), 'Qiniu\\' => array($vendorDir . '/qiniu/php-sdk/src/Qiniu'), diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index c7b82ab8d..e1cc1c6ed 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -22,13 +22,15 @@ public static function getLoader() return self::$loader; } + require __DIR__ . '/platform_check.php'; + spl_autoload_register(array('ComposerAutoloaderInitf1a511e38c2f284964a16f1eeccf1745', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInitf1a511e38c2f284964a16f1eeccf1745', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; + require __DIR__ . '/autoload_static.php'; call_user_func(\Composer\Autoload\ComposerStaticInitf1a511e38c2f284964a16f1eeccf1745::getInitializer($loader)); } else { diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 852cf88b2..6d7d2d211 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -8,14 +8,14 @@ class ComposerStaticInitf1a511e38c2f284964a16f1eeccf1745 { public static $files = array ( '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', + 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', 'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', - '841780ea2e1d6545ea3a253239d59c05' => __DIR__ . '/..' . '/qiniu/php-sdk/src/Qiniu/functions.php', '1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php', + '841780ea2e1d6545ea3a253239d59c05' => __DIR__ . '/..' . '/qiniu/php-sdk/src/Qiniu/functions.php', ); public static $prefixLengthsPsr4 = array ( @@ -36,7 +36,7 @@ class ComposerStaticInitf1a511e38c2f284964a16f1eeccf1745 'S' => array ( 'Symfony\\Polyfill\\Php72\\' => 23, - 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33, 'Symfony\\Polyfill\\Intl\\Idn\\' => 26, 'Symfony\\Component\\EventDispatcher\\' => 34, ), @@ -86,9 +86,9 @@ class ComposerStaticInitf1a511e38c2f284964a16f1eeccf1745 array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-php72', ), - 'Symfony\\Polyfill\\Mbstring\\' => + 'Symfony\\Polyfill\\Intl\\Normalizer\\' => array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', + 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer', ), 'Symfony\\Polyfill\\Intl\\Idn\\' => array ( @@ -156,12 +156,18 @@ class ComposerStaticInitf1a511e38c2f284964a16f1eeccf1745 ), ); + public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + 'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', + ); + public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { $loader->prefixLengthsPsr4 = ComposerStaticInitf1a511e38c2f284964a16f1eeccf1745::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInitf1a511e38c2f284964a16f1eeccf1745::$prefixDirsPsr4; $loader->prefixesPsr0 = ComposerStaticInitf1a511e38c2f284964a16f1eeccf1745::$prefixesPsr0; + $loader->classMap = ComposerStaticInitf1a511e38c2f284964a16f1eeccf1745::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 210ff3ecf..917be000f 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1,1313 +1,1388 @@ -[ - { - "name": "aliyuncs/oss-sdk-php", - "version": "v2.3.1", - "version_normalized": "2.3.1.0", - "source": { - "type": "git", - "url": "https://github.com/aliyun/aliyun-oss-php-sdk.git", - "reference": "053d7ba9e798e4c09b9c5c1edab153d25ea9643a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/aliyun/aliyun-oss-php-sdk/zipball/053d7ba9e798e4c09b9c5c1edab153d25ea9643a", - "reference": "053d7ba9e798e4c09b9c5c1edab153d25ea9643a", - "shasum": "", - "mirrors": [ +{ + "packages": [ + { + "name": "aliyuncs/oss-sdk-php", + "version": "v2.4.1", + "version_normalized": "2.4.1.0", + "source": { + "type": "git", + "url": "https://github.com/aliyun/aliyun-oss-php-sdk.git", + "reference": "492866331b7bafaac09506cf42f351b7e9e63766" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aliyun/aliyun-oss-php-sdk/zipball/492866331b7bafaac09506cf42f351b7e9e63766", + "reference": "492866331b7bafaac09506cf42f351b7e9e63766", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "satooshi/php-coveralls": "~1.0" + }, + "time": "2020-09-29T06:23:57+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "OSS\\": "src/OSS" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "Aliyuncs", + "homepage": "http://www.aliyun.com" } - ] - }, - "require": { - "php": ">=5.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0", - "satooshi/php-coveralls": "~1.0" - }, - "time": "2019-11-15T11:05:42+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "OSS\\": "src/OSS" - } - }, - "notification-url": "https://repo.packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Aliyuncs", - "homepage": "http://www.aliyun.com" - } - ], - "description": "Aliyun OSS SDK for PHP", - "homepage": "http://www.aliyun.com/product/oss/" - }, - { - "name": "guzzle/guzzle", - "version": "v3.9.3", - "version_normalized": "3.9.3.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle3.git", - "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", - "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", - "shasum": "", - "mirrors": [ + ], + "description": "Aliyun OSS SDK for PHP", + "homepage": "http://www.aliyun.com/product/oss/", + "support": { + "issues": "https://github.com/aliyun/aliyun-oss-php-sdk/issues", + "source": "https://github.com/aliyun/aliyun-oss-php-sdk/tree/v2.4.1" + }, + "install-path": "../aliyuncs/oss-sdk-php" + }, + { + "name": "guzzle/guzzle", + "version": "v3.9.3", + "version_normalized": "3.9.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle3.git", + "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", + "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.3", + "symfony/event-dispatcher": "~2.1" + }, + "replace": { + "guzzle/batch": "self.version", + "guzzle/cache": "self.version", + "guzzle/common": "self.version", + "guzzle/http": "self.version", + "guzzle/inflection": "self.version", + "guzzle/iterator": "self.version", + "guzzle/log": "self.version", + "guzzle/parser": "self.version", + "guzzle/plugin": "self.version", + "guzzle/plugin-async": "self.version", + "guzzle/plugin-backoff": "self.version", + "guzzle/plugin-cache": "self.version", + "guzzle/plugin-cookie": "self.version", + "guzzle/plugin-curlauth": "self.version", + "guzzle/plugin-error-response": "self.version", + "guzzle/plugin-history": "self.version", + "guzzle/plugin-log": "self.version", + "guzzle/plugin-md5": "self.version", + "guzzle/plugin-mock": "self.version", + "guzzle/plugin-oauth": "self.version", + "guzzle/service": "self.version", + "guzzle/stream": "self.version" + }, + "require-dev": { + "doctrine/cache": "~1.3", + "monolog/monolog": "~1.0", + "phpunit/phpunit": "3.7.*", + "psr/log": "~1.0", + "symfony/class-loader": "~2.1", + "zendframework/zend-cache": "2.*,<2.3", + "zendframework/zend-log": "2.*,<2.3" + }, + "suggest": { + "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated." + }, + "time": "2015-03-18T18:23:50+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.9-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Guzzle": "src/", + "Guzzle\\Tests": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Guzzle Community", + "homepage": "https://github.com/guzzle/guzzle/contributors" } - ] - }, - "require": { - "ext-curl": "*", - "php": ">=5.3.3", - "symfony/event-dispatcher": "~2.1" - }, - "replace": { - "guzzle/batch": "self.version", - "guzzle/cache": "self.version", - "guzzle/common": "self.version", - "guzzle/http": "self.version", - "guzzle/inflection": "self.version", - "guzzle/iterator": "self.version", - "guzzle/log": "self.version", - "guzzle/parser": "self.version", - "guzzle/plugin": "self.version", - "guzzle/plugin-async": "self.version", - "guzzle/plugin-backoff": "self.version", - "guzzle/plugin-cache": "self.version", - "guzzle/plugin-cookie": "self.version", - "guzzle/plugin-curlauth": "self.version", - "guzzle/plugin-error-response": "self.version", - "guzzle/plugin-history": "self.version", - "guzzle/plugin-log": "self.version", - "guzzle/plugin-md5": "self.version", - "guzzle/plugin-mock": "self.version", - "guzzle/plugin-oauth": "self.version", - "guzzle/service": "self.version", - "guzzle/stream": "self.version" - }, - "require-dev": { - "doctrine/cache": "~1.3", - "monolog/monolog": "~1.0", - "phpunit/phpunit": "3.7.*", - "psr/log": "~1.0", - "symfony/class-loader": "~2.1", - "zendframework/zend-cache": "2.*,<2.3", - "zendframework/zend-log": "2.*,<2.3" - }, - "suggest": { - "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated." - }, - "time": "2015-03-18T18:23:50+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.9-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-0": { - "Guzzle": "src/", - "Guzzle\\Tests": "tests/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Guzzle Community", - "homepage": "https://github.com/guzzle/guzzle/contributors" - } - ], - "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "abandoned": "guzzlehttp/guzzle" - }, - { - "name": "guzzlehttp/guzzle", - "version": "6.5.5", - "version_normalized": "6.5.5.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", - "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", - "shasum": "", - "mirrors": [ + ], + "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "abandoned": "guzzlehttp/guzzle", + "install-path": "../guzzle/guzzle" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.5", + "version_normalized": "6.5.5.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", + "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.17.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "time": "2020-06-16T21:01:06+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" } - ] - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.6.1", - "php": ">=5.5", - "symfony/polyfill-intl-idn": "^1.17.0" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", - "psr/log": "^1.1" - }, - "suggest": { - "psr/log": "Required for using the Log middleware" - }, - "time": "2020-06-16T21:01:06+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.5-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "GuzzleHttp\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ] - }, - { - "name": "guzzlehttp/promises", - "version": "v1.3.1", - "version_normalized": "1.3.1.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "shasum": "", - "mirrors": [ + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "install-path": "../guzzlehttp/guzzle" + }, + { + "name": "guzzlehttp/promises", + "version": "1.4.1", + "version_normalized": "1.4.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d", + "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "time": "2021-03-07T09:25:29+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" } - ] - }, - "require": { - "php": ">=5.5.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0" - }, - "time": "2016-12-20T10:07:11+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ] - }, - { - "name": "guzzlehttp/psr7", - "version": "1.6.1", - "version_normalized": "1.6.1.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a", - "shasum": "", - "mirrors": [ + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.4.1" + }, + "install-path": "../guzzlehttp/promises" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.8.1", + "version_normalized": "1.8.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/35ea11d335fd638b5882ff1725228b3d35496ab1", + "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "time": "2021-03-21T16:25:00+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" } - ] - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0", - "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "ext-zlib": "*", - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" - }, - "suggest": { - "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" - }, - "time": "2019-07-01T23:21:34+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Schultze", - "homepage": "https://github.com/Tobion" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "psr-7", - "request", - "response", - "stream", - "uri", - "url" - ] - }, - { - "name": "nicolab/php-ftp-client", - "version": "v1.5.3", - "version_normalized": "1.5.3.0", - "source": { - "type": "git", - "url": "https://github.com/Nicolab/php-ftp-client.git", - "reference": "692ea47a87049cf6b4f4dbce935e0551364e0576" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Nicolab/php-ftp-client/zipball/692ea47a87049cf6b4f4dbce935e0551364e0576", - "reference": "692ea47a87049cf6b4f4dbce935e0551364e0576", - "shasum": "", - "mirrors": [ + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.8.1" + }, + "install-path": "../guzzlehttp/psr7" + }, + { + "name": "nicolab/php-ftp-client", + "version": "v1.5.5", + "version_normalized": "1.5.5.0", + "source": { + "type": "git", + "url": "https://github.com/Nicolab/php-ftp-client.git", + "reference": "3c34d6beb4e31f29756ab92bc8436cd761f345d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nicolab/php-ftp-client/zipball/3c34d6beb4e31f29756ab92bc8436cd761f345d3", + "reference": "3c34d6beb4e31f29756ab92bc8436cd761f345d3", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-ftp": "*", + "php": ">=5.4" + }, + "time": "2021-01-06T13:58:04+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "FtpClient": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "Nicolas Tallefourtane", + "email": "dev@nicolab.net", + "homepage": "http://nicolab.net" } - ] - }, - "require": { - "ext-ftp": "*", - "php": ">=5.4" - }, - "time": "2020-03-09T13:56:46+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-0": { - "FtpClient": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Tallefourtane", - "email": "dev@nicolab.net", - "homepage": "http://nicolab.net" - } - ], - "description": "A flexible FTP and SSL-FTP client for PHP. This lib provides helpers easy to use to manage the remote files.", - "homepage": "https://github.com/Nicolab/php-ftp-client", - "keywords": [ - "file", - "ftp", - "helper", - "lib", - "server", - "sftp", - "ssl", - "ssl-ftp" - ] - }, - { - "name": "phpmailer/phpmailer", - "version": "v6.1.7", - "version_normalized": "6.1.7.0", - "source": { - "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0", - "reference": "2c2370ba3df7034f9eb7b8f387c97b52b2ba5ad0", - "shasum": "", - "mirrors": [ + ], + "description": "A flexible FTP and SSL-FTP client for PHP. This lib provides helpers easy to use to manage the remote files.", + "homepage": "https://github.com/Nicolab/php-ftp-client", + "keywords": [ + "file", + "ftp", + "helper", + "lib", + "server", + "sftp", + "ssl", + "ssl-ftp" + ], + "support": { + "source": "https://github.com/Nicolab/php-ftp-client/tree/v1.5.5" + }, + "install-path": "../nicolab/php-ftp-client" + }, + { + "name": "phpmailer/phpmailer", + "version": "v6.4.0", + "version_normalized": "6.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "050d430203105c27c30efd1dce7aa421ad882d01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/050d430203105c27c30efd1dce7aa421ad882d01", + "reference": "050d430203105c27c30efd1dce7aa421ad882d01", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "php": ">=5.5.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.2", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.5.6", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "suggest": { + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + }, + "time": "2021-03-31T20:06:42+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" } - ] - }, - "require": { - "ext-ctype": "*", - "ext-filter": "*", - "php": ">=5.5.0" - }, - "require-dev": { - "doctrine/annotations": "^1.2", - "friendsofphp/php-cs-fixer": "^2.2", - "phpunit/phpunit": "^4.8 || ^5.7" - }, - "suggest": { - "ext-mbstring": "Needed to send email in multibyte encoding charset", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" - }, - "time": "2020-07-14T18:50:27+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-only" - ], - "authors": [ - { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" - }, - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" - }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" - }, - { - "name": "Brent R. Matzelle" - } - ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "funding": [ - { - "url": "https://github.com/synchro", - "type": "github" - } - ] - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "", - "mirrors": [ + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.4.0" + }, + "funding": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "url": "https://github.com/Synchro", + "type": "github" } - ] - }, - "require": { - "php": ">=5.3.0" - }, - "time": "2016-08-06T14:39:51+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ] - }, - { - "name": "qcloud/cos-sdk-v5", - "version": "v1.3.4", - "version_normalized": "1.3.4.0", - "source": { - "type": "git", - "url": "https://github.com/tencentyun/cos-php-sdk-v5.git", - "reference": "1b32aa422f6dffe4ea411e5095e4b0da9135551b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tencentyun/cos-php-sdk-v5/zipball/1b32aa422f6dffe4ea411e5095e4b0da9135551b", - "reference": "1b32aa422f6dffe4ea411e5095e4b0da9135551b", - "shasum": "", - "mirrors": [ + ], + "install-path": "../phpmailer/phpmailer" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2016-08-06T14:39:51+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" } - ] - }, - "require": { - "guzzle/guzzle": "~3.7", - "php": ">=5.3.0" - }, - "time": "2019-09-02T12:08:44+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-0": { - "Qcloud\\Cos\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "yaozongyou", - "email": "yaozongyou@vip.qq.com" - }, - { - "name": "lewzylu", - "email": "327874225@qq.com" - } - ], - "description": "PHP SDK for QCloud COS", - "keywords": [ - "cos", - "php", - "qcloud" - ] - }, - { - "name": "qiniu/php-sdk", - "version": "v7.2.10", - "version_normalized": "7.2.10.0", - "source": { - "type": "git", - "url": "https://github.com/qiniu/php-sdk.git", - "reference": "d89987163f560ebf9dfa5bb25de9bd9b1a3b2bd8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/qiniu/php-sdk/zipball/d89987163f560ebf9dfa5bb25de9bd9b1a3b2bd8", - "reference": "d89987163f560ebf9dfa5bb25de9bd9b1a3b2bd8", - "shasum": "", - "mirrors": [ + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "install-path": "../psr/http-message" + }, + { + "name": "qcloud/cos-sdk-v5", + "version": "v1.3.4", + "version_normalized": "1.3.4.0", + "source": { + "type": "git", + "url": "https://github.com/tencentyun/cos-php-sdk-v5.git", + "reference": "1b32aa422f6dffe4ea411e5095e4b0da9135551b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tencentyun/cos-php-sdk-v5/zipball/1b32aa422f6dffe4ea411e5095e4b0da9135551b", + "reference": "1b32aa422f6dffe4ea411e5095e4b0da9135551b", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "guzzle/guzzle": "~3.7", + "php": ">=5.3.0" + }, + "time": "2019-09-02T12:08:44+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Qcloud\\Cos\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "yaozongyou", + "email": "yaozongyou@vip.qq.com" + }, + { + "name": "lewzylu", + "email": "327874225@qq.com" } - ] - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.3" - }, - "time": "2019-10-28T10:23:23+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Qiniu\\": "src/Qiniu" - }, - "files": [ - "src/Qiniu/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Qiniu", - "email": "sdk@qiniu.com", - "homepage": "http://www.qiniu.com" - } - ], - "description": "Qiniu Resource (Cloud) Storage SDK for PHP", - "homepage": "http://developer.qiniu.com/", - "keywords": [ - "cloud", - "qiniu", - "sdk", - "storage" - ] - }, - { - "name": "ralouphie/getallheaders", - "version": "3.0.3", - "version_normalized": "3.0.3.0", - "source": { - "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", - "shasum": "", - "mirrors": [ + ], + "description": "PHP SDK for QCloud COS", + "keywords": [ + "cos", + "php", + "qcloud" + ], + "install-path": "../qcloud/cos-sdk-v5" + }, + { + "name": "qiniu/php-sdk", + "version": "v7.3.0", + "version_normalized": "7.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/qiniu/php-sdk.git", + "reference": "0a461e13b09545b23df361843c6a65fdd3a26426" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/qiniu/php-sdk/zipball/0a461e13b09545b23df361843c6a65fdd3a26426", + "reference": "0a461e13b09545b23df361843c6a65fdd3a26426", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.3" + }, + "time": "2020-09-24T07:31:29+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Qiniu\\": "src/Qiniu" + }, + "files": [ + "src/Qiniu/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "Qiniu", + "email": "sdk@qiniu.com", + "homepage": "http://www.qiniu.com" } - ] - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" - }, - "time": "2019-03-08T08:55:37+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "src/getallheaders.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" - } - ], - "description": "A polyfill for getallheaders." - }, - { - "name": "symfony/event-dispatcher", - "version": "v2.8.52", - "version_normalized": "2.8.52.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a77e974a5fecb4398833b0709210e3d5e334ffb0", - "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0", - "shasum": "", - "mirrors": [ + ], + "description": "Qiniu Resource (Cloud) Storage SDK for PHP", + "homepage": "http://developer.qiniu.com/", + "keywords": [ + "cloud", + "qiniu", + "sdk", + "storage" + ], + "support": { + "issues": "https://github.com/qiniu/php-sdk/issues", + "source": "https://github.com/qiniu/php-sdk/tree/v7.3.0" + }, + "install-path": "../qiniu/php-sdk" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "version_normalized": "3.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "time": "2019-03-08T08:55:37+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" } - ] - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.6|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "time": "2018-11-21T14:20:20+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://repo.packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "https://symfony.com" - }, - { - "name": "symfony/polyfill-intl-idn", - "version": "v1.17.1", - "version_normalized": "1.17.1.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "a57f8161502549a742a63c09f0a604997bf47027" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a57f8161502549a742a63c09f0a604997bf47027", - "reference": "a57f8161502549a742a63c09f0a604997bf47027", - "shasum": "", - "mirrors": [ + ], + "description": "A polyfill for getallheaders.", + "install-path": "../ralouphie/getallheaders" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.8.52", + "version_normalized": "2.8.52.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a77e974a5fecb4398833b0709210e3d5e334ffb0", + "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^2.0.5|~3.0.0", + "symfony/dependency-injection": "~2.6|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/stopwatch": "~2.3|~3.0.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "time": "2018-11-21T14:20:20+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://repo.packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } - ] - }, - "require": { - "php": ">=5.3.3", - "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php72": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "time": "2020-06-06T08:46:27+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.17-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "idn", - "intl", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.17.1", - "version_normalized": "1.17.1.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "7110338d81ce1cbc3e273136e4574663627037a7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7110338d81ce1cbc3e273136e4574663627037a7", - "reference": "7110338d81ce1cbc3e273136e4574663627037a7", - "shasum": "", - "mirrors": [ + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "install-path": "../symfony/event-dispatcher" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.22.1", + "version_normalized": "1.22.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "2d63434d922daf7da8dd863e7907e67ee3031483" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/2d63434d922daf7da8dd863e7907e67ee3031483", + "reference": "2d63434d922daf7da8dd863e7907e67ee3031483", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-intl-normalizer": "^1.10", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "time": "2021-01-22T09:19:47+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } - ] - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "time": "2020-06-06T08:46:27+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.17-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.17.1", - "version_normalized": "1.17.1.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "3d9c70ff1b9f6bb618f9954b2f7f760220c2b38a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/3d9c70ff1b9f6bb618f9954b2f7f760220c2b38a", - "reference": "3d9c70ff1b9f6bb618f9954b2f7f760220c2b38a", - "shasum": "", - "mirrors": [ + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } - ] - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2020-06-06T08:46:27+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.17-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "topthink/framework", - "version": "v5.1.39", - "version_normalized": "5.1.39.0", - "source": { - "type": "git", - "url": "https://github.com/top-think/framework.git", - "reference": "5762858f3d58faafb3a39427f8788884b2927007" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/top-think/framework/zipball/5762858f3d58faafb3a39427f8788884b2927007", - "reference": "5762858f3d58faafb3a39427f8788884b2927007", - "shasum": "", - "mirrors": [ + ], + "install-path": "../symfony/polyfill-intl-idn" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.22.1", + "version_normalized": "1.22.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248", + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "time": "2021-01-22T09:19:47+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } - ] - }, - "require": { - "php": ">=5.6.0", - "topthink/think-installer": "2.*" - }, - "require-dev": { - "johnkary/phpunit-speedtrap": "^1.0", - "mikey179/vfsstream": "~1.6", - "phpdocumentor/reflection-docblock": "^2.0", - "phploc/phploc": "2.*", - "phpunit/phpunit": "^5.0|^6.0", - "sebastian/phpcpd": "2.*", - "squizlabs/php_codesniffer": "2.*" - }, - "time": "2019-11-17T23:22:02+00:00", - "type": "think-framework", - "installation-source": "dist", - "notification-url": "https://repo.packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "liu21st", - "email": "liu21st@gmail.com" - }, - { - "name": "yunwuxin", - "email": "448901948@qq.com" - } - ], - "description": "the new thinkphp framework", - "homepage": "http://thinkphp.cn/", - "keywords": [ - "framework", - "orm", - "thinkphp" - ] - }, - { - "name": "topthink/think-captcha", - "version": "v2.0.2", - "version_normalized": "2.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/top-think/think-captcha.git", - "reference": "54c8a51552f99ff9ea89ea9c272383a8f738ceee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/top-think/think-captcha/zipball/54c8a51552f99ff9ea89ea9c272383a8f738ceee", - "reference": "54c8a51552f99ff9ea89ea9c272383a8f738ceee", - "shasum": "", - "mirrors": [ + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } - ] - }, - "require": { - "topthink/framework": "5.1.*" - }, - "time": "2017-12-31T16:37:49+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "think\\captcha\\": "src/" - }, - "files": [ - "src/helper.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "yunwuxin", - "email": "448901948@qq.com" - } - ], - "description": "captcha package for thinkphp5" - }, - { - "name": "topthink/think-image", - "version": "v1.0.7", - "version_normalized": "1.0.7.0", - "source": { - "type": "git", - "url": "https://github.com/top-think/think-image.git", - "reference": "8586cf47f117481c6d415b20f7dedf62e79d5512" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/top-think/think-image/zipball/8586cf47f117481c6d415b20f7dedf62e79d5512", - "reference": "8586cf47f117481c6d415b20f7dedf62e79d5512", - "shasum": "", - "mirrors": [ + ], + "install-path": "../symfony/polyfill-intl-normalizer" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.22.1", + "version_normalized": "1.22.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1" + }, + "time": "2021-01-07T16:49:33+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } - ] - }, - "require": { - "ext-gd": "*" - }, - "require-dev": { - "phpunit/phpunit": "4.8.*", - "topthink/framework": "^5.0" - }, - "time": "2016-09-29T06:05:43+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "think\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "yunwuxin", - "email": "448901948@qq.com" - } - ], - "description": "The ThinkPHP5 Image Package" - }, - { - "name": "topthink/think-installer", - "version": "v2.0.0", - "version_normalized": "2.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/top-think/think-installer.git", - "reference": "f5400a12c60e513911aef41fe443fa6920952675" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/top-think/think-installer/zipball/f5400a12c60e513911aef41fe443fa6920952675", - "reference": "f5400a12c60e513911aef41fe443fa6920952675", - "shasum": "", - "mirrors": [ + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } - ] - }, - "require": { - "composer-plugin-api": "^1.0" - }, - "require-dev": { - "composer/composer": "1.0.*@dev" - }, - "time": "2018-05-11T06:45:42+00:00", - "type": "composer-plugin", - "extra": { - "class": "think\\composer\\Plugin" - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "think\\composer\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "yunwuxin", - "email": "448901948@qq.com" - } - ] - }, - { - "name": "upyun/sdk", - "version": "3.5.0", - "version_normalized": "3.5.0.0", - "source": { - "type": "git", - "url": "https://github.com/upyun/php-sdk.git", - "reference": "c9f824626552c32b987de4ac7f136e0e21cca962" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/upyun/php-sdk/zipball/c9f824626552c32b987de4ac7f136e0e21cca962", - "reference": "c9f824626552c32b987de4ac7f136e0e21cca962", - "shasum": "", - "mirrors": [ + ], + "install-path": "../symfony/polyfill-php72" + }, + { + "name": "topthink/framework", + "version": "v5.1.41", + "version_normalized": "5.1.41.0", + "source": { + "type": "git", + "url": "https://github.com/top-think/framework.git", + "reference": "7137741a323a4a60cfca334507cd1812fac91bb2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/framework/zipball/7137741a323a4a60cfca334507cd1812fac91bb2", + "reference": "7137741a323a4a60cfca334507cd1812fac91bb2", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.6.0", + "topthink/think-installer": "2.*" + }, + "require-dev": { + "johnkary/phpunit-speedtrap": "^1.0", + "mikey179/vfsstream": "~1.6", + "phpdocumentor/reflection-docblock": "^2.0", + "phploc/phploc": "2.*", + "phpunit/phpunit": "^5.0|^6.0", + "sebastian/phpcpd": "2.*", + "squizlabs/php_codesniffer": "2.*" + }, + "time": "2021-01-11T02:51:29+00:00", + "type": "think-framework", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true + "name": "liu21st", + "email": "liu21st@gmail.com" + }, + { + "name": "yunwuxin", + "email": "448901948@qq.com" } - ] - }, - "require": { - "ext-curl": "*", - "guzzlehttp/guzzle": "~6.0", - "php": ">=5.5.0" - }, - "require-dev": { - "consolidation/robo": "^1.0", - "phpdocumentor/phpdocumentor": "^2.9", - "phpunit/phpunit": "~4.0" - }, - "time": "2020-04-22T06:08:39+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Upyun\\": "src/Upyun/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "lfeng", - "email": "bonevv@gmail.com" - }, - { - "name": "lvtongda", - "email": "riyao.lyu@gmail.com" - }, - { - "name": "totoleo", - "email": "totoleo@163.com" - }, - { - "name": "sabakugaara", - "email": "senellise@gmail.com" - } - ], - "description": "UPYUN sdk for php", - "homepage": "https://github.com/upyun/php-sdk/", - "keywords": [ - "sdk", - "upyun" - ] - } -] + ], + "description": "the new thinkphp framework", + "homepage": "http://thinkphp.cn/", + "keywords": [ + "framework", + "orm", + "thinkphp" + ], + "support": { + "issues": "https://github.com/top-think/framework/issues", + "source": "https://github.com/top-think/framework/tree/v5.1.41" + }, + "install-path": "../../thinkphp" + }, + { + "name": "topthink/think-captcha", + "version": "v2.0.2", + "version_normalized": "2.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-captcha.git", + "reference": "54c8a51552f99ff9ea89ea9c272383a8f738ceee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-captcha/zipball/54c8a51552f99ff9ea89ea9c272383a8f738ceee", + "reference": "54c8a51552f99ff9ea89ea9c272383a8f738ceee", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "topthink/framework": "5.1.*" + }, + "time": "2017-12-31T16:37:49+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "think\\captcha\\": "src/" + }, + "files": [ + "src/helper.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "captcha package for thinkphp5", + "install-path": "../topthink/think-captcha" + }, + { + "name": "topthink/think-image", + "version": "v1.0.7", + "version_normalized": "1.0.7.0", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-image.git", + "reference": "8586cf47f117481c6d415b20f7dedf62e79d5512" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-image/zipball/8586cf47f117481c6d415b20f7dedf62e79d5512", + "reference": "8586cf47f117481c6d415b20f7dedf62e79d5512", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-gd": "*" + }, + "require-dev": { + "phpunit/phpunit": "4.8.*", + "topthink/framework": "^5.0" + }, + "time": "2016-09-29T06:05:43+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "think\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "The ThinkPHP5 Image Package", + "install-path": "../topthink/think-image" + }, + { + "name": "topthink/think-installer", + "version": "v2.0.5", + "version_normalized": "2.0.5.0", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-installer.git", + "reference": "38ba647706e35d6704b5d370c06f8a160b635f88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-installer/zipball/38ba647706e35d6704b5d370c06f8a160b635f88", + "reference": "38ba647706e35d6704b5d370c06f8a160b635f88", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "composer-plugin-api": "^1.0||^2.0" + }, + "require-dev": { + "composer/composer": "^1.0||^2.0" + }, + "time": "2021-01-14T12:12:14+00:00", + "type": "composer-plugin", + "extra": { + "class": "think\\composer\\Plugin" + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "think\\composer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "support": { + "issues": "https://github.com/top-think/think-installer/issues", + "source": "https://github.com/top-think/think-installer/tree/v2.0.5" + }, + "install-path": "../topthink/think-installer" + }, + { + "name": "upyun/sdk", + "version": "3.5.0", + "version_normalized": "3.5.0.0", + "source": { + "type": "git", + "url": "https://github.com/upyun/php-sdk.git", + "reference": "c9f824626552c32b987de4ac7f136e0e21cca962" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/upyun/php-sdk/zipball/c9f824626552c32b987de4ac7f136e0e21cca962", + "reference": "c9f824626552c32b987de4ac7f136e0e21cca962", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-curl": "*", + "guzzlehttp/guzzle": "~6.0", + "php": ">=5.5.0" + }, + "require-dev": { + "consolidation/robo": "^1.0", + "phpdocumentor/phpdocumentor": "^2.9", + "phpunit/phpunit": "~4.0" + }, + "time": "2020-04-22T06:08:39+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Upyun\\": "src/Upyun/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "lfeng", + "email": "bonevv@gmail.com" + }, + { + "name": "lvtongda", + "email": "riyao.lyu@gmail.com" + }, + { + "name": "totoleo", + "email": "totoleo@163.com" + }, + { + "name": "sabakugaara", + "email": "senellise@gmail.com" + } + ], + "description": "UPYUN sdk for php", + "homepage": "https://github.com/upyun/php-sdk/", + "keywords": [ + "sdk", + "upyun" + ], + "install-path": "../upyun/sdk" + } + ], + "dev": true +} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php new file mode 100644 index 000000000..08eb12da4 --- /dev/null +++ b/vendor/composer/installed.php @@ -0,0 +1,365 @@ + + array ( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'aliases' => + array ( + ), + 'reference' => '1a4a317fafac750db4742672a1501a2476d219c9', + 'name' => 'wisp-x/lsky-pro', + ), + 'versions' => + array ( + 'aliyuncs/oss-sdk-php' => + array ( + 'pretty_version' => 'v2.4.1', + 'version' => '2.4.1.0', + 'aliases' => + array ( + ), + 'reference' => '492866331b7bafaac09506cf42f351b7e9e63766', + ), + 'guzzle/batch' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/cache' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/common' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/guzzle' => + array ( + 'pretty_version' => 'v3.9.3', + 'version' => '3.9.3.0', + 'aliases' => + array ( + ), + 'reference' => '0645b70d953bc1c067bbc8d5bc53194706b628d9', + ), + 'guzzle/http' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/inflection' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/iterator' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/log' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/parser' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-async' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-backoff' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-cache' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-cookie' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-curlauth' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-error-response' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-history' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-log' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-md5' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-mock' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/plugin-oauth' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/service' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzle/stream' => + array ( + 'replaced' => + array ( + 0 => 'v3.9.3', + ), + ), + 'guzzlehttp/guzzle' => + array ( + 'pretty_version' => '6.5.5', + 'version' => '6.5.5.0', + 'aliases' => + array ( + ), + 'reference' => '9d4290de1cfd701f38099ef7e183b64b4b7b0c5e', + ), + 'guzzlehttp/promises' => + array ( + 'pretty_version' => '1.4.1', + 'version' => '1.4.1.0', + 'aliases' => + array ( + ), + 'reference' => '8e7d04f1f6450fef59366c399cfad4b9383aa30d', + ), + 'guzzlehttp/psr7' => + array ( + 'pretty_version' => '1.8.1', + 'version' => '1.8.1.0', + 'aliases' => + array ( + ), + 'reference' => '35ea11d335fd638b5882ff1725228b3d35496ab1', + ), + 'nicolab/php-ftp-client' => + array ( + 'pretty_version' => 'v1.5.5', + 'version' => '1.5.5.0', + 'aliases' => + array ( + ), + 'reference' => '3c34d6beb4e31f29756ab92bc8436cd761f345d3', + ), + 'phpmailer/phpmailer' => + array ( + 'pretty_version' => 'v6.4.0', + 'version' => '6.4.0.0', + 'aliases' => + array ( + ), + 'reference' => '050d430203105c27c30efd1dce7aa421ad882d01', + ), + 'psr/http-message' => + array ( + 'pretty_version' => '1.0.1', + 'version' => '1.0.1.0', + 'aliases' => + array ( + ), + 'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363', + ), + 'psr/http-message-implementation' => + array ( + 'provided' => + array ( + 0 => '1.0', + ), + ), + 'qcloud/cos-sdk-v5' => + array ( + 'pretty_version' => 'v1.3.4', + 'version' => '1.3.4.0', + 'aliases' => + array ( + ), + 'reference' => '1b32aa422f6dffe4ea411e5095e4b0da9135551b', + ), + 'qiniu/php-sdk' => + array ( + 'pretty_version' => 'v7.3.0', + 'version' => '7.3.0.0', + 'aliases' => + array ( + ), + 'reference' => '0a461e13b09545b23df361843c6a65fdd3a26426', + ), + 'ralouphie/getallheaders' => + array ( + 'pretty_version' => '3.0.3', + 'version' => '3.0.3.0', + 'aliases' => + array ( + ), + 'reference' => '120b605dfeb996808c31b6477290a714d356e822', + ), + 'symfony/event-dispatcher' => + array ( + 'pretty_version' => 'v2.8.52', + 'version' => '2.8.52.0', + 'aliases' => + array ( + ), + 'reference' => 'a77e974a5fecb4398833b0709210e3d5e334ffb0', + ), + 'symfony/polyfill-intl-idn' => + array ( + 'pretty_version' => 'v1.22.1', + 'version' => '1.22.1.0', + 'aliases' => + array ( + ), + 'reference' => '2d63434d922daf7da8dd863e7907e67ee3031483', + ), + 'symfony/polyfill-intl-normalizer' => + array ( + 'pretty_version' => 'v1.22.1', + 'version' => '1.22.1.0', + 'aliases' => + array ( + ), + 'reference' => '43a0283138253ed1d48d352ab6d0bdb3f809f248', + ), + 'symfony/polyfill-php72' => + array ( + 'pretty_version' => 'v1.22.1', + 'version' => '1.22.1.0', + 'aliases' => + array ( + ), + 'reference' => 'cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9', + ), + 'topthink/framework' => + array ( + 'pretty_version' => 'v5.1.41', + 'version' => '5.1.41.0', + 'aliases' => + array ( + ), + 'reference' => '7137741a323a4a60cfca334507cd1812fac91bb2', + ), + 'topthink/think-captcha' => + array ( + 'pretty_version' => 'v2.0.2', + 'version' => '2.0.2.0', + 'aliases' => + array ( + ), + 'reference' => '54c8a51552f99ff9ea89ea9c272383a8f738ceee', + ), + 'topthink/think-image' => + array ( + 'pretty_version' => 'v1.0.7', + 'version' => '1.0.7.0', + 'aliases' => + array ( + ), + 'reference' => '8586cf47f117481c6d415b20f7dedf62e79d5512', + ), + 'topthink/think-installer' => + array ( + 'pretty_version' => 'v2.0.5', + 'version' => '2.0.5.0', + 'aliases' => + array ( + ), + 'reference' => '38ba647706e35d6704b5d370c06f8a160b635f88', + ), + 'upyun/sdk' => + array ( + 'pretty_version' => '3.5.0', + 'version' => '3.5.0.0', + 'aliases' => + array ( + ), + 'reference' => 'c9f824626552c32b987de4ac7f136e0e21cca962', + ), + 'wisp-x/lsky-pro' => + array ( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'aliases' => + array ( + ), + 'reference' => '1a4a317fafac750db4742672a1501a2476d219c9', + ), + ), +); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php new file mode 100644 index 000000000..84ce05e46 --- /dev/null +++ b/vendor/composer/platform_check.php @@ -0,0 +1,27 @@ += 70100)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.0". You are running ' . PHP_VERSION . '.'; +} + +$missingExtensions = array(); +extension_loaded('ctype') || $missingExtensions[] = 'ctype'; +extension_loaded('curl') || $missingExtensions[] = 'curl'; +extension_loaded('filter') || $missingExtensions[] = 'filter'; +extension_loaded('ftp') || $missingExtensions[] = 'ftp'; +extension_loaded('gd') || $missingExtensions[] = 'gd'; +extension_loaded('hash') || $missingExtensions[] = 'hash'; +extension_loaded('json') || $missingExtensions[] = 'json'; + +if ($missingExtensions) { + $issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', $missingExtensions); +} + +if ($issues) { + echo 'Composer detected issues in your platform:' . "\n\n" . implode("\n", $issues); + exit(104); +} diff --git a/vendor/guzzlehttp/promises/CHANGELOG.md b/vendor/guzzlehttp/promises/CHANGELOG.md index 551929f6b..14796c472 100644 --- a/vendor/guzzlehttp/promises/CHANGELOG.md +++ b/vendor/guzzlehttp/promises/CHANGELOG.md @@ -1,5 +1,24 @@ # CHANGELOG +## 1.4.1 - 2021-02-18 + +- Fixed `each_limit` skipping promises and failing + +## 1.4.0 - 2020-09-30 + +### Added + +- Support for PHP 8 +- Optional `$recursive` flag to `all` +- Replaced functions by static methods + +### Fixed + +- Fix empty `each` processing +- Fix promise handling for Iterators of non-unique keys +- Fixed `method_exists` crashes on PHP 8 +- Memory leak on exceptions + ## 1.3.1 - 2016-12-20 diff --git a/vendor/guzzlehttp/promises/README.md b/vendor/guzzlehttp/promises/README.md index 7b607e28b..a95c60594 100644 --- a/vendor/guzzlehttp/promises/README.md +++ b/vendor/guzzlehttp/promises/README.md @@ -26,7 +26,7 @@ for a general introduction to promises. - Promises can be cancelled. - Works with any object that has a `then` function. - C# style async/await coroutine promises using - `GuzzleHttp\Promise\coroutine()`. + `GuzzleHttp\Promise\Coroutine::of()`. # Quick start @@ -88,7 +88,7 @@ $promise }); // Resolving the promise triggers the $onFulfilled callbacks and outputs -// "Hello, reader". +// "Hello, reader." $promise->resolve('reader.'); ``` @@ -150,7 +150,7 @@ use GuzzleHttp\Promise\Promise; $promise = new Promise(); $promise->then(null, function ($reason) { - throw new \Exception($reason); + throw new Exception($reason); })->then(null, function ($reason) { assert($reason->getMessage() === 'Error!'); }); @@ -182,7 +182,6 @@ invoked using the value returned from the `$onRejected` callback. ```php use GuzzleHttp\Promise\Promise; -use GuzzleHttp\Promise\RejectedPromise; $promise = new Promise(); $promise @@ -220,7 +219,7 @@ the promise is rejected with the exception and the exception is thrown. ```php $promise = new Promise(function () use (&$promise) { - throw new \Exception('foo'); + throw new Exception('foo'); }); $promise->wait(); // throws the exception. @@ -397,7 +396,7 @@ $deferred = new React\Promise\Deferred(); $reactPromise = $deferred->promise(); // Create a Guzzle promise that is fulfilled with a React promise. -$guzzlePromise = new \GuzzleHttp\Promise\Promise(); +$guzzlePromise = new GuzzleHttp\Promise\Promise(); $guzzlePromise->then(function ($value) use ($reactPromise) { // Do something something with the value... // Return the React promise @@ -424,7 +423,7 @@ instance. ```php // Get the global task queue -$queue = \GuzzleHttp\Promise\queue(); +$queue = GuzzleHttp\Promise\Utils::queue(); $queue->run(); ``` @@ -502,3 +501,32 @@ $promise->then(function ($value) { echo $value; }); $promise->resolve('foo'); // prints "foo" ``` + + +## Upgrading from Function API + +A static API was first introduced in 1.4.0, in order to mitigate problems with functions conflicting between global and local copies of the package. The function API will be removed in 2.0.0. A migration table has been provided here for your convenience: + +| Original Function | Replacement Method | +|----------------|----------------| +| `queue` | `Utils::queue` | +| `task` | `Utils::task` | +| `promise_for` | `Create::promiseFor` | +| `rejection_for` | `Create::rejectionFor` | +| `exception_for` | `Create::exceptionFor` | +| `iter_for` | `Create::iterFor` | +| `inspect` | `Utils::inspect` | +| `inspect_all` | `Utils::inspectAll` | +| `unwrap` | `Utils::unwrap` | +| `all` | `Utils::all` | +| `some` | `Utils::some` | +| `any` | `Utils::any` | +| `settle` | `Utils::settle` | +| `each` | `Each::of` | +| `each_limit` | `Each::ofLimit` | +| `each_limit_all` | `Each::ofLimitAll` | +| `!is_fulfilled` | `Is::pending` | +| `is_fulfilled` | `Is::fulfilled` | +| `is_rejected` | `Is::rejected` | +| `is_settled` | `Is::settled` | +| `coroutine` | `Coroutine::of` | diff --git a/vendor/guzzlehttp/promises/composer.json b/vendor/guzzlehttp/promises/composer.json index ec41a61e6..db44d9e3f 100644 --- a/vendor/guzzlehttp/promises/composer.json +++ b/vendor/guzzlehttp/promises/composer.json @@ -11,10 +11,10 @@ } ], "require": { - "php": ">=5.5.0" + "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "^4.0" + "symfony/phpunit-bridge": "^4.4 || ^5.1" }, "autoload": { "psr-4": { @@ -22,9 +22,14 @@ }, "files": ["src/functions_include.php"] }, + "autoload-dev": { + "psr-4": { + "GuzzleHttp\\Promise\\Tests\\": "tests/" + } + }, "scripts": { - "test": "vendor/bin/phpunit", - "test-ci": "vendor/bin/phpunit --coverage-text" + "test": "vendor/bin/simple-phpunit", + "test-ci": "vendor/bin/simple-phpunit --coverage-text" }, "extra": { "branch-alias": { diff --git a/vendor/guzzlehttp/promises/src/AggregateException.php b/vendor/guzzlehttp/promises/src/AggregateException.php index 6a5690c37..d2b5712b9 100644 --- a/vendor/guzzlehttp/promises/src/AggregateException.php +++ b/vendor/guzzlehttp/promises/src/AggregateException.php @@ -1,4 +1,5 @@ currentPromise->wait(); } }); - $this->nextCoroutine($this->generator->current()); + try { + $this->nextCoroutine($this->generator->current()); + } catch (\Exception $exception) { + $this->result->reject($exception); + } catch (Throwable $throwable) { + $this->result->reject($throwable); + } + } + + /** + * Create a new coroutine. + * + * @return self + */ + public static function of(callable $generatorFn) + { + return new self($generatorFn); } public function then( @@ -108,7 +126,7 @@ public function cancel() private function nextCoroutine($yielded) { - $this->currentPromise = promise_for($yielded) + $this->currentPromise = Create::promiseFor($yielded) ->then([$this, '_handleSuccess'], [$this, '_handleFailure']); } @@ -139,7 +157,7 @@ public function _handleFailure($reason) { unset($this->currentPromise); try { - $nextYield = $this->generator->throw(exception_for($reason)); + $nextYield = $this->generator->throw(Create::exceptionFor($reason)); // The throw was caught, so keep iterating on the coroutine $this->nextCoroutine($nextYield); } catch (Exception $exception) { diff --git a/vendor/guzzlehttp/promises/src/Create.php b/vendor/guzzlehttp/promises/src/Create.php new file mode 100644 index 000000000..8d038e9c1 --- /dev/null +++ b/vendor/guzzlehttp/promises/src/Create.php @@ -0,0 +1,84 @@ +then([$promise, 'resolve'], [$promise, 'reject']); + return $promise; + } + + return new FulfilledPromise($value); + } + + /** + * Creates a rejected promise for a reason if the reason is not a promise. + * If the provided reason is a promise, then it is returned as-is. + * + * @param mixed $reason Promise or reason. + * + * @return PromiseInterface + */ + public static function rejectionFor($reason) + { + if ($reason instanceof PromiseInterface) { + return $reason; + } + + return new RejectedPromise($reason); + } + + /** + * Create an exception for a rejected promise value. + * + * @param mixed $reason + * + * @return \Exception|\Throwable + */ + public static function exceptionFor($reason) + { + if ($reason instanceof \Exception || $reason instanceof \Throwable) { + return $reason; + } + + return new RejectionException($reason); + } + + /** + * Returns an iterator for the given value. + * + * @param mixed $value + * + * @return \Iterator + */ + public static function iterFor($value) + { + if ($value instanceof \Iterator) { + return $value; + } + + if (is_array($value)) { + return new \ArrayIterator($value); + } + + return new \ArrayIterator([$value]); + } +} diff --git a/vendor/guzzlehttp/promises/src/Each.php b/vendor/guzzlehttp/promises/src/Each.php new file mode 100644 index 000000000..1dda35499 --- /dev/null +++ b/vendor/guzzlehttp/promises/src/Each.php @@ -0,0 +1,90 @@ + $onFulfilled, + 'rejected' => $onRejected + ]))->promise(); + } + + /** + * Like of, but only allows a certain number of outstanding promises at any + * given time. + * + * $concurrency may be an integer or a function that accepts the number of + * pending promises and returns a numeric concurrency limit value to allow + * for dynamic a concurrency size. + * + * @param mixed $iterable + * @param int|callable $concurrency + * @param callable $onFulfilled + * @param callable $onRejected + * + * @return PromiseInterface + */ + public static function ofLimit( + $iterable, + $concurrency, + callable $onFulfilled = null, + callable $onRejected = null + ) { + return (new EachPromise($iterable, [ + 'fulfilled' => $onFulfilled, + 'rejected' => $onRejected, + 'concurrency' => $concurrency + ]))->promise(); + } + + /** + * Like limit, but ensures that no promise in the given $iterable argument + * is rejected. If any promise is rejected, then the aggregate promise is + * rejected with the encountered rejection. + * + * @param mixed $iterable + * @param int|callable $concurrency + * @param callable $onFulfilled + * + * @return PromiseInterface + */ + public static function ofLimitAll( + $iterable, + $concurrency, + callable $onFulfilled = null + ) { + return each_limit( + $iterable, + $concurrency, + $onFulfilled, + function ($reason, $idx, PromiseInterface $aggregate) { + $aggregate->reject($reason); + } + ); + } +} diff --git a/vendor/guzzlehttp/promises/src/EachPromise.php b/vendor/guzzlehttp/promises/src/EachPromise.php index d0ddf603f..748f4712c 100644 --- a/vendor/guzzlehttp/promises/src/EachPromise.php +++ b/vendor/guzzlehttp/promises/src/EachPromise.php @@ -1,4 +1,5 @@ iterable = iter_for($iterable); + $this->iterable = Create::iterFor($iterable); if (isset($config['concurrency'])) { $this->concurrency = $config['concurrency']; @@ -65,6 +68,7 @@ public function __construct($iterable, array $config = []) } } + /** @psalm-suppress InvalidNullableReturnType */ public function promise() { if ($this->aggregate) { @@ -73,14 +77,29 @@ public function promise() try { $this->createPromise(); + /** @psalm-assert Promise $this->aggregate */ $this->iterable->rewind(); - $this->refillPending(); + if (!$this->checkIfFinished()) { + $this->refillPending(); + } } catch (\Throwable $e) { + /** + * @psalm-suppress NullReference + * @phpstan-ignore-next-line + */ $this->aggregate->reject($e); } catch (\Exception $e) { + /** + * @psalm-suppress NullReference + * @phpstan-ignore-next-line + */ $this->aggregate->reject($e); } + /** + * @psalm-suppress NullableReturnStatement + * @phpstan-ignore-next-line + */ return $this->aggregate; } @@ -89,17 +108,12 @@ private function createPromise() $this->mutex = false; $this->aggregate = new Promise(function () { reset($this->pending); - if (empty($this->pending) && !$this->iterable->valid()) { - $this->aggregate->resolve(null); - return; - } - // Consume a potentially fluctuating list of promises while // ensuring that indexes are maintained (precluding array_shift). while ($promise = current($this->pending)) { next($this->pending); $promise->wait(); - if ($this->aggregate->getState() !== PromiseInterface::PENDING) { + if (Is::settled($this->aggregate)) { return; } } @@ -109,6 +123,7 @@ private function createPromise() $clearFn = function () { $this->iterable = $this->concurrency = $this->pending = null; $this->onFulfilled = $this->onRejected = null; + $this->nextPendingIndex = 0; }; $this->aggregate->then($clearFn, $clearFn); @@ -148,22 +163,32 @@ private function addPending() return false; } - $promise = promise_for($this->iterable->current()); - $idx = $this->iterable->key(); + $promise = Create::promiseFor($this->iterable->current()); + $key = $this->iterable->key(); + + // Iterable keys may not be unique, so we use a counter to + // guarantee uniqueness + $idx = $this->nextPendingIndex++; $this->pending[$idx] = $promise->then( - function ($value) use ($idx) { + function ($value) use ($idx, $key) { if ($this->onFulfilled) { call_user_func( - $this->onFulfilled, $value, $idx, $this->aggregate + $this->onFulfilled, + $value, + $key, + $this->aggregate ); } $this->step($idx); }, - function ($reason) use ($idx) { + function ($reason) use ($idx, $key) { if ($this->onRejected) { call_user_func( - $this->onRejected, $reason, $idx, $this->aggregate + $this->onRejected, + $reason, + $key, + $this->aggregate ); } $this->step($idx); @@ -201,7 +226,7 @@ private function advanceIterator() private function step($idx) { // If the promise was already resolved, then ignore this step. - if ($this->aggregate->getState() !== PromiseInterface::PENDING) { + if (Is::settled($this->aggregate)) { return; } diff --git a/vendor/guzzlehttp/promises/src/FulfilledPromise.php b/vendor/guzzlehttp/promises/src/FulfilledPromise.php index dbbeeb9f7..98f72a62a 100644 --- a/vendor/guzzlehttp/promises/src/FulfilledPromise.php +++ b/vendor/guzzlehttp/promises/src/FulfilledPromise.php @@ -1,4 +1,5 @@ value = $value; @@ -30,11 +32,11 @@ public function then( return $this; } - $queue = queue(); + $queue = Utils::queue(); $p = new Promise([$queue, 'run']); $value = $this->value; $queue->add(static function () use ($p, $value, $onFulfilled) { - if ($p->getState() === self::PENDING) { + if (Is::pending($p)) { try { $p->resolve($onFulfilled($value)); } catch (\Throwable $e) { diff --git a/vendor/guzzlehttp/promises/src/Is.php b/vendor/guzzlehttp/promises/src/Is.php new file mode 100644 index 000000000..c3ed8d014 --- /dev/null +++ b/vendor/guzzlehttp/promises/src/Is.php @@ -0,0 +1,46 @@ +getState() === PromiseInterface::PENDING; + } + + /** + * Returns true if a promise is fulfilled or rejected. + * + * @return bool + */ + public static function settled(PromiseInterface $promise) + { + return $promise->getState() !== PromiseInterface::PENDING; + } + + /** + * Returns true if a promise is fulfilled. + * + * @return bool + */ + public static function fulfilled(PromiseInterface $promise) + { + return $promise->getState() === PromiseInterface::FULFILLED; + } + + /** + * Returns true if a promise is rejected. + * + * @return bool + */ + public static function rejected(PromiseInterface $promise) + { + return $promise->getState() === PromiseInterface::REJECTED; + } +} diff --git a/vendor/guzzlehttp/promises/src/Promise.php b/vendor/guzzlehttp/promises/src/Promise.php index 844ada073..75939057b 100644 --- a/vendor/guzzlehttp/promises/src/Promise.php +++ b/vendor/guzzlehttp/promises/src/Promise.php @@ -1,4 +1,5 @@ state === self::FULFILLED) { - return $onFulfilled - ? promise_for($this->result)->then($onFulfilled) - : promise_for($this->result); + $promise = Create::promiseFor($this->result); + return $onFulfilled ? $promise->then($onFulfilled) : $promise; } // It's either cancelled or rejected, so return a rejected promise // and immediately invoke any callbacks. - $rejection = rejection_for($this->result); + $rejection = Create::rejectionFor($this->result); return $onRejected ? $rejection->then(null, $onRejected) : $rejection; } @@ -61,19 +61,15 @@ public function wait($unwrap = true) { $this->waitIfPending(); - $inner = $this->result instanceof PromiseInterface - ? $this->result->wait($unwrap) - : $this->result; - + if ($this->result instanceof PromiseInterface) { + return $this->result->wait($unwrap); + } if ($unwrap) { - if ($this->result instanceof PromiseInterface - || $this->state === self::FULFILLED - ) { - return $inner; - } else { - // It's rejected so "unwrap" and throw an exception. - throw exception_for($inner); + if ($this->state === self::FULFILLED) { + return $this->result; } + // It's rejected so "unwrap" and throw an exception. + throw Create::exceptionFor($this->result); } } @@ -103,6 +99,7 @@ public function cancel() } // Reject the promise only if it wasn't rejected in a then callback. + /** @psalm-suppress RedundantCondition */ if ($this->state === self::PENDING) { $this->reject(new CancellationException('Promise has been cancelled')); } @@ -148,17 +145,15 @@ private function settle($state, $value) // If the value was not a settled promise or a thenable, then resolve // it in the task queue using the correct ID. - if (!method_exists($value, 'then')) { + if (!is_object($value) || !method_exists($value, 'then')) { $id = $state === self::FULFILLED ? 1 : 2; // It's a success, so resolve the handlers in the queue. - queue()->add(static function () use ($id, $value, $handlers) { + Utils::queue()->add(static function () use ($id, $value, $handlers) { foreach ($handlers as $handler) { self::callHandler($id, $value, $handler); } }); - } elseif ($value instanceof Promise - && $value->getState() === self::PENDING - ) { + } elseif ($value instanceof Promise && Is::pending($value)) { // We can just merge our handlers onto the next promise. $value->handlers = array_merge($value->handlers, $handlers); } else { @@ -184,8 +179,6 @@ static function ($reason) use ($handlers) { * @param int $index 1 (resolve) or 2 (reject). * @param mixed $value Value to pass to the callback. * @param array $handler Array of handler data (promise and callbacks). - * - * @return array Returns the next group to resolve. */ private static function callHandler($index, $value, array $handler) { @@ -194,13 +187,21 @@ private static function callHandler($index, $value, array $handler) // The promise may have been cancelled or resolved before placing // this thunk in the queue. - if ($promise->getState() !== self::PENDING) { + if (Is::settled($promise)) { return; } try { if (isset($handler[$index])) { - $promise->resolve($handler[$index]($value)); + /* + * If $f throws an exception, then $handler will be in the exception + * stack trace. Since $handler contains a reference to the callable + * itself we get a circular reference. We clear the $handler + * here to avoid that memory leak. + */ + $f = $handler[$index]; + unset($handler); + $promise->resolve($f($value)); } elseif ($index === 1) { // Forward resolution values as-is. $promise->resolve($value); @@ -224,15 +225,16 @@ private function waitIfPending() } elseif ($this->waitList) { $this->invokeWaitList(); } else { - // If there's not wait function, then reject the promise. + // If there's no wait function, then reject the promise. $this->reject('Cannot wait on a promise that has ' . 'no internal wait function. You must provide a wait ' . 'function when constructing the promise to be able to ' . 'wait on a promise.'); } - queue()->run(); + Utils::queue()->run(); + /** @psalm-suppress RedundantCondition */ if ($this->state === self::PENDING) { $this->reject('Invoking the wait callback did not resolve the promise'); } @@ -263,17 +265,13 @@ private function invokeWaitList() $this->waitList = null; foreach ($waitList as $result) { - while (true) { + do { $result->waitIfPending(); + $result = $result->result; + } while ($result instanceof Promise); - if ($result->result instanceof Promise) { - $result = $result->result; - } else { - if ($result->result instanceof PromiseInterface) { - $result->result->wait(false); - } - break; - } + if ($result instanceof PromiseInterface) { + $result->wait(false); } } } diff --git a/vendor/guzzlehttp/promises/src/PromiseInterface.php b/vendor/guzzlehttp/promises/src/PromiseInterface.php index 8f5f4b99b..e59833143 100644 --- a/vendor/guzzlehttp/promises/src/PromiseInterface.php +++ b/vendor/guzzlehttp/promises/src/PromiseInterface.php @@ -1,4 +1,5 @@ reason = $reason; @@ -30,11 +32,11 @@ public function then( return $this; } - $queue = queue(); + $queue = Utils::queue(); $reason = $this->reason; $p = new Promise([$queue, 'run']); $queue->add(static function () use ($p, $reason, $onRejected) { - if ($p->getState() === self::PENDING) { + if (Is::pending($p)) { try { // Return a resolved promise if onRejected does not throw. $p->resolve($onRejected($reason)); @@ -59,8 +61,10 @@ public function otherwise(callable $onRejected) public function wait($unwrap = true, $defaultDelivery = null) { if ($unwrap) { - throw exception_for($this->reason); + throw Create::exceptionFor($this->reason); } + + return null; } public function getState() diff --git a/vendor/guzzlehttp/promises/src/RejectionException.php b/vendor/guzzlehttp/promises/src/RejectionException.php index 07c1136da..e2f137707 100644 --- a/vendor/guzzlehttp/promises/src/RejectionException.php +++ b/vendor/guzzlehttp/promises/src/RejectionException.php @@ -1,4 +1,5 @@ run(); + * GuzzleHttp\Promise\Utils::queue()->run(); */ class TaskQueue implements TaskQueueInterface { @@ -42,8 +43,8 @@ public function add(callable $task) public function run() { - /** @var callable $task */ while ($task = array_shift($this->queue)) { + /** @var callable $task */ $task(); } } diff --git a/vendor/guzzlehttp/promises/src/TaskQueueInterface.php b/vendor/guzzlehttp/promises/src/TaskQueueInterface.php index ac8306e19..723d4d54e 100644 --- a/vendor/guzzlehttp/promises/src/TaskQueueInterface.php +++ b/vendor/guzzlehttp/promises/src/TaskQueueInterface.php @@ -1,4 +1,5 @@ + * while ($eventLoop->isRunning()) { + * GuzzleHttp\Promise\Utils::queue()->run(); + * } + * + * + * @param TaskQueueInterface $assign Optionally specify a new queue instance. + * + * @return TaskQueueInterface + */ + public static function queue(TaskQueueInterface $assign = null) + { + static $queue; + + if ($assign) { + $queue = $assign; + } elseif (!$queue) { + $queue = new TaskQueue(); + } + + return $queue; + } + + /** + * Adds a function to run in the task queue when it is next `run()` and + * returns a promise that is fulfilled or rejected with the result. + * + * @param callable $task Task function to run. + * + * @return PromiseInterface + */ + public static function task(callable $task) + { + $queue = self::queue(); + $promise = new Promise([$queue, 'run']); + $queue->add(function () use ($task, $promise) { + try { + $promise->resolve($task()); + } catch (\Throwable $e) { + $promise->reject($e); + } catch (\Exception $e) { + $promise->reject($e); + } + }); + + return $promise; + } + + /** + * Synchronously waits on a promise to resolve and returns an inspection + * state array. + * + * Returns a state associative array containing a "state" key mapping to a + * valid promise state. If the state of the promise is "fulfilled", the + * array will contain a "value" key mapping to the fulfilled value of the + * promise. If the promise is rejected, the array will contain a "reason" + * key mapping to the rejection reason of the promise. + * + * @param PromiseInterface $promise Promise or value. + * + * @return array + */ + public static function inspect(PromiseInterface $promise) + { + try { + return [ + 'state' => PromiseInterface::FULFILLED, + 'value' => $promise->wait() + ]; + } catch (RejectionException $e) { + return ['state' => PromiseInterface::REJECTED, 'reason' => $e->getReason()]; + } catch (\Throwable $e) { + return ['state' => PromiseInterface::REJECTED, 'reason' => $e]; + } catch (\Exception $e) { + return ['state' => PromiseInterface::REJECTED, 'reason' => $e]; + } + } + + /** + * Waits on all of the provided promises, but does not unwrap rejected + * promises as thrown exception. + * + * Returns an array of inspection state arrays. + * + * @see inspect for the inspection state array format. + * + * @param PromiseInterface[] $promises Traversable of promises to wait upon. + * + * @return array + */ + public static function inspectAll($promises) + { + $results = []; + foreach ($promises as $key => $promise) { + $results[$key] = inspect($promise); + } + + return $results; + } + + /** + * Waits on all of the provided promises and returns the fulfilled values. + * + * Returns an array that contains the value of each promise (in the same + * order the promises were provided). An exception is thrown if any of the + * promises are rejected. + * + * @param iterable $promises Iterable of PromiseInterface objects to wait on. + * + * @return array + * + * @throws \Exception on error + * @throws \Throwable on error in PHP >=7 + */ + public static function unwrap($promises) + { + $results = []; + foreach ($promises as $key => $promise) { + $results[$key] = $promise->wait(); + } + + return $results; + } + + /** + * Given an array of promises, return a promise that is fulfilled when all + * the items in the array are fulfilled. + * + * The promise's fulfillment value is an array with fulfillment values at + * respective positions to the original array. If any promise in the array + * rejects, the returned promise is rejected with the rejection reason. + * + * @param mixed $promises Promises or values. + * @param bool $recursive If true, resolves new promises that might have been added to the stack during its own resolution. + * + * @return PromiseInterface + */ + public static function all($promises, $recursive = false) + { + $results = []; + $promise = Each::of( + $promises, + function ($value, $idx) use (&$results) { + $results[$idx] = $value; + }, + function ($reason, $idx, Promise $aggregate) { + $aggregate->reject($reason); + } + )->then(function () use (&$results) { + ksort($results); + return $results; + }); + + if (true === $recursive) { + $promise = $promise->then(function ($results) use ($recursive, &$promises) { + foreach ($promises as $promise) { + if (Is::pending($promise)) { + return self::all($promises, $recursive); + } + } + return $results; + }); + } + + return $promise; + } + + /** + * Initiate a competitive race between multiple promises or values (values + * will become immediately fulfilled promises). + * + * When count amount of promises have been fulfilled, the returned promise + * is fulfilled with an array that contains the fulfillment values of the + * winners in order of resolution. + * + * This promise is rejected with a {@see AggregateException} if the number + * of fulfilled promises is less than the desired $count. + * + * @param int $count Total number of promises. + * @param mixed $promises Promises or values. + * + * @return PromiseInterface + */ + public static function some($count, $promises) + { + $results = []; + $rejections = []; + + return Each::of( + $promises, + function ($value, $idx, PromiseInterface $p) use (&$results, $count) { + if (Is::settled($p)) { + return; + } + $results[$idx] = $value; + if (count($results) >= $count) { + $p->resolve(null); + } + }, + function ($reason) use (&$rejections) { + $rejections[] = $reason; + } + )->then( + function () use (&$results, &$rejections, $count) { + if (count($results) !== $count) { + throw new AggregateException( + 'Not enough promises to fulfill count', + $rejections + ); + } + ksort($results); + return array_values($results); + } + ); + } + + /** + * Like some(), with 1 as count. However, if the promise fulfills, the + * fulfillment value is not an array of 1 but the value directly. + * + * @param mixed $promises Promises or values. + * + * @return PromiseInterface + */ + public static function any($promises) + { + return self::some(1, $promises)->then(function ($values) { + return $values[0]; + }); + } + + /** + * Returns a promise that is fulfilled when all of the provided promises have + * been fulfilled or rejected. + * + * The returned promise is fulfilled with an array of inspection state arrays. + * + * @see inspect for the inspection state array format. + * + * @param mixed $promises Promises or values. + * + * @return PromiseInterface + */ + public static function settle($promises) + { + $results = []; + + return Each::of( + $promises, + function ($value, $idx) use (&$results) { + $results[$idx] = ['state' => PromiseInterface::FULFILLED, 'value' => $value]; + }, + function ($reason, $idx) use (&$results) { + $results[$idx] = ['state' => PromiseInterface::REJECTED, 'reason' => $reason]; + } + )->then(function () use (&$results) { + ksort($results); + return $results; + }); + } +} diff --git a/vendor/guzzlehttp/promises/src/functions.php b/vendor/guzzlehttp/promises/src/functions.php index 4e27709af..c03d39d02 100644 --- a/vendor/guzzlehttp/promises/src/functions.php +++ b/vendor/guzzlehttp/promises/src/functions.php @@ -1,4 +1,5 @@ add(function () use ($task, $promise) { - try { - $promise->resolve($task()); - } catch (\Throwable $e) { - $promise->reject($e); - } catch (\Exception $e) { - $promise->reject($e); - } - }); - - return $promise; + return Utils::task($task); } /** @@ -62,23 +47,12 @@ function task(callable $task) * @param mixed $value Promise or value. * * @return PromiseInterface + * + * @deprecated promise_for will be removed in guzzlehttp/promises:2.0. Use Create::promiseFor instead. */ function promise_for($value) { - if ($value instanceof PromiseInterface) { - return $value; - } - - // Return a Guzzle promise that shadows the given promise. - if (method_exists($value, 'then')) { - $wfn = method_exists($value, 'wait') ? [$value, 'wait'] : null; - $cfn = method_exists($value, 'cancel') ? [$value, 'cancel'] : null; - $promise = new Promise($wfn, $cfn); - $value->then([$promise, 'resolve'], [$promise, 'reject']); - return $promise; - } - - return new FulfilledPromise($value); + return Create::promiseFor($value); } /** @@ -88,14 +62,12 @@ function promise_for($value) * @param mixed $reason Promise or reason. * * @return PromiseInterface + * + * @deprecated rejection_for will be removed in guzzlehttp/promises:2.0. Use Create::rejectionFor instead. */ function rejection_for($reason) { - if ($reason instanceof PromiseInterface) { - return $reason; - } - - return new RejectedPromise($reason); + return Create::rejectionFor($reason); } /** @@ -104,12 +76,12 @@ function rejection_for($reason) * @param mixed $reason * * @return \Exception|\Throwable + * + * @deprecated exception_for will be removed in guzzlehttp/promises:2.0. Use Create::exceptionFor instead. */ function exception_for($reason) { - return $reason instanceof \Exception || $reason instanceof \Throwable - ? $reason - : new RejectionException($reason); + return Create::exceptionFor($reason); } /** @@ -118,16 +90,12 @@ function exception_for($reason) * @param mixed $value * * @return \Iterator + * + * @deprecated iter_for will be removed in guzzlehttp/promises:2.0. Use Create::iterFor instead. */ function iter_for($value) { - if ($value instanceof \Iterator) { - return $value; - } elseif (is_array($value)) { - return new \ArrayIterator($value); - } else { - return new \ArrayIterator([$value]); - } + return Create::iterFor($value); } /** @@ -143,21 +111,12 @@ function iter_for($value) * @param PromiseInterface $promise Promise or value. * * @return array + * + * @deprecated inspect will be removed in guzzlehttp/promises:2.0. Use Utils::inspect instead. */ function inspect(PromiseInterface $promise) { - try { - return [ - 'state' => PromiseInterface::FULFILLED, - 'value' => $promise->wait() - ]; - } catch (RejectionException $e) { - return ['state' => PromiseInterface::REJECTED, 'reason' => $e->getReason()]; - } catch (\Throwable $e) { - return ['state' => PromiseInterface::REJECTED, 'reason' => $e]; - } catch (\Exception $e) { - return ['state' => PromiseInterface::REJECTED, 'reason' => $e]; - } + return Utils::inspect($promise); } /** @@ -166,19 +125,17 @@ function inspect(PromiseInterface $promise) * * Returns an array of inspection state arrays. * + * @see inspect for the inspection state array format. + * * @param PromiseInterface[] $promises Traversable of promises to wait upon. * * @return array - * @see GuzzleHttp\Promise\inspect for the inspection state array format. + * + * @deprecated inspect will be removed in guzzlehttp/promises:2.0. Use Utils::inspectAll instead. */ function inspect_all($promises) { - $results = []; - foreach ($promises as $key => $promise) { - $results[$key] = inspect($promise); - } - - return $results; + return Utils::inspectAll($promises); } /** @@ -188,20 +145,18 @@ function inspect_all($promises) * the promises were provided). An exception is thrown if any of the promises * are rejected. * - * @param mixed $promises Iterable of PromiseInterface objects to wait on. + * @param iterable $promises Iterable of PromiseInterface objects to wait on. * * @return array + * * @throws \Exception on error * @throws \Throwable on error in PHP >=7 + * + * @deprecated unwrap will be removed in guzzlehttp/promises:2.0. Use Utils::unwrap instead. */ function unwrap($promises) { - $results = []; - foreach ($promises as $key => $promise) { - $results[$key] = $promise->wait(); - } - - return $results; + return Utils::unwrap($promises); } /** @@ -212,25 +167,16 @@ function unwrap($promises) * respective positions to the original array. If any promise in the array * rejects, the returned promise is rejected with the rejection reason. * - * @param mixed $promises Promises or values. + * @param mixed $promises Promises or values. + * @param bool $recursive If true, resolves new promises that might have been added to the stack during its own resolution. * * @return PromiseInterface + * + * @deprecated all will be removed in guzzlehttp/promises:2.0. Use Utils::all instead. */ -function all($promises) +function all($promises, $recursive = false) { - $results = []; - return each( - $promises, - function ($value, $idx) use (&$results) { - $results[$idx] = $value; - }, - function ($reason, $idx, Promise $aggregate) { - $aggregate->reject($reason); - } - )->then(function () use (&$results) { - ksort($results); - return $results; - }); + return Utils::all($promises, $recursive); } /** @@ -241,45 +187,19 @@ function ($reason, $idx, Promise $aggregate) { * fulfilled with an array that contains the fulfillment values of the winners * in order of resolution. * - * This prommise is rejected with a {@see GuzzleHttp\Promise\AggregateException} - * if the number of fulfilled promises is less than the desired $count. + * This promise is rejected with a {@see AggregateException} if the number of + * fulfilled promises is less than the desired $count. * * @param int $count Total number of promises. * @param mixed $promises Promises or values. * * @return PromiseInterface + * + * @deprecated some will be removed in guzzlehttp/promises:2.0. Use Utils::some instead. */ function some($count, $promises) { - $results = []; - $rejections = []; - - return each( - $promises, - function ($value, $idx, PromiseInterface $p) use (&$results, $count) { - if ($p->getState() !== PromiseInterface::PENDING) { - return; - } - $results[$idx] = $value; - if (count($results) >= $count) { - $p->resolve(null); - } - }, - function ($reason) use (&$rejections) { - $rejections[] = $reason; - } - )->then( - function () use (&$results, &$rejections, $count) { - if (count($results) !== $count) { - throw new AggregateException( - 'Not enough promises to fulfill count', - $rejections - ); - } - ksort($results); - return array_values($results); - } - ); + return Utils::some($count, $promises); } /** @@ -289,10 +209,12 @@ function () use (&$results, &$rejections, $count) { * @param mixed $promises Promises or values. * * @return PromiseInterface + * + * @deprecated any will be removed in guzzlehttp/promises:2.0. Use Utils::any instead. */ function any($promises) { - return some(1, $promises)->then(function ($values) { return $values[0]; }); + return Utils::any($promises); } /** @@ -301,27 +223,17 @@ function any($promises) * * The returned promise is fulfilled with an array of inspection state arrays. * + * @see inspect for the inspection state array format. + * * @param mixed $promises Promises or values. * * @return PromiseInterface - * @see GuzzleHttp\Promise\inspect for the inspection state array format. + * + * @deprecated settle will be removed in guzzlehttp/promises:2.0. Use Utils::settle instead. */ function settle($promises) { - $results = []; - - return each( - $promises, - function ($value, $idx) use (&$results) { - $results[$idx] = ['state' => PromiseInterface::FULFILLED, 'value' => $value]; - }, - function ($reason, $idx) use (&$results) { - $results[$idx] = ['state' => PromiseInterface::REJECTED, 'reason' => $reason]; - } - )->then(function () use (&$results) { - ksort($results); - return $results; - }); + return Utils::settle($promises); } /** @@ -329,29 +241,28 @@ function ($reason, $idx) use (&$results) { * fulfilled with a null value when the iterator has been consumed or the * aggregate promise has been fulfilled or rejected. * - * $onFulfilled is a function that accepts the fulfilled value, iterator - * index, and the aggregate promise. The callback can invoke any necessary side - * effects and choose to resolve or reject the aggregate promise if needed. + * $onFulfilled is a function that accepts the fulfilled value, iterator index, + * and the aggregate promise. The callback can invoke any necessary side + * effects and choose to resolve or reject the aggregate if needed. * - * $onRejected is a function that accepts the rejection reason, iterator - * index, and the aggregate promise. The callback can invoke any necessary side - * effects and choose to resolve or reject the aggregate promise if needed. + * $onRejected is a function that accepts the rejection reason, iterator index, + * and the aggregate promise. The callback can invoke any necessary side + * effects and choose to resolve or reject the aggregate if needed. * * @param mixed $iterable Iterator or array to iterate over. * @param callable $onFulfilled * @param callable $onRejected * * @return PromiseInterface + * + * @deprecated each will be removed in guzzlehttp/promises:2.0. Use Each::of instead. */ function each( $iterable, callable $onFulfilled = null, callable $onRejected = null ) { - return (new EachPromise($iterable, [ - 'fulfilled' => $onFulfilled, - 'rejected' => $onRejected - ]))->promise(); + return Each::of($iterable, $onFulfilled, $onRejected); } /** @@ -368,6 +279,8 @@ function each( * @param callable $onRejected * * @return PromiseInterface + * + * @deprecated each_limit will be removed in guzzlehttp/promises:2.0. Use Each::ofLimit instead. */ function each_limit( $iterable, @@ -375,11 +288,7 @@ function each_limit( callable $onFulfilled = null, callable $onRejected = null ) { - return (new EachPromise($iterable, [ - 'fulfilled' => $onFulfilled, - 'rejected' => $onRejected, - 'concurrency' => $concurrency - ]))->promise(); + return Each::ofLimit($iterable, $concurrency, $onFulfilled, $onRejected); } /** @@ -392,66 +301,63 @@ function each_limit( * @param callable $onFulfilled * * @return PromiseInterface + * + * @deprecated each_limit_all will be removed in guzzlehttp/promises:2.0. Use Each::ofLimitAll instead. */ function each_limit_all( $iterable, $concurrency, callable $onFulfilled = null ) { - return each_limit( - $iterable, - $concurrency, - $onFulfilled, - function ($reason, $idx, PromiseInterface $aggregate) { - $aggregate->reject($reason); - } - ); + return Each::ofLimitAll($iterable, $concurrency, $onFulfilled); } /** * Returns true if a promise is fulfilled. * - * @param PromiseInterface $promise - * * @return bool + * + * @deprecated is_fulfilled will be removed in guzzlehttp/promises:2.0. Use Is::fulfilled instead. */ function is_fulfilled(PromiseInterface $promise) { - return $promise->getState() === PromiseInterface::FULFILLED; + return Is::fulfilled($promise); } /** * Returns true if a promise is rejected. * - * @param PromiseInterface $promise - * * @return bool + * + * @deprecated is_rejected will be removed in guzzlehttp/promises:2.0. Use Is::rejected instead. */ function is_rejected(PromiseInterface $promise) { - return $promise->getState() === PromiseInterface::REJECTED; + return Is::rejected($promise); } /** * Returns true if a promise is fulfilled or rejected. * - * @param PromiseInterface $promise - * * @return bool + * + * @deprecated is_settled will be removed in guzzlehttp/promises:2.0. Use Is::settled instead. */ function is_settled(PromiseInterface $promise) { - return $promise->getState() !== PromiseInterface::PENDING; + return Is::settled($promise); } /** - * @see Coroutine + * Create a new coroutine. * - * @param callable $generatorFn + * @see Coroutine * * @return PromiseInterface + * + * @deprecated coroutine will be removed in guzzlehttp/promises:2.0. Use Coroutine::of instead. */ function coroutine(callable $generatorFn) { - return new Coroutine($generatorFn); + return Coroutine::of($generatorFn); } diff --git a/vendor/guzzlehttp/psr7/.github/workflows/bc.yml b/vendor/guzzlehttp/psr7/.github/workflows/bc.yml new file mode 100644 index 000000000..9eaedbce7 --- /dev/null +++ b/vendor/guzzlehttp/psr7/.github/workflows/bc.yml @@ -0,0 +1,16 @@ +name: BC Check + +on: + pull_request: + +jobs: + roave-bc-check: + name: Roave BC Check + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Roave BC Check + uses: docker://nyholm/roave-bc-check-ga diff --git a/vendor/guzzlehttp/psr7/.github/workflows/ci.yml b/vendor/guzzlehttp/psr7/.github/workflows/ci.yml new file mode 100644 index 000000000..da7414e57 --- /dev/null +++ b/vendor/guzzlehttp/psr7/.github/workflows/ci.yml @@ -0,0 +1,30 @@ +name: CI + +on: + pull_request: + +jobs: + build: + name: Build + runs-on: ubuntu-latest + strategy: + max-parallel: 10 + matrix: + php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4'] + + steps: + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: 'none' + extensions: mbstring + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Install dependencies + run: composer update --no-interaction --no-progress --prefer-dist + + - name: Run tests + run: make test diff --git a/vendor/guzzlehttp/psr7/.github/workflows/integration.yml b/vendor/guzzlehttp/psr7/.github/workflows/integration.yml new file mode 100644 index 000000000..b6e0eb241 --- /dev/null +++ b/vendor/guzzlehttp/psr7/.github/workflows/integration.yml @@ -0,0 +1,37 @@ +name: Integration + +on: + pull_request: + +jobs: + + build: + name: Test + runs-on: ubuntu-latest + strategy: + max-parallel: 10 + matrix: + php: ['7.2', '7.3', '7.4', '8.0'] + + steps: + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download dependencies + uses: ramsey/composer-install@v1 + with: + composer-options: --no-interaction --prefer-dist --optimize-autoloader + + - name: Start server + run: php -S 127.0.0.1:10002 tests/Integration/server.php & + + - name: Run tests + env: + TEST_SERVER: 127.0.0.1:10002 + run: ./vendor/bin/phpunit --testsuite Integration diff --git a/vendor/guzzlehttp/psr7/.php_cs.dist b/vendor/guzzlehttp/psr7/.php_cs.dist new file mode 100644 index 000000000..e4f0bd535 --- /dev/null +++ b/vendor/guzzlehttp/psr7/.php_cs.dist @@ -0,0 +1,56 @@ +setRiskyAllowed(true) + ->setRules([ + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + 'concat_space' => ['spacing' => 'one'], + 'declare_strict_types' => false, + 'final_static_access' => true, + 'fully_qualified_strict_types' => true, + 'header_comment' => false, + 'is_null' => ['use_yoda_style' => true], + 'list_syntax' => ['syntax' => 'long'], + 'lowercase_cast' => true, + 'magic_method_casing' => true, + 'modernize_types_casting' => true, + 'multiline_comment_opening_closing' => true, + 'no_alias_functions' => true, + 'no_alternative_syntax' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_comment' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => true, + 'no_leading_import_slash' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_unset_cast' => true, + 'no_unused_imports' => true, + 'no_whitespace_in_blank_line' => true, + 'ordered_imports' => true, + 'php_unit_ordered_covers' => true, + 'php_unit_test_annotation' => ['style' => 'prefix'], + 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], + 'phpdoc_align' => ['align' => 'vertical'], + 'phpdoc_no_useless_inheritdoc' => true, + 'phpdoc_scalar' => true, + 'phpdoc_separation' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_trim' => true, + 'phpdoc_trim_consecutive_blank_line_separation' => true, + 'phpdoc_types' => true, + 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], + 'phpdoc_var_without_name' => true, + 'single_trait_insert_per_statement' => true, + 'standardize_not_equals' => true, + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->in(__DIR__.'/src') + ->in(__DIR__.'/tests') + ->name('*.php') + ) +; + +return $config; diff --git a/vendor/guzzlehttp/psr7/CHANGELOG.md b/vendor/guzzlehttp/psr7/CHANGELOG.md index 8a3743dba..a608aa419 100644 --- a/vendor/guzzlehttp/psr7/CHANGELOG.md +++ b/vendor/guzzlehttp/psr7/CHANGELOG.md @@ -9,8 +9,51 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +## [1.8.1] - 2021-03-21 -## [1.6.0] +### Fixed + +- Issue parsing IPv6 URLs +- Issue modifying ServerRequest lost all its attributes + +## [1.8.0] - 2021-03-21 + +### Added + +- Locale independent URL parsing +- Most classes got a `@final` annotation to prepare for 2.0 + +### Fixed + +- Issue when creating stream from `php://input` and curl-ext is not installed +- Broken `Utils::tryFopen()` on PHP 8 + +## [1.7.0] - 2020-09-30 + +### Added + +- Replaced functions by static methods + +### Fixed + +- Converting a non-seekable stream to a string +- Handle multiple Set-Cookie correctly +- Ignore array keys in header values when merging +- Allow multibyte characters to be parsed in `Message:bodySummary()` + +### Changed + +- Restored partial HHVM 3 support + + +## [1.6.1] - 2019-07-02 + +### Fixed + +- Accept null and bool header values again + + +## [1.6.0] - 2019-06-30 ### Added diff --git a/vendor/guzzlehttp/psr7/README.md b/vendor/guzzlehttp/psr7/README.md index c60a6a38d..acfabfdcb 100644 --- a/vendor/guzzlehttp/psr7/README.md +++ b/vendor/guzzlehttp/psr7/README.md @@ -23,11 +23,11 @@ Reads from multiple streams, one after the other. ```php use GuzzleHttp\Psr7; -$a = Psr7\stream_for('abc, '); -$b = Psr7\stream_for('123.'); +$a = Psr7\Utils::streamFor('abc, '); +$b = Psr7\Utils::streamFor('123.'); $composed = new Psr7\AppendStream([$a, $b]); -$composed->addStream(Psr7\stream_for(' Above all listen to me')); +$composed->addStream(Psr7\Utils::streamFor(' Above all listen to me')); echo $composed; // abc, 123. Above all listen to me. ``` @@ -65,7 +65,7 @@ then on disk. ```php use GuzzleHttp\Psr7; -$original = Psr7\stream_for(fopen('http://www.google.com', 'r')); +$original = Psr7\Utils::streamFor(fopen('http://www.google.com', 'r')); $stream = new Psr7\CachingStream($original); $stream->read(1024); @@ -89,7 +89,7 @@ stream becomes too full. use GuzzleHttp\Psr7; // Create an empty stream -$stream = Psr7\stream_for(); +$stream = Psr7\Utils::streamFor(); // Start dropping data when the stream has more than 10 bytes $dropping = new Psr7\DroppingStream($stream, 10); @@ -112,7 +112,7 @@ to create a concrete class for a simple extension point. use GuzzleHttp\Psr7; -$stream = Psr7\stream_for('hi'); +$stream = Psr7\Utils::streamFor('hi'); $fnStream = Psr7\FnStream::decorate($stream, [ 'rewind' => function () use ($stream) { echo 'About to rewind - '; @@ -167,7 +167,7 @@ chunks (e.g. Amazon S3's multipart upload API). ```php use GuzzleHttp\Psr7; -$original = Psr7\stream_for(fopen('/tmp/test.txt', 'r+')); +$original = Psr7\Utils::streamFor(fopen('/tmp/test.txt', 'r+')); echo $original->getSize(); // >>> 1048576 @@ -197,7 +197,7 @@ NoSeekStream wraps a stream and does not allow seeking. ```php use GuzzleHttp\Psr7; -$original = Psr7\stream_for('foo'); +$original = Psr7\Utils::streamFor('foo'); $noSeek = new Psr7\NoSeekStream($original); echo $noSeek->read(3); @@ -271,7 +271,7 @@ This decorator could be added to any existing stream and used like so: ```php use GuzzleHttp\Psr7; -$original = Psr7\stream_for('foo'); +$original = Psr7\Utils::streamFor('foo'); $eofStream = new EofCallbackStream($original, function () { echo 'EOF!'; @@ -297,228 +297,292 @@ stream from a PSR-7 stream. ```php use GuzzleHttp\Psr7\StreamWrapper; -$stream = GuzzleHttp\Psr7\stream_for('hello!'); +$stream = GuzzleHttp\Psr7\Utils::streamFor('hello!'); $resource = StreamWrapper::getResource($stream); echo fread($resource, 6); // outputs hello! ``` -# Function API +# Static API -There are various functions available under the `GuzzleHttp\Psr7` namespace. +There are various static methods available under the `GuzzleHttp\Psr7` namespace. -## `function str` +## `GuzzleHttp\Psr7\Message::toString` -`function str(MessageInterface $message)` +`public static function toString(MessageInterface $message): string` Returns the string representation of an HTTP message. ```php $request = new GuzzleHttp\Psr7\Request('GET', 'http://example.com'); -echo GuzzleHttp\Psr7\str($request); +echo GuzzleHttp\Psr7\Message::toString($request); ``` -## `function uri_for` +## `GuzzleHttp\Psr7\Message::bodySummary` -`function uri_for($uri)` +`public static function bodySummary(MessageInterface $message, int $truncateAt = 120): string|null` -This function accepts a string or `Psr\Http\Message\UriInterface` and returns a -UriInterface for the given value. If the value is already a `UriInterface`, it -is returned as-is. +Get a short summary of the message body. -```php -$uri = GuzzleHttp\Psr7\uri_for('http://example.com'); -assert($uri === GuzzleHttp\Psr7\uri_for($uri)); -``` +Will return `null` if the response is not printable. -## `function stream_for` +## `GuzzleHttp\Psr7\Message::rewindBody` -`function stream_for($resource = '', array $options = [])` +`public static function rewindBody(MessageInterface $message): void` -Create a new stream based on the input type. +Attempts to rewind a message body and throws an exception on failure. -Options is an associative array that can contain the following keys: +The body of the message will only be rewound if a call to `tell()` +returns a value other than `0`. -* - metadata: Array of custom metadata. -* - size: Size of the stream. -This method accepts the following `$resource` types: +## `GuzzleHttp\Psr7\Message::parseMessage` -- `Psr\Http\Message\StreamInterface`: Returns the value as-is. -- `string`: Creates a stream object that uses the given string as the contents. -- `resource`: Creates a stream object that wraps the given PHP stream resource. -- `Iterator`: If the provided value implements `Iterator`, then a read-only - stream object will be created that wraps the given iterable. Each time the - stream is read from, data from the iterator will fill a buffer and will be - continuously called until the buffer is equal to the requested read size. - Subsequent read calls will first read from the buffer and then call `next` - on the underlying iterator until it is exhausted. -- `object` with `__toString()`: If the object has the `__toString()` method, - the object will be cast to a string and then a stream will be returned that - uses the string value. -- `NULL`: When `null` is passed, an empty stream object is returned. -- `callable` When a callable is passed, a read-only stream object will be - created that invokes the given callable. The callable is invoked with the - number of suggested bytes to read. The callable can return any number of - bytes, but MUST return `false` when there is no more data to return. The - stream object that wraps the callable will invoke the callable until the - number of requested bytes are available. Any additional bytes will be - buffered and used in subsequent reads. +`public static function parseMessage(string $message): array` -```php -$stream = GuzzleHttp\Psr7\stream_for('foo'); -$stream = GuzzleHttp\Psr7\stream_for(fopen('/path/to/file', 'r')); +Parses an HTTP message into an associative array. -$generator = function ($bytes) { - for ($i = 0; $i < $bytes; $i++) { - yield ' '; - } -} +The array contains the "start-line" key containing the start line of +the message, "headers" key containing an associative array of header +array values, and a "body" key containing the body of the message. -$stream = GuzzleHttp\Psr7\stream_for($generator(100)); -``` +## `GuzzleHttp\Psr7\Message::parseRequestUri` -## `function parse_header` +`public static function parseRequestUri(string $path, array $headers): string` -`function parse_header($header)` +Constructs a URI for an HTTP request message. -Parse an array of header values containing ";" separated data into an array of -associative arrays representing the header key value pair data of the header. -When a parameter does not contain a value, but just contains a key, this -function will inject a key with a '' string value. +## `GuzzleHttp\Psr7\Message::parseRequest` -## `function normalize_header` +`public static function parseRequest(string $message): Request` -`function normalize_header($header)` +Parses a request message string into a request object. -Converts an array of header values that may contain comma separated headers -into an array of headers with no comma separated values. +## `GuzzleHttp\Psr7\Message::parseResponse` -## `function modify_request` +`public static function parseResponse(string $message): Response` -`function modify_request(RequestInterface $request, array $changes)` +Parses a response message string into a response object. -Clone and modify a request with the given changes. This method is useful for -reducing the number of clones needed to mutate a message. -The changes can be one of: +## `GuzzleHttp\Psr7\Header::parse` -- method: (string) Changes the HTTP method. -- set_headers: (array) Sets the given headers. -- remove_headers: (array) Remove the given headers. -- body: (mixed) Sets the given body. -- uri: (UriInterface) Set the URI. -- query: (string) Set the query string value of the URI. -- version: (string) Set the protocol version. +`public static function parse(string|array $header): array` +Parse an array of header values containing ";" separated data into an +array of associative arrays representing the header key value pair data +of the header. When a parameter does not contain a value, but just +contains a key, this function will inject a key with a '' string value. -## `function rewind_body` -`function rewind_body(MessageInterface $message)` +## `GuzzleHttp\Psr7\Header::normalize` -Attempts to rewind a message body and throws an exception on failure. The body -of the message will only be rewound if a call to `tell()` returns a value other -than `0`. +`public static function normalize(string|array $header): array` +Converts an array of header values that may contain comma separated +headers into an array of headers with no comma separated values. -## `function try_fopen` -`function try_fopen($filename, $mode)` +## `GuzzleHttp\Psr7\Query::parse` -Safely opens a PHP stream resource using a filename. +`public static function parse(string $str, int|bool $urlEncoding = true): array` + +Parse a query string into an associative array. + +If multiple values are found for the same key, the value of that key +value pair will become an array. This function does not parse nested +PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2` +will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`. + + +## `GuzzleHttp\Psr7\Query::build` + +`public static function build(array $params, int|false $encoding = PHP_QUERY_RFC3986): string` + +Build a query string from an array of key value pairs. + +This function can use the return value of `parse()` to build a query +string. This function does not modify the provided keys when an array is +encountered (like `http_build_query()` would). + + +## `GuzzleHttp\Psr7\Utils::caselessRemove` + +`public static function caselessRemove(iterable $keys, $keys, array $data): array` -When fopen fails, PHP normally raises a warning. This function adds an error -handler that checks for errors and throws an exception instead. +Remove the items given by the keys, case insensitively from the data. -## `function copy_to_string` +## `GuzzleHttp\Psr7\Utils::copyToStream` -`function copy_to_string(StreamInterface $stream, $maxLen = -1)` +`public static function copyToStream(StreamInterface $source, StreamInterface $dest, int $maxLen = -1): void` -Copy the contents of a stream into a string until the given number of bytes -have been read. +Copy the contents of a stream into another stream until the given number +of bytes have been read. -## `function copy_to_stream` +## `GuzzleHttp\Psr7\Utils::copyToString` -`function copy_to_stream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)` +`public static function copyToString(StreamInterface $stream, int $maxLen = -1): string` -Copy the contents of a stream into another stream until the given number of +Copy the contents of a stream into a string until the given number of bytes have been read. -## `function hash` +## `GuzzleHttp\Psr7\Utils::hash` -`function hash(StreamInterface $stream, $algo, $rawOutput = false)` +`public static function hash(StreamInterface $stream, string $algo, bool $rawOutput = false): string` -Calculate a hash of a Stream. This method reads the entire stream to calculate -a rolling hash (based on PHP's hash_init functions). +Calculate a hash of a stream. +This method reads the entire stream to calculate a rolling hash, based on +PHP's `hash_init` functions. -## `function readline` -`function readline(StreamInterface $stream, $maxLength = null)` +## `GuzzleHttp\Psr7\Utils::modifyRequest` + +`public static function modifyRequest(RequestInterface $request, array $changes): RequestInterface` + +Clone and modify a request with the given changes. + +This method is useful for reducing the number of clones needed to mutate +a message. + +- method: (string) Changes the HTTP method. +- set_headers: (array) Sets the given headers. +- remove_headers: (array) Remove the given headers. +- body: (mixed) Sets the given body. +- uri: (UriInterface) Set the URI. +- query: (string) Set the query string value of the URI. +- version: (string) Set the protocol version. + + +## `GuzzleHttp\Psr7\Utils::readLine` + +`public static function readLine(StreamInterface $stream, int $maxLength = null): string` Read a line from the stream up to the maximum allowed buffer length. -## `function parse_request` +## `GuzzleHttp\Psr7\Utils::streamFor` -`function parse_request($message)` +`public static function streamFor(resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource = '', array $options = []): StreamInterface` -Parses a request message string into a request object. +Create a new stream based on the input type. +Options is an associative array that can contain the following keys: -## `function parse_response` +- metadata: Array of custom metadata. +- size: Size of the stream. -`function parse_response($message)` +This method accepts the following `$resource` types: -Parses a response message string into a response object. +- `Psr\Http\Message\StreamInterface`: Returns the value as-is. +- `string`: Creates a stream object that uses the given string as the contents. +- `resource`: Creates a stream object that wraps the given PHP stream resource. +- `Iterator`: If the provided value implements `Iterator`, then a read-only + stream object will be created that wraps the given iterable. Each time the + stream is read from, data from the iterator will fill a buffer and will be + continuously called until the buffer is equal to the requested read size. + Subsequent read calls will first read from the buffer and then call `next` + on the underlying iterator until it is exhausted. +- `object` with `__toString()`: If the object has the `__toString()` method, + the object will be cast to a string and then a stream will be returned that + uses the string value. +- `NULL`: When `null` is passed, an empty stream object is returned. +- `callable` When a callable is passed, a read-only stream object will be + created that invokes the given callable. The callable is invoked with the + number of suggested bytes to read. The callable can return any number of + bytes, but MUST return `false` when there is no more data to return. The + stream object that wraps the callable will invoke the callable until the + number of requested bytes are available. Any additional bytes will be + buffered and used in subsequent reads. +```php +$stream = GuzzleHttp\Psr7\Utils::streamFor('foo'); +$stream = GuzzleHttp\Psr7\Utils::streamFor(fopen('/path/to/file', 'r')); -## `function parse_query` +$generator = function ($bytes) { + for ($i = 0; $i < $bytes; $i++) { + yield ' '; + } +} -`function parse_query($str, $urlEncoding = true)` +$stream = GuzzleHttp\Psr7\Utils::streamFor($generator(100)); +``` -Parse a query string into an associative array. -If multiple values are found for the same key, the value of that key value pair -will become an array. This function does not parse nested PHP style arrays into -an associative array (e.g., `foo[a]=1&foo[b]=2` will be parsed into -`['foo[a]' => '1', 'foo[b]' => '2']`). +## `GuzzleHttp\Psr7\Utils::tryFopen` +`public static function tryFopen(string $filename, string $mode): resource` -## `function build_query` +Safely opens a PHP stream resource using a filename. -`function build_query(array $params, $encoding = PHP_QUERY_RFC3986)` +When fopen fails, PHP normally raises a warning. This function adds an +error handler that checks for errors and throws an exception instead. -Build a query string from an array of key value pairs. -This function can use the return value of parse_query() to build a query string. -This function does not modify the provided keys when an array is encountered -(like http_build_query would). +## `GuzzleHttp\Psr7\Utils::uriFor` + +`public static function uriFor(string|UriInterface $uri): UriInterface` + +Returns a UriInterface for the given value. +This function accepts a string or UriInterface and returns a +UriInterface for the given value. If the value is already a +UriInterface, it is returned as-is. -## `function mimetype_from_filename` -`function mimetype_from_filename($filename)` +## `GuzzleHttp\Psr7\MimeType::fromFilename` + +`public static function fromFilename(string $filename): string|null` Determines the mimetype of a file by looking at its extension. -## `function mimetype_from_extension` +## `GuzzleHttp\Psr7\MimeType::fromExtension` -`function mimetype_from_extension($extension)` +`public static function fromExtension(string $extension): string|null` Maps a file extensions to a mimetype. +## Upgrading from Function API + +The static API was first introduced in 1.7.0, in order to mitigate problems with functions conflicting between global and local copies of the package. The function API will be removed in 2.0.0. A migration table has been provided here for your convenience: + +| Original Function | Replacement Method | +|----------------|----------------| +| `str` | `Message::toString` | +| `uri_for` | `Utils::uriFor` | +| `stream_for` | `Utils::streamFor` | +| `parse_header` | `Header::parse` | +| `normalize_header` | `Header::normalize` | +| `modify_request` | `Utils::modifyRequest` | +| `rewind_body` | `Message::rewindBody` | +| `try_fopen` | `Utils::tryFopen` | +| `copy_to_string` | `Utils::copyToString` | +| `copy_to_stream` | `Utils::copyToStream` | +| `hash` | `Utils::hash` | +| `readline` | `Utils::readLine` | +| `parse_request` | `Message::parseRequest` | +| `parse_response` | `Message::parseResponse` | +| `parse_query` | `Query::parse` | +| `build_query` | `Query::build` | +| `mimetype_from_filename` | `MimeType::fromFilename` | +| `mimetype_from_extension` | `MimeType::fromExtension` | +| `_parse_message` | `Message::parseMessage` | +| `_parse_request_uri` | `Message::parseRequestUri` | +| `get_message_body_summary` | `Message::bodySummary` | +| `_caseless_remove` | `Utils::caselessRemove` | + + # Additional URI Methods Aside from the standard `Psr\Http\Message\UriInterface` implementation in form of the `GuzzleHttp\Psr7\Uri` class, diff --git a/vendor/guzzlehttp/psr7/composer.json b/vendor/guzzlehttp/psr7/composer.json index 168a055b0..58dcb07e4 100644 --- a/vendor/guzzlehttp/psr7/composer.json +++ b/vendor/guzzlehttp/psr7/composer.json @@ -21,14 +21,14 @@ "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" }, "require-dev": { - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10", "ext-zlib": "*" }, "provide": { "psr/http-message-implementation": "1.0" }, "suggest": { - "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "autoload": { "psr-4": { @@ -43,7 +43,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.6-dev" + "dev-master": "1.7-dev" } } } diff --git a/vendor/guzzlehttp/psr7/src/AppendStream.php b/vendor/guzzlehttp/psr7/src/AppendStream.php index 472a0d61b..fa9153d78 100644 --- a/vendor/guzzlehttp/psr7/src/AppendStream.php +++ b/vendor/guzzlehttp/psr7/src/AppendStream.php @@ -1,4 +1,5 @@ streams = []; + + return null; } public function tell() diff --git a/vendor/guzzlehttp/psr7/src/BufferStream.php b/vendor/guzzlehttp/psr7/src/BufferStream.php index af4d4c227..783859c19 100644 --- a/vendor/guzzlehttp/psr7/src/BufferStream.php +++ b/vendor/guzzlehttp/psr7/src/BufferStream.php @@ -1,4 +1,5 @@ close(); + + return null; } public function getSize() diff --git a/vendor/guzzlehttp/psr7/src/CachingStream.php b/vendor/guzzlehttp/psr7/src/CachingStream.php index ed68f0861..fe749e981 100644 --- a/vendor/guzzlehttp/psr7/src/CachingStream.php +++ b/vendor/guzzlehttp/psr7/src/CachingStream.php @@ -1,4 +1,5 @@ remoteStream = $stream; - $this->stream = $target ?: new Stream(fopen('php://temp', 'r+')); + $this->stream = $target ?: new Stream(Utils::tryFopen('php://temp', 'r+')); } public function getSize() @@ -131,7 +134,7 @@ public function close() private function cacheEntireStream() { $target = new FnStream(['write' => 'strlen']); - copy_to_stream($this, $target); + Utils::copyToStream($this, $target); return $this->tell(); } diff --git a/vendor/guzzlehttp/psr7/src/DroppingStream.php b/vendor/guzzlehttp/psr7/src/DroppingStream.php index 8935c80d7..9f7420c40 100644 --- a/vendor/guzzlehttp/psr7/src/DroppingStream.php +++ b/vendor/guzzlehttp/psr7/src/DroppingStream.php @@ -1,4 +1,5 @@ ]+>|[^=]+/', $kvp, $matches)) { + $m = $matches[0]; + if (isset($m[1])) { + $part[trim($m[0], $trimmed)] = trim($m[1], $trimmed); + } else { + $part[] = trim($m[0], $trimmed); + } + } + } + if ($part) { + $params[] = $part; + } + } + + return $params; + } + + /** + * Converts an array of header values that may contain comma separated + * headers into an array of headers with no comma separated values. + * + * @param string|array $header Header to normalize. + * + * @return array Returns the normalized header field values. + */ + public static function normalize($header) + { + if (!is_array($header)) { + return array_map('trim', explode(',', $header)); + } + + $result = []; + foreach ($header as $value) { + foreach ((array) $value as $v) { + if (strpos($v, ',') === false) { + $result[] = $v; + continue; + } + foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $v) as $vv) { + $result[] = trim($vv); + } + } + } + + return $result; + } +} diff --git a/vendor/guzzlehttp/psr7/src/InflateStream.php b/vendor/guzzlehttp/psr7/src/InflateStream.php index 5e4f6028c..0cbd2cce2 100644 --- a/vendor/guzzlehttp/psr7/src/InflateStream.php +++ b/vendor/guzzlehttp/psr7/src/InflateStream.php @@ -1,4 +1,5 @@ filename, $this->mode)); + return Utils::streamFor(Utils::tryFopen($this->filename, $this->mode)); } } diff --git a/vendor/guzzlehttp/psr7/src/LimitStream.php b/vendor/guzzlehttp/psr7/src/LimitStream.php index e4f239e30..1173ec40d 100644 --- a/vendor/guzzlehttp/psr7/src/LimitStream.php +++ b/vendor/guzzlehttp/psr7/src/LimitStream.php @@ -1,11 +1,13 @@ getMethod() . ' ' + . $message->getRequestTarget()) + . ' HTTP/' . $message->getProtocolVersion(); + if (!$message->hasHeader('host')) { + $msg .= "\r\nHost: " . $message->getUri()->getHost(); + } + } elseif ($message instanceof ResponseInterface) { + $msg = 'HTTP/' . $message->getProtocolVersion() . ' ' + . $message->getStatusCode() . ' ' + . $message->getReasonPhrase(); + } else { + throw new \InvalidArgumentException('Unknown message type'); + } + + foreach ($message->getHeaders() as $name => $values) { + if (strtolower($name) === 'set-cookie') { + foreach ($values as $value) { + $msg .= "\r\n{$name}: " . $value; + } + } else { + $msg .= "\r\n{$name}: " . implode(', ', $values); + } + } + + return "{$msg}\r\n\r\n" . $message->getBody(); + } + + /** + * Get a short summary of the message body. + * + * Will return `null` if the response is not printable. + * + * @param MessageInterface $message The message to get the body summary + * @param int $truncateAt The maximum allowed size of the summary + * + * @return string|null + */ + public static function bodySummary(MessageInterface $message, $truncateAt = 120) + { + $body = $message->getBody(); + + if (!$body->isSeekable() || !$body->isReadable()) { + return null; + } + + $size = $body->getSize(); + + if ($size === 0) { + return null; + } + + $summary = $body->read($truncateAt); + $body->rewind(); + + if ($size > $truncateAt) { + $summary .= ' (truncated...)'; + } + + // Matches any printable character, including unicode characters: + // letters, marks, numbers, punctuation, spacing, and separators. + if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/u', $summary)) { + return null; + } + + return $summary; + } + + /** + * Attempts to rewind a message body and throws an exception on failure. + * + * The body of the message will only be rewound if a call to `tell()` + * returns a value other than `0`. + * + * @param MessageInterface $message Message to rewind + * + * @throws \RuntimeException + */ + public static function rewindBody(MessageInterface $message) + { + $body = $message->getBody(); + + if ($body->tell()) { + $body->rewind(); + } + } + + /** + * Parses an HTTP message into an associative array. + * + * The array contains the "start-line" key containing the start line of + * the message, "headers" key containing an associative array of header + * array values, and a "body" key containing the body of the message. + * + * @param string $message HTTP request or response to parse. + * + * @return array + */ + public static function parseMessage($message) + { + if (!$message) { + throw new \InvalidArgumentException('Invalid message'); + } + + $message = ltrim($message, "\r\n"); + + $messageParts = preg_split("/\r?\n\r?\n/", $message, 2); + + if ($messageParts === false || count($messageParts) !== 2) { + throw new \InvalidArgumentException('Invalid message: Missing header delimiter'); + } + + list($rawHeaders, $body) = $messageParts; + $rawHeaders .= "\r\n"; // Put back the delimiter we split previously + $headerParts = preg_split("/\r?\n/", $rawHeaders, 2); + + if ($headerParts === false || count($headerParts) !== 2) { + throw new \InvalidArgumentException('Invalid message: Missing status line'); + } + + list($startLine, $rawHeaders) = $headerParts; + + if (preg_match("/(?:^HTTP\/|^[A-Z]+ \S+ HTTP\/)(\d+(?:\.\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') { + // Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0 + $rawHeaders = preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders); + } + + /** @var array[] $headerLines */ + $count = preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, PREG_SET_ORDER); + + // If these aren't the same, then one line didn't match and there's an invalid header. + if ($count !== substr_count($rawHeaders, "\n")) { + // Folding is deprecated, see https://tools.ietf.org/html/rfc7230#section-3.2.4 + if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) { + throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding'); + } + + throw new \InvalidArgumentException('Invalid header syntax'); + } + + $headers = []; + + foreach ($headerLines as $headerLine) { + $headers[$headerLine[1]][] = $headerLine[2]; + } + + return [ + 'start-line' => $startLine, + 'headers' => $headers, + 'body' => $body, + ]; + } + + /** + * Constructs a URI for an HTTP request message. + * + * @param string $path Path from the start-line + * @param array $headers Array of headers (each value an array). + * + * @return string + */ + public static function parseRequestUri($path, array $headers) + { + $hostKey = array_filter(array_keys($headers), function ($k) { + return strtolower($k) === 'host'; + }); + + // If no host is found, then a full URI cannot be constructed. + if (!$hostKey) { + return $path; + } + + $host = $headers[reset($hostKey)][0]; + $scheme = substr($host, -4) === ':443' ? 'https' : 'http'; + + return $scheme . '://' . $host . '/' . ltrim($path, '/'); + } + + /** + * Parses a request message string into a request object. + * + * @param string $message Request message string. + * + * @return Request + */ + public static function parseRequest($message) + { + $data = self::parseMessage($message); + $matches = []; + if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) { + throw new \InvalidArgumentException('Invalid request string'); + } + $parts = explode(' ', $data['start-line'], 3); + $version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1'; + + $request = new Request( + $parts[0], + $matches[1] === '/' ? self::parseRequestUri($parts[1], $data['headers']) : $parts[1], + $data['headers'], + $data['body'], + $version + ); + + return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]); + } + + /** + * Parses a response message string into a response object. + * + * @param string $message Response message string. + * + * @return Response + */ + public static function parseResponse($message) + { + $data = self::parseMessage($message); + // According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space + // between status-code and reason-phrase is required. But browsers accept + // responses without space and reason as well. + if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) { + throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']); + } + $parts = explode(' ', $data['start-line'], 3); + + return new Response( + (int) $parts[1], + $data['headers'], + $data['body'], + explode('/', $parts[0])[1], + isset($parts[2]) ? $parts[2] : null + ); + } +} diff --git a/vendor/guzzlehttp/psr7/src/MessageTrait.php b/vendor/guzzlehttp/psr7/src/MessageTrait.php index a7966d10c..99203bb43 100644 --- a/vendor/guzzlehttp/psr7/src/MessageTrait.php +++ b/vendor/guzzlehttp/psr7/src/MessageTrait.php @@ -1,4 +1,5 @@ stream) { - $this->stream = stream_for(''); + $this->stream = Utils::streamFor(''); } return $this->stream; @@ -194,7 +195,7 @@ private function trimHeaderValues(array $values) } return trim((string) $value, " \t"); - }, $values); + }, array_values($values)); } private function assertHeader($header) diff --git a/vendor/guzzlehttp/psr7/src/MimeType.php b/vendor/guzzlehttp/psr7/src/MimeType.php new file mode 100644 index 000000000..205c7b1fa --- /dev/null +++ b/vendor/guzzlehttp/psr7/src/MimeType.php @@ -0,0 +1,140 @@ + 'video/3gpp', + '7z' => 'application/x-7z-compressed', + 'aac' => 'audio/x-aac', + 'ai' => 'application/postscript', + 'aif' => 'audio/x-aiff', + 'asc' => 'text/plain', + 'asf' => 'video/x-ms-asf', + 'atom' => 'application/atom+xml', + 'avi' => 'video/x-msvideo', + 'bmp' => 'image/bmp', + 'bz2' => 'application/x-bzip2', + 'cer' => 'application/pkix-cert', + 'crl' => 'application/pkix-crl', + 'crt' => 'application/x-x509-ca-cert', + 'css' => 'text/css', + 'csv' => 'text/csv', + 'cu' => 'application/cu-seeme', + 'deb' => 'application/x-debian-package', + 'doc' => 'application/msword', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dvi' => 'application/x-dvi', + 'eot' => 'application/vnd.ms-fontobject', + 'eps' => 'application/postscript', + 'epub' => 'application/epub+zip', + 'etx' => 'text/x-setext', + 'flac' => 'audio/flac', + 'flv' => 'video/x-flv', + 'gif' => 'image/gif', + 'gz' => 'application/gzip', + 'htm' => 'text/html', + 'html' => 'text/html', + 'ico' => 'image/x-icon', + 'ics' => 'text/calendar', + 'ini' => 'text/plain', + 'iso' => 'application/x-iso9660-image', + 'jar' => 'application/java-archive', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'js' => 'text/javascript', + 'json' => 'application/json', + 'latex' => 'application/x-latex', + 'log' => 'text/plain', + 'm4a' => 'audio/mp4', + 'm4v' => 'video/mp4', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mov' => 'video/quicktime', + 'mkv' => 'video/x-matroska', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mp4', + 'mp4a' => 'audio/mp4', + 'mp4v' => 'video/mp4', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpg4' => 'video/mp4', + 'oga' => 'audio/ogg', + 'ogg' => 'audio/ogg', + 'ogv' => 'video/ogg', + 'ogx' => 'application/ogg', + 'pbm' => 'image/x-portable-bitmap', + 'pdf' => 'application/pdf', + 'pgm' => 'image/x-portable-graymap', + 'png' => 'image/png', + 'pnm' => 'image/x-portable-anymap', + 'ppm' => 'image/x-portable-pixmap', + 'ppt' => 'application/vnd.ms-powerpoint', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'ps' => 'application/postscript', + 'qt' => 'video/quicktime', + 'rar' => 'application/x-rar-compressed', + 'ras' => 'image/x-cmu-raster', + 'rss' => 'application/rss+xml', + 'rtf' => 'application/rtf', + 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', + 'svg' => 'image/svg+xml', + 'swf' => 'application/x-shockwave-flash', + 'tar' => 'application/x-tar', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'torrent' => 'application/x-bittorrent', + 'ttf' => 'application/x-font-ttf', + 'txt' => 'text/plain', + 'wav' => 'audio/x-wav', + 'webm' => 'video/webm', + 'webp' => 'image/webp', + 'wma' => 'audio/x-ms-wma', + 'wmv' => 'video/x-ms-wmv', + 'woff' => 'application/x-font-woff', + 'wsdl' => 'application/wsdl+xml', + 'xbm' => 'image/x-xbitmap', + 'xls' => 'application/vnd.ms-excel', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xml' => 'application/xml', + 'xpm' => 'image/x-xpixmap', + 'xwd' => 'image/x-xwindowdump', + 'yaml' => 'text/yaml', + 'yml' => 'text/yaml', + 'zip' => 'application/zip', + ]; + + $extension = strtolower($extension); + + return isset($mimetypes[$extension]) + ? $mimetypes[$extension] + : null; + } +} diff --git a/vendor/guzzlehttp/psr7/src/MultipartStream.php b/vendor/guzzlehttp/psr7/src/MultipartStream.php index c0fd584f7..5a6079a89 100644 --- a/vendor/guzzlehttp/psr7/src/MultipartStream.php +++ b/vendor/guzzlehttp/psr7/src/MultipartStream.php @@ -1,4 +1,5 @@ addStream(stream_for("--{$this->boundary}--\r\n")); + $stream->addStream(Utils::streamFor("--{$this->boundary}--\r\n")); return $stream; } @@ -84,7 +87,7 @@ private function addElement(AppendStream $stream, array $element) } } - $element['contents'] = stream_for($element['contents']); + $element['contents'] = Utils::streamFor($element['contents']); if (empty($element['filename'])) { $uri = $element['contents']->getMetadata('uri'); @@ -100,9 +103,9 @@ private function addElement(AppendStream $stream, array $element) isset($element['headers']) ? $element['headers'] : [] ); - $stream->addStream(stream_for($this->getHeaders($headers))); + $stream->addStream(Utils::streamFor($this->getHeaders($headers))); $stream->addStream($body); - $stream->addStream(stream_for("\r\n")); + $stream->addStream(Utils::streamFor("\r\n")); } /** @@ -114,9 +117,11 @@ private function createElement($name, StreamInterface $stream, $filename, array $disposition = $this->getHeader($headers, 'content-disposition'); if (!$disposition) { $headers['Content-Disposition'] = ($filename === '0' || $filename) - ? sprintf('form-data; name="%s"; filename="%s"', + ? sprintf( + 'form-data; name="%s"; filename="%s"', $name, - basename($filename)) + basename($filename) + ) : "form-data; name=\"{$name}\""; } @@ -131,7 +136,7 @@ private function createElement($name, StreamInterface $stream, $filename, array // Set a default Content-Type if one was not supplied $type = $this->getHeader($headers, 'content-type'); if (!$type && ($filename === '0' || $filename)) { - if ($type = mimetype_from_filename($filename)) { + if ($type = MimeType::fromFilename($filename)) { $headers['Content-Type'] = $type; } } diff --git a/vendor/guzzlehttp/psr7/src/NoSeekStream.php b/vendor/guzzlehttp/psr7/src/NoSeekStream.php index 233221805..d66bdde46 100644 --- a/vendor/guzzlehttp/psr7/src/NoSeekStream.php +++ b/vendor/guzzlehttp/psr7/src/NoSeekStream.php @@ -1,10 +1,13 @@ tellPos = false; $this->source = null; + + return null; } public function getSize() diff --git a/vendor/guzzlehttp/psr7/src/Query.php b/vendor/guzzlehttp/psr7/src/Query.php new file mode 100644 index 000000000..5a7cc0359 --- /dev/null +++ b/vendor/guzzlehttp/psr7/src/Query.php @@ -0,0 +1,113 @@ + '1', 'foo[b]' => '2'])`. + * + * @param string $str Query string to parse + * @param int|bool $urlEncoding How the query string is encoded + * + * @return array + */ + public static function parse($str, $urlEncoding = true) + { + $result = []; + + if ($str === '') { + return $result; + } + + if ($urlEncoding === true) { + $decoder = function ($value) { + return rawurldecode(str_replace('+', ' ', $value)); + }; + } elseif ($urlEncoding === PHP_QUERY_RFC3986) { + $decoder = 'rawurldecode'; + } elseif ($urlEncoding === PHP_QUERY_RFC1738) { + $decoder = 'urldecode'; + } else { + $decoder = function ($str) { + return $str; + }; + } + + foreach (explode('&', $str) as $kvp) { + $parts = explode('=', $kvp, 2); + $key = $decoder($parts[0]); + $value = isset($parts[1]) ? $decoder($parts[1]) : null; + if (!isset($result[$key])) { + $result[$key] = $value; + } else { + if (!is_array($result[$key])) { + $result[$key] = [$result[$key]]; + } + $result[$key][] = $value; + } + } + + return $result; + } + + /** + * Build a query string from an array of key value pairs. + * + * This function can use the return value of `parse()` to build a query + * string. This function does not modify the provided keys when an array is + * encountered (like `http_build_query()` would). + * + * @param array $params Query string parameters. + * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986 + * to encode using RFC3986, or PHP_QUERY_RFC1738 + * to encode using RFC1738. + * + * @return string + */ + public static function build(array $params, $encoding = PHP_QUERY_RFC3986) + { + if (!$params) { + return ''; + } + + if ($encoding === false) { + $encoder = function ($str) { + return $str; + }; + } elseif ($encoding === PHP_QUERY_RFC3986) { + $encoder = 'rawurlencode'; + } elseif ($encoding === PHP_QUERY_RFC1738) { + $encoder = 'urlencode'; + } else { + throw new \InvalidArgumentException('Invalid type'); + } + + $qs = ''; + foreach ($params as $k => $v) { + $k = $encoder($k); + if (!is_array($v)) { + $qs .= $k; + if ($v !== null) { + $qs .= '=' . $encoder($v); + } + $qs .= '&'; + } else { + foreach ($v as $vv) { + $qs .= $k; + if ($vv !== null) { + $qs .= '=' . $encoder($vv); + } + $qs .= '&'; + } + } + } + + return $qs ? (string) substr($qs, 0, -1) : ''; + } +} diff --git a/vendor/guzzlehttp/psr7/src/Request.php b/vendor/guzzlehttp/psr7/src/Request.php index 59f337db1..c1cdaebff 100644 --- a/vendor/guzzlehttp/psr7/src/Request.php +++ b/vendor/guzzlehttp/psr7/src/Request.php @@ -1,4 +1,5 @@ stream = stream_for($body); + $this->stream = Utils::streamFor($body); } } diff --git a/vendor/guzzlehttp/psr7/src/Response.php b/vendor/guzzlehttp/psr7/src/Response.php index e7e04d86a..8c01a0f5a 100644 --- a/vendor/guzzlehttp/psr7/src/Response.php +++ b/vendor/guzzlehttp/psr7/src/Response.php @@ -1,4 +1,5 @@ statusCode = $status; if ($body !== '' && $body !== null) { - $this->stream = stream_for($body); + $this->stream = Utils::streamFor($body); } $this->setHeaders($headers); @@ -134,7 +135,7 @@ public function withStatus($code, $reasonPhrase = '') if ($reasonPhrase == '' && isset(self::$phrases[$new->statusCode])) { $reasonPhrase = self::$phrases[$new->statusCode]; } - $new->reasonPhrase = $reasonPhrase; + $new->reasonPhrase = (string) $reasonPhrase; return $new; } diff --git a/vendor/guzzlehttp/psr7/src/Rfc7230.php b/vendor/guzzlehttp/psr7/src/Rfc7230.php index 505e4742b..51b571f24 100644 --- a/vendor/guzzlehttp/psr7/src/Rfc7230.php +++ b/vendor/guzzlehttp/psr7/src/Rfc7230.php @@ -11,6 +11,7 @@ final class Rfc7230 * Note: header delimiter (\r\n) is modified to \r?\n to accept line feed only delimiters for BC reasons. * * @link https://github.com/amphp/http/blob/v1.0.1/src/Rfc7230.php#L12-L15 + * * @license https://github.com/amphp/http/blob/v1.0.1/LICENSE */ const HEADER_REGEX = "(^([^()<>@,;:\\\"/[\]?={}\x01-\x20\x7F]++):[ \t]*+((?:[ \t]*+[\x21-\x7E\x80-\xFF]++)*+)[ \t]*+\r?\n)m"; diff --git a/vendor/guzzlehttp/psr7/src/ServerRequest.php b/vendor/guzzlehttp/psr7/src/ServerRequest.php index 1a09a6c87..e6d26f5ff 100644 --- a/vendor/guzzlehttp/psr7/src/ServerRequest.php +++ b/vendor/guzzlehttp/psr7/src/ServerRequest.php @@ -4,9 +4,9 @@ use InvalidArgumentException; use Psr\Http\Message\ServerRequestInterface; -use Psr\Http\Message\UriInterface; use Psr\Http\Message\StreamInterface; use Psr\Http\Message\UploadedFileInterface; +use Psr\Http\Message\UriInterface; /** * Server-side HTTP request @@ -35,7 +35,7 @@ class ServerRequest extends Request implements ServerRequestInterface private $cookieParams = []; /** - * @var null|array|object + * @var array|object|null */ private $parsedBody; @@ -58,7 +58,7 @@ class ServerRequest extends Request implements ServerRequestInterface * @param string $method HTTP method * @param string|UriInterface $uri URI * @param array $headers Request headers - * @param string|null|resource|StreamInterface $body Request body + * @param string|resource|StreamInterface|null $body Request body * @param string $version Protocol version * @param array $serverParams Typically the $_SERVER superglobal */ @@ -79,8 +79,10 @@ public function __construct( * Return an UploadedFile instance array. * * @param array $files A array which respect $_FILES structure - * @throws InvalidArgumentException for unrecognized values + * * @return array + * + * @throws InvalidArgumentException for unrecognized values */ public static function normalizeFiles(array $files) { @@ -109,6 +111,7 @@ public static function normalizeFiles(array $files) * delegate to normalizeNestedFileSpec() and return that return value. * * @param array $value $_FILES struct + * * @return array|UploadedFileInterface */ private static function createUploadedFileFromSpec(array $value) @@ -133,6 +136,7 @@ private static function createUploadedFileFromSpec(array $value) * UploadedFileInterface instances. * * @param array $files + * * @return UploadedFileInterface[] */ private static function normalizeNestedFileSpec(array $files = []) @@ -182,7 +186,7 @@ public static function fromGlobals() private static function extractHostAndPortFromAuthority($authority) { - $uri = 'http://'.$authority; + $uri = 'http://' . $authority; $parts = parse_url($uri); if (false === $parts) { return [null, null]; @@ -243,7 +247,6 @@ public static function getUriFromGlobals() return $uri; } - /** * {@inheritdoc} */ diff --git a/vendor/guzzlehttp/psr7/src/Stream.php b/vendor/guzzlehttp/psr7/src/Stream.php index d9e7409c7..3865d6d6a 100644 --- a/vendor/guzzlehttp/psr7/src/Stream.php +++ b/vendor/guzzlehttp/psr7/src/Stream.php @@ -1,4 +1,5 @@ seek(0); - return (string) stream_get_contents($this->stream); + if ($this->isSeekable()) { + $this->seek(0); + } + return $this->getContents(); } catch (\Exception $e) { return ''; } @@ -193,7 +196,7 @@ public function rewind() public function seek($offset, $whence = SEEK_SET) { $whence = (int) $whence; - + if (!isset($this->stream)) { throw new \RuntimeException('Stream is detached'); } diff --git a/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php b/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php index daec6f52e..5025dd67b 100644 --- a/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php +++ b/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php @@ -1,10 +1,12 @@ file, $targetPath) : move_uploaded_file($this->file, $targetPath); } else { - copy_to_stream( + Utils::copyToStream( $this->getStream(), new LazyOpenStream($targetPath, 'w') ); @@ -288,6 +299,7 @@ public function getSize() * {@inheritdoc} * * @see http://php.net/manual/en/features.file-upload.errors.php + * * @return int One of PHP's UPLOAD_ERR_XXX constants. */ public function getError() @@ -299,7 +311,7 @@ public function getError() * {@inheritdoc} * * @return string|null The filename sent by the client or null if none - * was provided. + * was provided. */ public function getClientFilename() { diff --git a/vendor/guzzlehttp/psr7/src/Uri.php b/vendor/guzzlehttp/psr7/src/Uri.php index 825a25eed..ab201c1d1 100644 --- a/vendor/guzzlehttp/psr7/src/Uri.php +++ b/vendor/guzzlehttp/psr7/src/Uri.php @@ -1,4 +1,5 @@ path = '/'. $this->path; + $this->path = '/' . $this->path; //throw new \InvalidArgumentException('The path of a URI with an authority must start with a slash "/" or be empty'); } } diff --git a/vendor/guzzlehttp/psr7/src/UriNormalizer.php b/vendor/guzzlehttp/psr7/src/UriNormalizer.php index 384c29e50..81419ead4 100644 --- a/vendor/guzzlehttp/psr7/src/UriNormalizer.php +++ b/vendor/guzzlehttp/psr7/src/UriNormalizer.php @@ -1,4 +1,5 @@ $keys + * + * @return array + */ + public static function caselessRemove($keys, array $data) + { + $result = []; + + foreach ($keys as &$key) { + $key = strtolower($key); + } + + foreach ($data as $k => $v) { + if (!in_array(strtolower($k), $keys)) { + $result[$k] = $v; + } + } + + return $result; + } + + /** + * Copy the contents of a stream into another stream until the given number + * of bytes have been read. + * + * @param StreamInterface $source Stream to read from + * @param StreamInterface $dest Stream to write to + * @param int $maxLen Maximum number of bytes to read. Pass -1 + * to read the entire stream. + * + * @throws \RuntimeException on error. + */ + public static function copyToStream(StreamInterface $source, StreamInterface $dest, $maxLen = -1) + { + $bufferSize = 8192; + + if ($maxLen === -1) { + while (!$source->eof()) { + if (!$dest->write($source->read($bufferSize))) { + break; + } + } + } else { + $remaining = $maxLen; + while ($remaining > 0 && !$source->eof()) { + $buf = $source->read(min($bufferSize, $remaining)); + $len = strlen($buf); + if (!$len) { + break; + } + $remaining -= $len; + $dest->write($buf); + } + } + } + + /** + * Copy the contents of a stream into a string until the given number of + * bytes have been read. + * + * @param StreamInterface $stream Stream to read + * @param int $maxLen Maximum number of bytes to read. Pass -1 + * to read the entire stream. + * + * @return string + * + * @throws \RuntimeException on error. + */ + public static function copyToString(StreamInterface $stream, $maxLen = -1) + { + $buffer = ''; + + if ($maxLen === -1) { + while (!$stream->eof()) { + $buf = $stream->read(1048576); + // Using a loose equality here to match on '' and false. + if ($buf == null) { + break; + } + $buffer .= $buf; + } + return $buffer; + } + + $len = 0; + while (!$stream->eof() && $len < $maxLen) { + $buf = $stream->read($maxLen - $len); + // Using a loose equality here to match on '' and false. + if ($buf == null) { + break; + } + $buffer .= $buf; + $len = strlen($buffer); + } + + return $buffer; + } + + /** + * Calculate a hash of a stream. + * + * This method reads the entire stream to calculate a rolling hash, based + * on PHP's `hash_init` functions. + * + * @param StreamInterface $stream Stream to calculate the hash for + * @param string $algo Hash algorithm (e.g. md5, crc32, etc) + * @param bool $rawOutput Whether or not to use raw output + * + * @return string Returns the hash of the stream + * + * @throws \RuntimeException on error. + */ + public static function hash(StreamInterface $stream, $algo, $rawOutput = false) + { + $pos = $stream->tell(); + + if ($pos > 0) { + $stream->rewind(); + } + + $ctx = hash_init($algo); + while (!$stream->eof()) { + hash_update($ctx, $stream->read(1048576)); + } + + $out = hash_final($ctx, (bool) $rawOutput); + $stream->seek($pos); + + return $out; + } + + /** + * Clone and modify a request with the given changes. + * + * This method is useful for reducing the number of clones needed to mutate + * a message. + * + * The changes can be one of: + * - method: (string) Changes the HTTP method. + * - set_headers: (array) Sets the given headers. + * - remove_headers: (array) Remove the given headers. + * - body: (mixed) Sets the given body. + * - uri: (UriInterface) Set the URI. + * - query: (string) Set the query string value of the URI. + * - version: (string) Set the protocol version. + * + * @param RequestInterface $request Request to clone and modify. + * @param array $changes Changes to apply. + * + * @return RequestInterface + */ + public static function modifyRequest(RequestInterface $request, array $changes) + { + if (!$changes) { + return $request; + } + + $headers = $request->getHeaders(); + + if (!isset($changes['uri'])) { + $uri = $request->getUri(); + } else { + // Remove the host header if one is on the URI + if ($host = $changes['uri']->getHost()) { + $changes['set_headers']['Host'] = $host; + + if ($port = $changes['uri']->getPort()) { + $standardPorts = ['http' => 80, 'https' => 443]; + $scheme = $changes['uri']->getScheme(); + if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) { + $changes['set_headers']['Host'] .= ':' . $port; + } + } + } + $uri = $changes['uri']; + } + + if (!empty($changes['remove_headers'])) { + $headers = self::caselessRemove($changes['remove_headers'], $headers); + } + + if (!empty($changes['set_headers'])) { + $headers = self::caselessRemove(array_keys($changes['set_headers']), $headers); + $headers = $changes['set_headers'] + $headers; + } + + if (isset($changes['query'])) { + $uri = $uri->withQuery($changes['query']); + } + + if ($request instanceof ServerRequestInterface) { + $new = (new ServerRequest( + isset($changes['method']) ? $changes['method'] : $request->getMethod(), + $uri, + $headers, + isset($changes['body']) ? $changes['body'] : $request->getBody(), + isset($changes['version']) + ? $changes['version'] + : $request->getProtocolVersion(), + $request->getServerParams() + )) + ->withParsedBody($request->getParsedBody()) + ->withQueryParams($request->getQueryParams()) + ->withCookieParams($request->getCookieParams()) + ->withUploadedFiles($request->getUploadedFiles()); + + foreach ($request->getAttributes() as $key => $value) { + $new = $new->withAttribute($key, $value); + } + + return $new; + } + + return new Request( + isset($changes['method']) ? $changes['method'] : $request->getMethod(), + $uri, + $headers, + isset($changes['body']) ? $changes['body'] : $request->getBody(), + isset($changes['version']) + ? $changes['version'] + : $request->getProtocolVersion() + ); + } + + /** + * Read a line from the stream up to the maximum allowed buffer length. + * + * @param StreamInterface $stream Stream to read from + * @param int|null $maxLength Maximum buffer length + * + * @return string + */ + public static function readLine(StreamInterface $stream, $maxLength = null) + { + $buffer = ''; + $size = 0; + + while (!$stream->eof()) { + // Using a loose equality here to match on '' and false. + if (null == ($byte = $stream->read(1))) { + return $buffer; + } + $buffer .= $byte; + // Break when a new line is found or the max length - 1 is reached + if ($byte === "\n" || ++$size === $maxLength - 1) { + break; + } + } + + return $buffer; + } + + /** + * Create a new stream based on the input type. + * + * Options is an associative array that can contain the following keys: + * - metadata: Array of custom metadata. + * - size: Size of the stream. + * + * This method accepts the following `$resource` types: + * - `Psr\Http\Message\StreamInterface`: Returns the value as-is. + * - `string`: Creates a stream object that uses the given string as the contents. + * - `resource`: Creates a stream object that wraps the given PHP stream resource. + * - `Iterator`: If the provided value implements `Iterator`, then a read-only + * stream object will be created that wraps the given iterable. Each time the + * stream is read from, data from the iterator will fill a buffer and will be + * continuously called until the buffer is equal to the requested read size. + * Subsequent read calls will first read from the buffer and then call `next` + * on the underlying iterator until it is exhausted. + * - `object` with `__toString()`: If the object has the `__toString()` method, + * the object will be cast to a string and then a stream will be returned that + * uses the string value. + * - `NULL`: When `null` is passed, an empty stream object is returned. + * - `callable` When a callable is passed, a read-only stream object will be + * created that invokes the given callable. The callable is invoked with the + * number of suggested bytes to read. The callable can return any number of + * bytes, but MUST return `false` when there is no more data to return. The + * stream object that wraps the callable will invoke the callable until the + * number of requested bytes are available. Any additional bytes will be + * buffered and used in subsequent reads. + * + * @param resource|string|int|float|bool|StreamInterface|callable|\Iterator|null $resource Entity body data + * @param array $options Additional options + * + * @return StreamInterface + * + * @throws \InvalidArgumentException if the $resource arg is not valid. + */ + public static function streamFor($resource = '', array $options = []) + { + if (is_scalar($resource)) { + $stream = self::tryFopen('php://temp', 'r+'); + if ($resource !== '') { + fwrite($stream, $resource); + fseek($stream, 0); + } + return new Stream($stream, $options); + } + + switch (gettype($resource)) { + case 'resource': + /* + * The 'php://input' is a special stream with quirks and inconsistencies. + * We avoid using that stream by reading it into php://temp + */ + if (\stream_get_meta_data($resource)['uri'] === 'php://input') { + $stream = self::tryFopen('php://temp', 'w+'); + fwrite($stream, stream_get_contents($resource)); + fseek($stream, 0); + $resource = $stream; + } + return new Stream($resource, $options); + case 'object': + if ($resource instanceof StreamInterface) { + return $resource; + } elseif ($resource instanceof \Iterator) { + return new PumpStream(function () use ($resource) { + if (!$resource->valid()) { + return false; + } + $result = $resource->current(); + $resource->next(); + return $result; + }, $options); + } elseif (method_exists($resource, '__toString')) { + return Utils::streamFor((string) $resource, $options); + } + break; + case 'NULL': + return new Stream(self::tryFopen('php://temp', 'r+'), $options); + } + + if (is_callable($resource)) { + return new PumpStream($resource, $options); + } + + throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource)); + } + + /** + * Safely opens a PHP stream resource using a filename. + * + * When fopen fails, PHP normally raises a warning. This function adds an + * error handler that checks for errors and throws an exception instead. + * + * @param string $filename File to open + * @param string $mode Mode used to open the file + * + * @return resource + * + * @throws \RuntimeException if the file cannot be opened + */ + public static function tryFopen($filename, $mode) + { + $ex = null; + set_error_handler(function () use ($filename, $mode, &$ex) { + $ex = new \RuntimeException(sprintf( + 'Unable to open "%s" using mode "%s": %s', + $filename, + $mode, + func_get_args()[1] + )); + + return true; + }); + + try { + $handle = fopen($filename, $mode); + } catch (\Throwable $e) { + $ex = new \RuntimeException(sprintf( + 'Unable to open "%s" using mode "%s": %s', + $filename, + $mode, + $e->getMessage() + ), 0, $e); + } + + restore_error_handler(); + + if ($ex) { + /** @var $ex \RuntimeException */ + throw $ex; + } + + return $handle; + } + + /** + * Returns a UriInterface for the given value. + * + * This function accepts a string or UriInterface and returns a + * UriInterface for the given value. If the value is already a + * UriInterface, it is returned as-is. + * + * @param string|UriInterface $uri + * + * @return UriInterface + * + * @throws \InvalidArgumentException + */ + public static function uriFor($uri) + { + if ($uri instanceof UriInterface) { + return $uri; + } + + if (is_string($uri)) { + return new Uri($uri); + } + + throw new \InvalidArgumentException('URI must be a string or UriInterface'); + } +} diff --git a/vendor/guzzlehttp/psr7/src/functions.php b/vendor/guzzlehttp/psr7/src/functions.php index 8e6dafe68..b0901fadd 100644 --- a/vendor/guzzlehttp/psr7/src/functions.php +++ b/vendor/guzzlehttp/psr7/src/functions.php @@ -1,10 +1,9 @@ getMethod() . ' ' - . $message->getRequestTarget()) - . ' HTTP/' . $message->getProtocolVersion(); - if (!$message->hasHeader('host')) { - $msg .= "\r\nHost: " . $message->getUri()->getHost(); - } - } elseif ($message instanceof ResponseInterface) { - $msg = 'HTTP/' . $message->getProtocolVersion() . ' ' - . $message->getStatusCode() . ' ' - . $message->getReasonPhrase(); - } else { - throw new \InvalidArgumentException('Unknown message type'); - } - - foreach ($message->getHeaders() as $name => $values) { - $msg .= "\r\n{$name}: " . implode(', ', $values); - } - - return "{$msg}\r\n\r\n" . $message->getBody(); + return Message::toString($message); } /** * Returns a UriInterface for the given value. * - * This function accepts a string or {@see Psr\Http\Message\UriInterface} and - * returns a UriInterface for the given value. If the value is already a - * `UriInterface`, it is returned as-is. + * This function accepts a string or UriInterface and returns a + * UriInterface for the given value. If the value is already a + * UriInterface, it is returned as-is. * * @param string|UriInterface $uri * * @return UriInterface + * * @throws \InvalidArgumentException + * + * @deprecated uri_for will be removed in guzzlehttp/psr7:2.0. Use Utils::uriFor instead. */ function uri_for($uri) { - if ($uri instanceof UriInterface) { - return $uri; - } elseif (is_string($uri)) { - return new Uri($uri); - } - - throw new \InvalidArgumentException('URI must be a string or UriInterface'); + return Utils::uriFor($uri); } /** @@ -69,86 +48,57 @@ function uri_for($uri) * - metadata: Array of custom metadata. * - size: Size of the stream. * - * @param resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource Entity body data + * This method accepts the following `$resource` types: + * - `Psr\Http\Message\StreamInterface`: Returns the value as-is. + * - `string`: Creates a stream object that uses the given string as the contents. + * - `resource`: Creates a stream object that wraps the given PHP stream resource. + * - `Iterator`: If the provided value implements `Iterator`, then a read-only + * stream object will be created that wraps the given iterable. Each time the + * stream is read from, data from the iterator will fill a buffer and will be + * continuously called until the buffer is equal to the requested read size. + * Subsequent read calls will first read from the buffer and then call `next` + * on the underlying iterator until it is exhausted. + * - `object` with `__toString()`: If the object has the `__toString()` method, + * the object will be cast to a string and then a stream will be returned that + * uses the string value. + * - `NULL`: When `null` is passed, an empty stream object is returned. + * - `callable` When a callable is passed, a read-only stream object will be + * created that invokes the given callable. The callable is invoked with the + * number of suggested bytes to read. The callable can return any number of + * bytes, but MUST return `false` when there is no more data to return. The + * stream object that wraps the callable will invoke the callable until the + * number of requested bytes are available. Any additional bytes will be + * buffered and used in subsequent reads. + * + * @param resource|string|int|float|bool|StreamInterface|callable|\Iterator|null $resource Entity body data * @param array $options Additional options * * @return StreamInterface + * * @throws \InvalidArgumentException if the $resource arg is not valid. + * + * @deprecated stream_for will be removed in guzzlehttp/psr7:2.0. Use Utils::streamFor instead. */ function stream_for($resource = '', array $options = []) { - if (is_scalar($resource)) { - $stream = fopen('php://temp', 'r+'); - if ($resource !== '') { - fwrite($stream, $resource); - fseek($stream, 0); - } - return new Stream($stream, $options); - } - - switch (gettype($resource)) { - case 'resource': - return new Stream($resource, $options); - case 'object': - if ($resource instanceof StreamInterface) { - return $resource; - } elseif ($resource instanceof \Iterator) { - return new PumpStream(function () use ($resource) { - if (!$resource->valid()) { - return false; - } - $result = $resource->current(); - $resource->next(); - return $result; - }, $options); - } elseif (method_exists($resource, '__toString')) { - return stream_for((string) $resource, $options); - } - break; - case 'NULL': - return new Stream(fopen('php://temp', 'r+'), $options); - } - - if (is_callable($resource)) { - return new PumpStream($resource, $options); - } - - throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource)); + return Utils::streamFor($resource, $options); } /** * Parse an array of header values containing ";" separated data into an - * array of associative arrays representing the header key value pair - * data of the header. When a parameter does not contain a value, but just + * array of associative arrays representing the header key value pair data + * of the header. When a parameter does not contain a value, but just * contains a key, this function will inject a key with a '' string value. * * @param string|array $header Header to parse into components. * * @return array Returns the parsed header values. + * + * @deprecated parse_header will be removed in guzzlehttp/psr7:2.0. Use Header::parse instead. */ function parse_header($header) { - static $trimmed = "\"' \n\t\r"; - $params = $matches = []; - - foreach (normalize_header($header) as $val) { - $part = []; - foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) { - if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) { - $m = $matches[0]; - if (isset($m[1])) { - $part[trim($m[0], $trimmed)] = trim($m[1], $trimmed); - } else { - $part[] = trim($m[0], $trimmed); - } - } - } - if ($part) { - $params[] = $part; - } - } - - return $params; + return Header::parse($header); } /** @@ -158,32 +108,20 @@ function parse_header($header) * @param string|array $header Header to normalize. * * @return array Returns the normalized header field values. + * + * @deprecated normalize_header will be removed in guzzlehttp/psr7:2.0. Use Header::normalize instead. */ function normalize_header($header) { - if (!is_array($header)) { - return array_map('trim', explode(',', $header)); - } - - $result = []; - foreach ($header as $value) { - foreach ((array) $value as $v) { - if (strpos($v, ',') === false) { - $result[] = $v; - continue; - } - foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $v) as $vv) { - $result[] = trim($vv); - } - } - } - - return $result; + return Header::normalize($header); } /** * Clone and modify a request with the given changes. * + * This method is useful for reducing the number of clones needed to mutate a + * message. + * * The changes can be one of: * - method: (string) Changes the HTTP method. * - set_headers: (array) Sets the given headers. @@ -197,72 +135,12 @@ function normalize_header($header) * @param array $changes Changes to apply. * * @return RequestInterface + * + * @deprecated modify_request will be removed in guzzlehttp/psr7:2.0. Use Utils::modifyRequest instead. */ function modify_request(RequestInterface $request, array $changes) { - if (!$changes) { - return $request; - } - - $headers = $request->getHeaders(); - - if (!isset($changes['uri'])) { - $uri = $request->getUri(); - } else { - // Remove the host header if one is on the URI - if ($host = $changes['uri']->getHost()) { - $changes['set_headers']['Host'] = $host; - - if ($port = $changes['uri']->getPort()) { - $standardPorts = ['http' => 80, 'https' => 443]; - $scheme = $changes['uri']->getScheme(); - if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) { - $changes['set_headers']['Host'] .= ':'.$port; - } - } - } - $uri = $changes['uri']; - } - - if (!empty($changes['remove_headers'])) { - $headers = _caseless_remove($changes['remove_headers'], $headers); - } - - if (!empty($changes['set_headers'])) { - $headers = _caseless_remove(array_keys($changes['set_headers']), $headers); - $headers = $changes['set_headers'] + $headers; - } - - if (isset($changes['query'])) { - $uri = $uri->withQuery($changes['query']); - } - - if ($request instanceof ServerRequestInterface) { - return (new ServerRequest( - isset($changes['method']) ? $changes['method'] : $request->getMethod(), - $uri, - $headers, - isset($changes['body']) ? $changes['body'] : $request->getBody(), - isset($changes['version']) - ? $changes['version'] - : $request->getProtocolVersion(), - $request->getServerParams() - )) - ->withParsedBody($request->getParsedBody()) - ->withQueryParams($request->getQueryParams()) - ->withCookieParams($request->getCookieParams()) - ->withUploadedFiles($request->getUploadedFiles()); - } - - return new Request( - isset($changes['method']) ? $changes['method'] : $request->getMethod(), - $uri, - $headers, - isset($changes['body']) ? $changes['body'] : $request->getBody(), - isset($changes['version']) - ? $changes['version'] - : $request->getProtocolVersion() - ); + return Utils::modifyRequest($request, $changes); } /** @@ -274,14 +152,12 @@ function modify_request(RequestInterface $request, array $changes) * @param MessageInterface $message Message to rewind * * @throws \RuntimeException + * + * @deprecated rewind_body will be removed in guzzlehttp/psr7:2.0. Use Message::rewindBody instead. */ function rewind_body(MessageInterface $message) { - $body = $message->getBody(); - - if ($body->tell()) { - $body->rewind(); - } + Message::rewindBody($message); } /** @@ -294,29 +170,14 @@ function rewind_body(MessageInterface $message) * @param string $mode Mode used to open the file * * @return resource + * * @throws \RuntimeException if the file cannot be opened + * + * @deprecated try_fopen will be removed in guzzlehttp/psr7:2.0. Use Utils::tryFopen instead. */ function try_fopen($filename, $mode) { - $ex = null; - set_error_handler(function () use ($filename, $mode, &$ex) { - $ex = new \RuntimeException(sprintf( - 'Unable to open %s using mode %s: %s', - $filename, - $mode, - func_get_args()[1] - )); - }); - - $handle = fopen($filename, $mode); - restore_error_handler(); - - if ($ex) { - /** @var $ex \RuntimeException */ - throw $ex; - } - - return $handle; + return Utils::tryFopen($filename, $mode); } /** @@ -326,37 +187,16 @@ function try_fopen($filename, $mode) * @param StreamInterface $stream Stream to read * @param int $maxLen Maximum number of bytes to read. Pass -1 * to read the entire stream. + * * @return string + * * @throws \RuntimeException on error. + * + * @deprecated copy_to_string will be removed in guzzlehttp/psr7:2.0. Use Utils::copyToString instead. */ function copy_to_string(StreamInterface $stream, $maxLen = -1) { - $buffer = ''; - - if ($maxLen === -1) { - while (!$stream->eof()) { - $buf = $stream->read(1048576); - // Using a loose equality here to match on '' and false. - if ($buf == null) { - break; - } - $buffer .= $buf; - } - return $buffer; - } - - $len = 0; - while (!$stream->eof() && $len < $maxLen) { - $buf = $stream->read($maxLen - $len); - // Using a loose equality here to match on '' and false. - if ($buf == null) { - break; - } - $buffer .= $buf; - $len = strlen($buffer); - } - - return $buffer; + return Utils::copyToString($stream, $maxLen); } /** @@ -369,92 +209,48 @@ function copy_to_string(StreamInterface $stream, $maxLen = -1) * to read the entire stream. * * @throws \RuntimeException on error. + * + * @deprecated copy_to_stream will be removed in guzzlehttp/psr7:2.0. Use Utils::copyToStream instead. */ -function copy_to_stream( - StreamInterface $source, - StreamInterface $dest, - $maxLen = -1 -) { - $bufferSize = 8192; - - if ($maxLen === -1) { - while (!$source->eof()) { - if (!$dest->write($source->read($bufferSize))) { - break; - } - } - } else { - $remaining = $maxLen; - while ($remaining > 0 && !$source->eof()) { - $buf = $source->read(min($bufferSize, $remaining)); - $len = strlen($buf); - if (!$len) { - break; - } - $remaining -= $len; - $dest->write($buf); - } - } +function copy_to_stream(StreamInterface $source, StreamInterface $dest, $maxLen = -1) +{ + return Utils::copyToStream($source, $dest, $maxLen); } /** - * Calculate a hash of a Stream + * Calculate a hash of a stream. + * + * This method reads the entire stream to calculate a rolling hash, based on + * PHP's `hash_init` functions. * * @param StreamInterface $stream Stream to calculate the hash for * @param string $algo Hash algorithm (e.g. md5, crc32, etc) * @param bool $rawOutput Whether or not to use raw output * * @return string Returns the hash of the stream + * * @throws \RuntimeException on error. + * + * @deprecated hash will be removed in guzzlehttp/psr7:2.0. Use Utils::hash instead. */ -function hash( - StreamInterface $stream, - $algo, - $rawOutput = false -) { - $pos = $stream->tell(); - - if ($pos > 0) { - $stream->rewind(); - } - - $ctx = hash_init($algo); - while (!$stream->eof()) { - hash_update($ctx, $stream->read(1048576)); - } - - $out = hash_final($ctx, (bool) $rawOutput); - $stream->seek($pos); - - return $out; +function hash(StreamInterface $stream, $algo, $rawOutput = false) +{ + return Utils::hash($stream, $algo, $rawOutput); } /** - * Read a line from the stream up to the maximum allowed buffer length + * Read a line from the stream up to the maximum allowed buffer length. * * @param StreamInterface $stream Stream to read from - * @param int $maxLength Maximum buffer length + * @param int|null $maxLength Maximum buffer length * * @return string + * + * @deprecated readline will be removed in guzzlehttp/psr7:2.0. Use Utils::readLine instead. */ function readline(StreamInterface $stream, $maxLength = null) { - $buffer = ''; - $size = 0; - - while (!$stream->eof()) { - // Using a loose equality here to match on '' and false. - if (null == ($byte = $stream->read(1))) { - return $buffer; - } - $buffer .= $byte; - // Break when a new line is found or the max length - 1 is reached - if ($byte === "\n" || ++$size === $maxLength - 1) { - break; - } - } - - return $buffer; + return Utils::readLine($stream, $maxLength); } /** @@ -463,26 +259,12 @@ function readline(StreamInterface $stream, $maxLength = null) * @param string $message Request message string. * * @return Request + * + * @deprecated parse_request will be removed in guzzlehttp/psr7:2.0. Use Message::parseRequest instead. */ function parse_request($message) { - $data = _parse_message($message); - $matches = []; - if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) { - throw new \InvalidArgumentException('Invalid request string'); - } - $parts = explode(' ', $data['start-line'], 3); - $version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1'; - - $request = new Request( - $parts[0], - $matches[1] === '/' ? _parse_request_uri($parts[1], $data['headers']) : $parts[1], - $data['headers'], - $data['body'], - $version - ); - - return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]); + return Message::parseRequest($message); } /** @@ -491,139 +273,67 @@ function parse_request($message) * @param string $message Response message string. * * @return Response + * + * @deprecated parse_response will be removed in guzzlehttp/psr7:2.0. Use Message::parseResponse instead. */ function parse_response($message) { - $data = _parse_message($message); - // According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space - // between status-code and reason-phrase is required. But browsers accept - // responses without space and reason as well. - if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) { - throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']); - } - $parts = explode(' ', $data['start-line'], 3); - - return new Response( - $parts[1], - $data['headers'], - $data['body'], - explode('/', $parts[0])[1], - isset($parts[2]) ? $parts[2] : null - ); + return Message::parseResponse($message); } /** * Parse a query string into an associative array. * - * If multiple values are found for the same key, the value of that key - * value pair will become an array. This function does not parse nested - * PHP style arrays into an associative array (e.g., foo[a]=1&foo[b]=2 will - * be parsed into ['foo[a]' => '1', 'foo[b]' => '2']). + * If multiple values are found for the same key, the value of that key value + * pair will become an array. This function does not parse nested PHP style + * arrays into an associative array (e.g., `foo[a]=1&foo[b]=2` will be parsed + * into `['foo[a]' => '1', 'foo[b]' => '2'])`. * * @param string $str Query string to parse * @param int|bool $urlEncoding How the query string is encoded * * @return array + * + * @deprecated parse_query will be removed in guzzlehttp/psr7:2.0. Use Query::parse instead. */ function parse_query($str, $urlEncoding = true) { - $result = []; - - if ($str === '') { - return $result; - } - - if ($urlEncoding === true) { - $decoder = function ($value) { - return rawurldecode(str_replace('+', ' ', $value)); - }; - } elseif ($urlEncoding === PHP_QUERY_RFC3986) { - $decoder = 'rawurldecode'; - } elseif ($urlEncoding === PHP_QUERY_RFC1738) { - $decoder = 'urldecode'; - } else { - $decoder = function ($str) { return $str; }; - } - - foreach (explode('&', $str) as $kvp) { - $parts = explode('=', $kvp, 2); - $key = $decoder($parts[0]); - $value = isset($parts[1]) ? $decoder($parts[1]) : null; - if (!isset($result[$key])) { - $result[$key] = $value; - } else { - if (!is_array($result[$key])) { - $result[$key] = [$result[$key]]; - } - $result[$key][] = $value; - } - } - - return $result; + return Query::parse($str, $urlEncoding); } /** * Build a query string from an array of key value pairs. * - * This function can use the return value of parse_query() to build a query + * This function can use the return value of `parse_query()` to build a query * string. This function does not modify the provided keys when an array is - * encountered (like http_build_query would). + * encountered (like `http_build_query()` would). * * @param array $params Query string parameters. * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986 * to encode using RFC3986, or PHP_QUERY_RFC1738 * to encode using RFC1738. + * * @return string + * + * @deprecated build_query will be removed in guzzlehttp/psr7:2.0. Use Query::build instead. */ function build_query(array $params, $encoding = PHP_QUERY_RFC3986) { - if (!$params) { - return ''; - } - - if ($encoding === false) { - $encoder = function ($str) { return $str; }; - } elseif ($encoding === PHP_QUERY_RFC3986) { - $encoder = 'rawurlencode'; - } elseif ($encoding === PHP_QUERY_RFC1738) { - $encoder = 'urlencode'; - } else { - throw new \InvalidArgumentException('Invalid type'); - } - - $qs = ''; - foreach ($params as $k => $v) { - $k = $encoder($k); - if (!is_array($v)) { - $qs .= $k; - if ($v !== null) { - $qs .= '=' . $encoder($v); - } - $qs .= '&'; - } else { - foreach ($v as $vv) { - $qs .= $k; - if ($vv !== null) { - $qs .= '=' . $encoder($vv); - } - $qs .= '&'; - } - } - } - - return $qs ? (string) substr($qs, 0, -1) : ''; + return Query::build($params, $encoding); } /** * Determines the mimetype of a file by looking at its extension. * - * @param $filename + * @param string $filename * - * @return null|string + * @return string|null + * + * @deprecated mimetype_from_filename will be removed in guzzlehttp/psr7:2.0. Use MimeType::fromFilename instead. */ function mimetype_from_filename($filename) { - return mimetype_from_extension(pathinfo($filename, PATHINFO_EXTENSION)); + return MimeType::fromFilename($filename); } /** @@ -632,119 +342,13 @@ function mimetype_from_filename($filename) * @param $extension string The file extension. * * @return string|null + * * @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types + * @deprecated mimetype_from_extension will be removed in guzzlehttp/psr7:2.0. Use MimeType::fromExtension instead. */ function mimetype_from_extension($extension) { - static $mimetypes = [ - '3gp' => 'video/3gpp', - '7z' => 'application/x-7z-compressed', - 'aac' => 'audio/x-aac', - 'ai' => 'application/postscript', - 'aif' => 'audio/x-aiff', - 'asc' => 'text/plain', - 'asf' => 'video/x-ms-asf', - 'atom' => 'application/atom+xml', - 'avi' => 'video/x-msvideo', - 'bmp' => 'image/bmp', - 'bz2' => 'application/x-bzip2', - 'cer' => 'application/pkix-cert', - 'crl' => 'application/pkix-crl', - 'crt' => 'application/x-x509-ca-cert', - 'css' => 'text/css', - 'csv' => 'text/csv', - 'cu' => 'application/cu-seeme', - 'deb' => 'application/x-debian-package', - 'doc' => 'application/msword', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'dvi' => 'application/x-dvi', - 'eot' => 'application/vnd.ms-fontobject', - 'eps' => 'application/postscript', - 'epub' => 'application/epub+zip', - 'etx' => 'text/x-setext', - 'flac' => 'audio/flac', - 'flv' => 'video/x-flv', - 'gif' => 'image/gif', - 'gz' => 'application/gzip', - 'htm' => 'text/html', - 'html' => 'text/html', - 'ico' => 'image/x-icon', - 'ics' => 'text/calendar', - 'ini' => 'text/plain', - 'iso' => 'application/x-iso9660-image', - 'jar' => 'application/java-archive', - 'jpe' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'js' => 'text/javascript', - 'json' => 'application/json', - 'latex' => 'application/x-latex', - 'log' => 'text/plain', - 'm4a' => 'audio/mp4', - 'm4v' => 'video/mp4', - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mov' => 'video/quicktime', - 'mkv' => 'video/x-matroska', - 'mp3' => 'audio/mpeg', - 'mp4' => 'video/mp4', - 'mp4a' => 'audio/mp4', - 'mp4v' => 'video/mp4', - 'mpe' => 'video/mpeg', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpg4' => 'video/mp4', - 'oga' => 'audio/ogg', - 'ogg' => 'audio/ogg', - 'ogv' => 'video/ogg', - 'ogx' => 'application/ogg', - 'pbm' => 'image/x-portable-bitmap', - 'pdf' => 'application/pdf', - 'pgm' => 'image/x-portable-graymap', - 'png' => 'image/png', - 'pnm' => 'image/x-portable-anymap', - 'ppm' => 'image/x-portable-pixmap', - 'ppt' => 'application/vnd.ms-powerpoint', - 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'ps' => 'application/postscript', - 'qt' => 'video/quicktime', - 'rar' => 'application/x-rar-compressed', - 'ras' => 'image/x-cmu-raster', - 'rss' => 'application/rss+xml', - 'rtf' => 'application/rtf', - 'sgm' => 'text/sgml', - 'sgml' => 'text/sgml', - 'svg' => 'image/svg+xml', - 'swf' => 'application/x-shockwave-flash', - 'tar' => 'application/x-tar', - 'tif' => 'image/tiff', - 'tiff' => 'image/tiff', - 'torrent' => 'application/x-bittorrent', - 'ttf' => 'application/x-font-ttf', - 'txt' => 'text/plain', - 'wav' => 'audio/x-wav', - 'webm' => 'video/webm', - 'webp' => 'image/webp', - 'wma' => 'audio/x-ms-wma', - 'wmv' => 'video/x-ms-wmv', - 'woff' => 'application/x-font-woff', - 'wsdl' => 'application/wsdl+xml', - 'xbm' => 'image/x-xbitmap', - 'xls' => 'application/vnd.ms-excel', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'xml' => 'application/xml', - 'xpm' => 'image/x-xpixmap', - 'xwd' => 'image/x-xwindowdump', - 'yaml' => 'text/yaml', - 'yml' => 'text/yaml', - 'zip' => 'application/zip', - ]; - - $extension = strtolower($extension); - - return isset($mimetypes[$extension]) - ? $mimetypes[$extension] - : null; + return MimeType::fromExtension($extension); } /** @@ -757,61 +361,14 @@ function mimetype_from_extension($extension) * @param string $message HTTP request or response to parse. * * @return array + * * @internal + * + * @deprecated _parse_message will be removed in guzzlehttp/psr7:2.0. Use Message::parseMessage instead. */ function _parse_message($message) { - if (!$message) { - throw new \InvalidArgumentException('Invalid message'); - } - - $message = ltrim($message, "\r\n"); - - $messageParts = preg_split("/\r?\n\r?\n/", $message, 2); - - if ($messageParts === false || count($messageParts) !== 2) { - throw new \InvalidArgumentException('Invalid message: Missing header delimiter'); - } - - list($rawHeaders, $body) = $messageParts; - $rawHeaders .= "\r\n"; // Put back the delimiter we split previously - $headerParts = preg_split("/\r?\n/", $rawHeaders, 2); - - if ($headerParts === false || count($headerParts) !== 2) { - throw new \InvalidArgumentException('Invalid message: Missing status line'); - } - - list($startLine, $rawHeaders) = $headerParts; - - if (preg_match("/(?:^HTTP\/|^[A-Z]+ \S+ HTTP\/)(\d+(?:\.\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') { - // Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0 - $rawHeaders = preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders); - } - - /** @var array[] $headerLines */ - $count = preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, PREG_SET_ORDER); - - // If these aren't the same, then one line didn't match and there's an invalid header. - if ($count !== substr_count($rawHeaders, "\n")) { - // Folding is deprecated, see https://tools.ietf.org/html/rfc7230#section-3.2.4 - if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) { - throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding'); - } - - throw new \InvalidArgumentException('Invalid header syntax'); - } - - $headers = []; - - foreach ($headerLines as $headerLine) { - $headers[$headerLine[1]][] = $headerLine[2]; - } - - return [ - 'start-line' => $startLine, - 'headers' => $headers, - 'body' => $body, - ]; + return Message::parseMessage($message); } /** @@ -821,79 +378,45 @@ function _parse_message($message) * @param array $headers Array of headers (each value an array). * * @return string + * * @internal + * + * @deprecated _parse_request_uri will be removed in guzzlehttp/psr7:2.0. Use Message::parseRequestUri instead. */ function _parse_request_uri($path, array $headers) { - $hostKey = array_filter(array_keys($headers), function ($k) { - return strtolower($k) === 'host'; - }); - - // If no host is found, then a full URI cannot be constructed. - if (!$hostKey) { - return $path; - } - - $host = $headers[reset($hostKey)][0]; - $scheme = substr($host, -4) === ':443' ? 'https' : 'http'; - - return $scheme . '://' . $host . '/' . ltrim($path, '/'); + return Message::parseRequestUri($path, $headers); } /** - * Get a short summary of the message body + * Get a short summary of the message body. * * Will return `null` if the response is not printable. * * @param MessageInterface $message The message to get the body summary * @param int $truncateAt The maximum allowed size of the summary * - * @return null|string + * @return string|null + * + * @deprecated get_message_body_summary will be removed in guzzlehttp/psr7:2.0. Use Message::bodySummary instead. */ function get_message_body_summary(MessageInterface $message, $truncateAt = 120) { - $body = $message->getBody(); - - if (!$body->isSeekable() || !$body->isReadable()) { - return null; - } - - $size = $body->getSize(); - - if ($size === 0) { - return null; - } - - $summary = $body->read($truncateAt); - $body->rewind(); - - if ($size > $truncateAt) { - $summary .= ' (truncated...)'; - } - - // Matches any printable character, including unicode characters: - // letters, marks, numbers, punctuation, spacing, and separators. - if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) { - return null; - } - - return $summary; + return Message::bodySummary($message, $truncateAt); } -/** @internal */ +/** + * Remove the items given by the keys, case insensitively from the data. + * + * @param iterable $keys + * + * @return array + * + * @internal + * + * @deprecated _caseless_remove will be removed in guzzlehttp/psr7:2.0. Use Utils::caselessRemove instead. + */ function _caseless_remove($keys, array $data) { - $result = []; - - foreach ($keys as &$key) { - $key = strtolower($key); - } - - foreach ($data as $k => $v) { - if (!in_array(strtolower($k), $keys)) { - $result[$k] = $v; - } - } - - return $result; + return Utils::caselessRemove($keys, $data); } diff --git a/vendor/nicolab/php-ftp-client/README.md b/vendor/nicolab/php-ftp-client/README.md index 227314ce0..82d6cd4f7 100644 --- a/vendor/nicolab/php-ftp-client/README.md +++ b/vendor/nicolab/php-ftp-client/README.md @@ -218,7 +218,7 @@ $ftp->connect($host); $ftp->login($login, $password); // remove the old files -$ftp->removeByTime('/www/mysite.com/demo', time() - 86400)); +$ftp->removeByTime('/www/mysite.com/demo', time() - 86400); // search PNG files $ftp->search('/(.*)\.png$/i'); diff --git a/vendor/nicolab/php-ftp-client/src/FtpClient/FtpClient.php b/vendor/nicolab/php-ftp-client/src/FtpClient/FtpClient.php index 0cb70469e..dd069cb5f 100644 --- a/vendor/nicolab/php-ftp-client/src/FtpClient/FtpClient.php +++ b/vendor/nicolab/php-ftp-client/src/FtpClient/FtpClient.php @@ -17,6 +17,7 @@ * The FTP and SSL-FTP client for PHP. * * @method bool alloc(int $filesize, string &$result = null) Allocates space for a file to be uploaded + * @method bool append(string $remote_file, string $local_file, int $mode = FTP_BINARY) Append the contents of a file to another file on the FTP server * @method bool cdup() Changes to the parent directory * @method bool chdir(string $directory) Changes the current directory on a FTP server * @method int chmod(int $mode, string $filename) Set permissions on a file via FTP @@ -33,7 +34,6 @@ * @method int nb_fput(string $remote_file, resource $handle, int $mode, int $startpos = 0) Stores a file from an open file to the FTP server (non-blocking) * @method int nb_get(string $local_file, string $remote_file, int $mode, int $resumepos = 0) Retrieves a file from the FTP server and writes it to a local file (non-blocking) * @method int nb_put(string $remote_file, string $local_file, int $mode, int $startpos = 0) Stores a file on the FTP server (non-blocking) - * @method array nlist(string $remote_dir) Returns a list of file names in the given directory; remote_dir parameter may also include arguments * @method bool pasv(bool $pasv) Turns passive mode on or off * @method bool put(string $remote_file, string $local_file, int $mode, int $startpos = 0) Uploads a file to the FTP server * @method string pwd() Returns the current directory name @@ -356,7 +356,7 @@ public function nlist($directory = '.', $recursive = false, $filter = 'sort') * * @param string $directory The directory * @param bool $recursive - * @return array + * @return bool */ public function mkdir($directory, $recursive = false) { @@ -453,8 +453,19 @@ public function remove($path, $recursive = false) try { if (@$this->ftp->delete($path) - or ($this->isDir($path) and $this->rmdir($path, $recursive))) { + or ($this->isDir($path) + and $this->rmdir($path, $recursive))) { return true; + } else { + // in special cases the delete can fail (for example, at Symfony's "r+e.gex[c]a(r)s" directory) + $newPath = preg_replace('/[^A-Za-z0-9\/]/', '', $path); + if ($this->rename($path, $newPath)) { + if (@$this->ftp->delete($newPath) + or ($this->isDir($newPath) + and $this->rmdir($newPath, $recursive))) { + return true; + } + } } return false; @@ -569,7 +580,7 @@ public function getContent($remote_file, $mode = FTP_BINARY, $resumepos = 0) { $handle = fopen('php://temp', 'r+'); - if ($this->fget($handle, $remote_file, $mode, $resumepos)) { + if ($this->ftp->fget($handle, $remote_file, $mode, $resumepos)) { rewind($handle); return stream_get_contents($handle); } @@ -641,7 +652,6 @@ public function putAll($source_directory, $target_directory, $mode = FTP_BINARY) // do the following if it is a directory if (is_dir($source_directory.'/'.$file)) { - if (!$this->isDir($target_directory.'/'.$file)) { // create directories that do not yet exist @@ -744,7 +754,7 @@ public function rawlist($directory = '.', $recursive = false) $chunks = preg_split("/\s+/", $item); // if not "name" - if (empty($chunks[8]) || $chunks[8] == '.' || $chunks[8] == '..') { + if (!isset($chunks[8]) || strlen($chunks[8]) === 0 || $chunks[8] == '.' || $chunks[8] == '..') { continue; } @@ -789,7 +799,7 @@ public function rawlist($directory = '.', $recursive = false) $chunks = preg_split("/\s+/", $item); // if not "name" - if (empty($chunks[8]) || $chunks[8] == '.' || $chunks[8] == '..') { + if (!isset($chunks[8]) || strlen($chunks[8]) === 0 || $chunks[8] == '.' || $chunks[8] == '..') { continue; } diff --git a/vendor/nicolab/php-ftp-client/src/FtpClient/FtpWrapper.php b/vendor/nicolab/php-ftp-client/src/FtpClient/FtpWrapper.php index 7c1852835..3a0d45f59 100644 --- a/vendor/nicolab/php-ftp-client/src/FtpClient/FtpWrapper.php +++ b/vendor/nicolab/php-ftp-client/src/FtpClient/FtpWrapper.php @@ -27,7 +27,7 @@ * @method bool get(string $local_file, string $remote_file, int $mode, int $resumepos = 0) Downloads a file from the FTP server * @method bool login(string $username, string $password) Logs in to an FTP connection * @method int mdtm(string $remote_file) Returns the last modified time of the given file - * @method string mkdir(string $directory) Creates a directory + * @method bool mkdir(string $directory) Creates a directory * @method array mlsd(string $remote_dir) Returns a list of files in the given directory * @method int nb_continue() Continues retrieving/sending a file (non-blocking) * @method int nb_fget(resource $handle, string $remote_file, int $mode, int $resumepos = 0) Retrieves a file from the FTP server and writes it to an open file (non-blocking) diff --git a/vendor/phpmailer/phpmailer/README.md b/vendor/phpmailer/phpmailer/README.md index c287e307a..fa27d2f68 100644 --- a/vendor/phpmailer/phpmailer/README.md +++ b/vendor/phpmailer/phpmailer/README.md @@ -1,46 +1,45 @@ ![PHPMailer](https://raw.github.com/PHPMailer/PHPMailer/master/examples/images/phpmailer.png) -# PHPMailer - A full-featured email creation and transfer class for PHP +# PHPMailer – A full-featured email creation and transfer class for PHP -Build status: [![Build Status](https://travis-ci.org/PHPMailer/PHPMailer.svg)](https://travis-ci.org/PHPMailer/PHPMailer) -[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/PHPMailer/PHPMailer/badges/quality-score.png?s=3758e21d279becdf847a557a56a3ed16dfec9d5d)](https://scrutinizer-ci.com/g/PHPMailer/PHPMailer/) -[![Code Coverage](https://scrutinizer-ci.com/g/PHPMailer/PHPMailer/badges/coverage.png?s=3fe6ca5fe8cd2cdf96285756e42932f7ca256962)](https://scrutinizer-ci.com/g/PHPMailer/PHPMailer/) +[![Test status](https://github.com/PHPMailer/PHPMailer/workflows/Tests/badge.svg)](https://github.com/PHPMailer/PHPMailer/actions) [![Latest Stable Version](https://poser.pugx.org/phpmailer/phpmailer/v/stable.svg)](https://packagist.org/packages/phpmailer/phpmailer) [![Total Downloads](https://poser.pugx.org/phpmailer/phpmailer/downloads)](https://packagist.org/packages/phpmailer/phpmailer) [![License](https://poser.pugx.org/phpmailer/phpmailer/license.svg)](https://packagist.org/packages/phpmailer/phpmailer) [![API Docs](https://github.com/phpmailer/phpmailer/workflows/Docs/badge.svg)](https://phpmailer.github.io/PHPMailer/) -[![Latest Stable Version](https://poser.pugx.org/phpmailer/phpmailer/v/stable.svg)](https://packagist.org/packages/phpmailer/phpmailer) [![Total Downloads](https://poser.pugx.org/phpmailer/phpmailer/downloads)](https://packagist.org/packages/phpmailer/phpmailer) [![Latest Unstable Version](https://poser.pugx.org/phpmailer/phpmailer/v/unstable.svg)](https://packagist.org/packages/phpmailer/phpmailer) [![License](https://poser.pugx.org/phpmailer/phpmailer/license.svg)](https://packagist.org/packages/phpmailer/phpmailer) [![API Docs](https://github.com/phpmailer/phpmailer/workflows/Docs/badge.svg)](http://phpmailer.github.io/PHPMailer/) - -## Class Features +## Features - Probably the world's most popular code for sending email from PHP! - Used by many open-source projects: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! and many more -- Integrated SMTP support - send without a local mail server +- Integrated SMTP support – send without a local mail server - Send emails with multiple To, CC, BCC and Reply-to addresses - Multipart/alternative emails for mail clients that do not read HTML email - Add attachments, including inline - Support for UTF-8 content and 8bit, base64, binary, and quoted-printable encodings -- SMTP authentication with LOGIN, PLAIN, CRAM-MD5, and XOAUTH2 mechanisms over SSL and SMTP+STARTTLS transports +- SMTP authentication with LOGIN, PLAIN, CRAM-MD5, and XOAUTH2 mechanisms over SMTPS and SMTP+STARTTLS transports - Validates email addresses automatically -- Protect against header injection attacks +- Protects against header injection attacks - Error messages in over 50 languages! - DKIM and S/MIME signing support -- Compatible with PHP 5.5 and later +- Compatible with PHP 5.5 and later, including PHP 8.0 - Namespaced to prevent name clashes - Much more! ## Why you might need it -Many PHP developers need to send email from their code. The only PHP function that supports this is [`mail()`](https://www.php.net/manual/en/function.mail.php). However, it does not provide any assistance for making use of popular features such as encryption, authentication, HTML messages, and attachments. +Many PHP developers need to send email from their code. The only PHP function that supports this directly is [`mail()`](https://www.php.net/manual/en/function.mail.php). However, it does not provide any assistance for making use of popular features such as encryption, authentication, HTML messages, and attachments. + +Formatting email correctly is surprisingly difficult. There are myriad overlapping (and conflicting) standards, requiring tight adherence to horribly complicated formatting and encoding rules – the vast majority of code that you'll find online that uses the `mail()` function directly is just plain wrong, if not unsafe! -Formatting email correctly is surprisingly difficult. There are myriad overlapping RFCs, requiring tight adherence to horribly complicated formatting and encoding rules – the vast majority of code that you'll find online that uses the `mail()` function directly is just plain wrong! -*Please* don't be tempted to do it yourself – if you don't use PHPMailer, there are many other excellent libraries that you should look at before rolling your own. Try [SwiftMailer](https://swiftmailer.symfony.com/), [Zend/Mail](https://zendframework.github.io/zend-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail) etc. +The PHP `mail()` function usually sends via a local mail server, typically fronted by a `sendmail` binary on Linux, BSD, and macOS platforms, however, Windows usually doesn't include a local mail server; PHPMailer's integrated SMTP client allows email sending on all platforms without needing a local mail server. Be aware though, that the `mail()` function should be avoided when possible; it's both faster and [safer](https://exploitbox.io/paper/Pwning-PHP-Mail-Function-For-Fun-And-RCE.html) to use SMTP to localhost. -The PHP `mail()` function usually sends via a local mail server, typically fronted by a `sendmail` binary on Linux, BSD, and macOS platforms, however, Windows usually doesn't include a local mail server; PHPMailer's integrated SMTP implementation allows email sending on Windows platforms without a local mail server. +*Please* don't be tempted to do it yourself – if you don't use PHPMailer, there are many other excellent libraries that +you should look at before rolling your own. Try [SwiftMailer](https://swiftmailer.symfony.com/) +, [Laminas/Mail](https://docs.laminas.dev/laminas-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail) etc. ## License -This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read LICENSE for information on the software availability and distribution. +This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read [LICENSE](https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE) for information on the software availability and distribution. ## Installation & loading PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file: ```json -"phpmailer/phpmailer": "~6.1" +"phpmailer/phpmailer": "^6.2" ``` or run @@ -53,7 +52,8 @@ Note that the `vendor` folder and the `vendor/autoload.php` script are generated If you want to use the Gmail XOAUTH2 authentication class, you will also need to add a dependency on the `league/oauth2-client` package in your `composer.json`. -Alternatively, if you're not using Composer, copy the contents of the PHPMailer folder into one of the `include_path` directories specified in your PHP configuration and load each class file manually: +Alternatively, if you're not using Composer, you +can [download PHPMailer as a zip file](https://github.com/PHPMailer/PHPMailer/archive/master.zip), (note that docs and examples are not included in the zip file), then copy the contents of the PHPMailer folder into one of the `include_path` directories specified in your PHP configuration and load each class file manually: ```php SMTPDebug = SMTP::DEBUG_SERVER; // Enable verbose debug output - $mail->isSMTP(); // Send using SMTP - $mail->Host = 'smtp1.example.com'; // Set the SMTP server to send through - $mail->SMTPAuth = true; // Enable SMTP authentication - $mail->Username = 'user@example.com'; // SMTP username - $mail->Password = 'secret'; // SMTP password - $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged - $mail->Port = 587; // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above + $mail->SMTPDebug = SMTP::DEBUG_SERVER; //Enable verbose debug output + $mail->isSMTP(); //Send using SMTP + $mail->Host = 'smtp.example.com'; //Set the SMTP server to send through + $mail->SMTPAuth = true; //Enable SMTP authentication + $mail->Username = 'user@example.com'; //SMTP username + $mail->Password = 'secret'; //SMTP password + $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; //Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged + $mail->Port = 587; //TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above //Recipients $mail->setFrom('from@example.com', 'Mailer'); - $mail->addAddress('joe@example.net', 'Joe User'); // Add a recipient - $mail->addAddress('ellen@example.com'); // Name is optional + $mail->addAddress('joe@example.net', 'Joe User'); //Add a recipient + $mail->addAddress('ellen@example.com'); //Name is optional $mail->addReplyTo('info@example.com', 'Information'); $mail->addCC('cc@example.com'); $mail->addBCC('bcc@example.com'); - // Attachments - $mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments - $mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name + //Attachments + $mail->addAttachment('/var/tmp/file.tar.gz'); //Add attachments + $mail->addAttachment('/tmp/image.jpg', 'new.jpg'); //Optional name - // Content - $mail->isHTML(true); // Set email format to HTML + //Content + $mail->isHTML(true); //Set email format to HTML $mail->Subject = 'Here is the subject'; $mail->Body = 'This is the HTML message body in bold!'; $mail->AltBody = 'This is the body in plain text for non-HTML mail clients'; @@ -130,7 +128,7 @@ try { } ``` -You'll find plenty more to play with in the [examples](https://github.com/PHPMailer/PHPMailer/tree/master/examples) folder. +You'll find plenty to play with in the [examples](https://github.com/PHPMailer/PHPMailer/tree/master/examples) folder, which covers many common scenarios including sending through gmail, building contact forms, sending to mailing lists, and more. If you are re-using the instance (e.g. when sending to a mailing list), you may need to clear the recipient list to avoid sending duplicate messages. See [the mailing list example](https://github.com/PHPMailer/PHPMailer/blob/master/examples/mailing_list.phps) for further guidance. @@ -140,49 +138,43 @@ That's it. You should now be ready to use PHPMailer! PHPMailer defaults to English, but in the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder you'll find many translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this: ```php -// To load the French version +//To load the French version $mail->setLanguage('fr', '/optional/path/to/language/directory/'); ``` -We welcome corrections and new languages - if you're looking for corrections to do, run the [PHPMailerLangTest.php](https://github.com/PHPMailer/PHPMailer/tree/master/test/PHPMailerLangTest.php) script in the tests folder and it will show any missing translations. +We welcome corrections and new languages – if you're looking for corrections, run the [PHPMailerLangTest.php](https://github.com/PHPMailer/PHPMailer/tree/master/test/PHPMailerLangTest.php) script in the tests folder and it will show any missing translations. ## Documentation -Start reading at the [GitHub wiki](https://github.com/PHPMailer/PHPMailer/wiki). If you're having trouble, this should be the first place you look as it's the most frequently updated. +Start reading at the [GitHub wiki](https://github.com/PHPMailer/PHPMailer/wiki). If you're having trouble, head for [the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting) as it's frequently updated. Examples of how to use PHPMailer for common scenarios can be found in the [examples](https://github.com/PHPMailer/PHPMailer/tree/master/examples) folder. If you're looking for a good starting point, we recommend you start with [the Gmail example](https://github.com/PHPMailer/PHPMailer/tree/master/examples/gmail.phps). -Note that in order to reduce PHPMailer's deployed code footprint, the examples are no longer included if you load PHPMailer via Composer or via [GitHub's zip file download](https://github.com/PHPMailer/PHPMailer/archive/master.zip), so you'll need to either clone the git repository or use the above links to get to the examples directly. +To reduce PHPMailer's deployed code footprint, examples are not included if you load PHPMailer via Composer or via [GitHub's zip file download](https://github.com/PHPMailer/PHPMailer/archive/master.zip), so you'll need to either clone the git repository or use the above links to get to the examples directly. -Complete generated API documentation is [available online](http://phpmailer.github.io/PHPMailer/). +Complete generated API documentation is [available online](https://phpmailer.github.io/PHPMailer/). -You can generate complete API-level documentation by running `phpdoc` in the top-level folder, and documentation will appear in the `docs` folder, though you'll need to have [PHPDocumentor](http://www.phpdoc.org) installed. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/blob/master/test/PHPMailerTest.php) a good source of how to do various operations such as encryption. +You can generate complete API-level documentation by running `phpdoc` in the top-level folder, and documentation will appear in the `docs` folder, though you'll need to have [PHPDocumentor](http://www.phpdoc.org) installed. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/blob/master/test/PHPMailerTest.php) a good reference for how to do various operations such as encryption. If the documentation doesn't cover what you need, search the [many questions on Stack Overflow](http://stackoverflow.com/questions/tagged/phpmailer), and before you ask a question about "SMTP Error: Could not connect to SMTP host.", [read the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting). ## Tests -There is a PHPUnit test script in the [test](https://github.com/PHPMailer/PHPMailer/tree/master/test/) folder. PHPMailer uses PHPUnit 4.8 - we would use 5.x but we need to run on PHP 5.5. +[PHPMailer tests](https://github.com/PHPMailer/PHPMailer/tree/master/test/) use PHPUnit 9, with [a polyfill](https://github.com/Yoast/PHPUnit-Polyfills) to let 9-style tests run on older PHPUnit and PHP versions. -Build status: [![Build Status](https://travis-ci.org/PHPMailer/PHPMailer.svg)](https://travis-ci.org/PHPMailer/PHPMailer) +[![Test status](https://github.com/PHPMailer/PHPMailer/workflows/Tests/badge.svg)](https://github.com/PHPMailer/PHPMailer/actions) If this isn't passing, is there something you can do to help? ## Security -Please disclose any vulnerabilities found responsibly - report any security problems found to the maintainers privately. - -PHPMailer versions prior to 5.2.22 (released January 9th 2017) have a local file disclosure vulnerability, [CVE-2017-5223](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-5223). If content passed into `msgHTML()` is sourced from unfiltered user input, relative paths can map to absolute local file paths and added as attachments. Also note that `addAttachment` (just like `file_get_contents`, `passthru`, `unlink`, etc) should not be passed user-sourced params either! Reported by Yongxiang Li of Asiasecurity. - -PHPMailer versions prior to 5.2.20 (released December 28th 2016) are vulnerable to [CVE-2016-10045](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10045) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10045-Vuln-Patch-Bypass.html), and patched by Paul Buonopane (@Zenexer). +Please disclose any vulnerabilities found responsibly – report security issues to the maintainers privately. -PHPMailer versions prior to 5.2.18 (released December 2016) are vulnerable to [CVE-2016-10033](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10033) a critical remote code execution vulnerability, responsibly reported by [Dawid Golunski](http://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html). - -See [SECURITY](https://github.com/PHPMailer/PHPMailer/tree/master/SECURITY.md) for more detail on security issues. +See [SECURITY](https://github.com/PHPMailer/PHPMailer/tree/master/SECURITY.md) and [PHPMailer's security advisories on GitHub](https://github.com/PHPMailer/PHPMailer/security). ## Contributing Please submit bug reports, suggestions and pull requests to the [GitHub issue tracker](https://github.com/PHPMailer/PHPMailer/issues). We're particularly interested in fixing edge-cases, expanding test coverage and updating translations. -If you found a mistake in the docs, or want to add something, go ahead and amend the wiki - anyone can edit it. +If you found a mistake in the docs, or want to add something, go ahead and amend the wiki – anyone can edit it. If you have git clones from prior to the move to the PHPMailer GitHub organisation, you'll need to update any remote URLs referencing the old GitHub location with a command like this from within your clone: @@ -193,27 +185,36 @@ git remote set-url upstream https://github.com/PHPMailer/PHPMailer.git Please *don't* use the SourceForge or Google Code projects any more; they are obsolete and no longer maintained. ## Sponsorship -Development time and resources for PHPMailer are provided by [Smartmessages.net](https://info.smartmessages.net/), a powerful email marketing system. +Development time and resources for PHPMailer are provided by [Smartmessages.net](https://info.smartmessages.net/), the world's only privacy-first email marketing system. + +Smartmessages.net privacy-first email marketing logo + +Donations are very welcome, whether in beer 🍺, T-shirts 👕, or cold, hard cash 💰. Sponsorship through GitHub is a simple and convenient way to say "thank you" to PHPMailer's maintainers and contributors – just click the "Sponsor" button [on the project page](https://github.com/PHPMailer/PHPMailer). If your company uses PHPMailer, consider taking part in Tidelift's enterprise support programme. + +## PHPMailer For Enterprise -Smartmessages email marketing +Available as part of the Tidelift Subscription. -Other contributions are gladly received, whether in beer 🍺, T-shirts 👕, Amazon wishlist raids, or cold, hard cash 💰. If you'd like to donate to say "thank you" to maintainers or contributors, please contact them through individual profile pages via [the contributors page](https://github.com/PHPMailer/PHPMailer/graphs/contributors). +The maintainers of PHPMailer and thousands of other packages are working with Tidelift to deliver commercial +support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and +improve code health, while paying the maintainers of the exact packages you +use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-phpmailer-phpmailer?utm_source=packagist-phpmailer-phpmailer&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) ## Changelog See [changelog](changelog.md). ## History - PHPMailer was originally written in 2001 by Brent R. Matzelle as a [SourceForge project](http://sourceforge.net/projects/phpmailer/). -- Marcus Bointon (coolbru on SF) and Andy Prevost (codeworxtech) took over the project in 2004. +- [Marcus Bointon](https://github.com/Synchro) (`coolbru` on SF) and Andy Prevost (`codeworxtech`) took over the project in 2004. - Became an Apache incubator project on Google Code in 2010, managed by Jim Jagielski. -- Marcus created his fork on [GitHub](https://github.com/Synchro/PHPMailer) in 2008. +- Marcus created [his fork on GitHub](https://github.com/Synchro/PHPMailer) in 2008. - Jim and Marcus decide to join forces and use GitHub as the canonical and official repo for PHPMailer in 2013. -- PHPMailer moves to the [PHPMailer organisation](https://github.com/PHPMailer) on GitHub in 2013. +- PHPMailer moves to [the PHPMailer organisation](https://github.com/PHPMailer) on GitHub in 2013. ### What's changed since moving from SourceForge? - Official successor to the SourceForge and Google Code projects. - Test suite. -- Continuous integration with Travis-CI. +- Continuous integration with Github Actions. - Composer support. - Public development. - Additional languages and language strings. diff --git a/vendor/phpmailer/phpmailer/SECURITY.md b/vendor/phpmailer/phpmailer/SECURITY.md index fc3e61c20..2552df8a3 100644 --- a/vendor/phpmailer/phpmailer/SECURITY.md +++ b/vendor/phpmailer/phpmailer/SECURITY.md @@ -1,6 +1,6 @@ # Security notices relating to PHPMailer -Please disclose any vulnerabilities found responsibly - report any security problems found to the maintainers privately. +Please disclose any security issues or vulnerabilities found through [Tidelift's coordinated disclosure system](https://tidelift.com/security) or to the maintainers privately. PHPMailer versions 6.1.5 and earlier contain an output escaping bug that occurs in `Content-Type` and `Content-Disposition` when filenames passed into `addAttachment` and other methods that accept attachment names contain double quote characters, in contravention of RFC822 3.4.1. No specific vulnerability has been found relating to this, but it could allow file attachments to bypass attachment filters that are based on matching filename extensions. Recorded as [CVE-2020-13625](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2020-13625). Reported by Elar Lang of Clarified Security. diff --git a/vendor/phpmailer/phpmailer/VERSION b/vendor/phpmailer/phpmailer/VERSION index cb6b1ffdc..c0be8a799 100644 --- a/vendor/phpmailer/phpmailer/VERSION +++ b/vendor/phpmailer/phpmailer/VERSION @@ -1 +1 @@ -6.1.7 \ No newline at end of file +6.4.0 \ No newline at end of file diff --git a/vendor/phpmailer/phpmailer/composer.json b/vendor/phpmailer/phpmailer/composer.json index 90d2576f5..b8aa5cfcc 100644 --- a/vendor/phpmailer/phpmailer/composer.json +++ b/vendor/phpmailer/phpmailer/composer.json @@ -21,26 +21,30 @@ ], "funding": [ { - "url": "https://github.com/synchro", + "url": "https://github.com/Synchro", "type": "github" } ], "require": { "php": ">=5.5.0", "ext-ctype": "*", - "ext-filter": "*" + "ext-filter": "*", + "ext-hash": "*" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.2", - "phpunit/phpunit": "^4.8 || ^5.7", - "doctrine/annotations": "^1.2" + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.2", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.5.6", + "yoast/phpunit-polyfills": "^0.2.0" }, "suggest": { - "psr/log": "For optional PSR-3 debug logging", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", - "ext-mbstring": "Needed to send email in multibyte encoding charset", "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" }, "autoload": { diff --git a/vendor/phpmailer/phpmailer/get_oauth_token.php b/vendor/phpmailer/phpmailer/get_oauth_token.php index 1237b57be..befdc34a5 100644 --- a/vendor/phpmailer/phpmailer/get_oauth_token.php +++ b/vendor/phpmailer/phpmailer/get_oauth_token.php @@ -1,4 +1,5 @@ * @author Andy Prevost (codeworxtech) * @author Brent R. Matzelle (original founder) - * @copyright 2012 - 2017 Marcus Bointon + * @copyright 2012 - 2020 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License @@ -16,6 +17,7 @@ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. */ + /** * Get an OAuth2 token from an OAuth2 provider. * * Install this script on your server so that it's accessible @@ -36,24 +38,24 @@ * Plenty to choose from here: * @see http://oauth2-client.thephpleague.com/providers/thirdparty/ */ -// @see https://github.com/thephpleague/oauth2-google +//@see https://github.com/thephpleague/oauth2-google use League\OAuth2\Client\Provider\Google; -// @see https://packagist.org/packages/hayageek/oauth2-yahoo +//@see https://packagist.org/packages/hayageek/oauth2-yahoo use Hayageek\OAuth2\Client\Provider\Yahoo; -// @see https://github.com/stevenmaguire/oauth2-microsoft +//@see https://github.com/stevenmaguire/oauth2-microsoft use Stevenmaguire\OAuth2\Client\Provider\Microsoft; if (!isset($_GET['code']) && !isset($_GET['provider'])) { -?> + ?> -Select Provider:
-Google
-Yahoo
-Microsoft/Outlook/Hotmail/Live/Office365
+Select Provider:
+Google
+Yahoo
+Microsoft/Outlook/Hotmail/Live/Office365
-getAuthorizationUrl($options); $_SESSION['oauth2state'] = $provider->getState(); header('Location: ' . $authUrl); exit; -// Check given state against previously stored one to mitigate CSRF attack + //Check given state against previously stored one to mitigate CSRF attack } elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) { unset($_SESSION['oauth2state']); unset($_SESSION['provider']); exit('Invalid state'); } else { unset($_SESSION['provider']); - // Try to get an access token (using the authorization code grant) + //Try to get an access token (using the authorization code grant) $token = $provider->getAccessToken( 'authorization_code', [ 'code' => $_GET['code'] ] ); - // Use this to interact with an API on the users behalf - // Use this to get a new access token if the old one expires + //Use this to interact with an API on the users behalf + //Use this to get a new access token if the old one expires echo 'Refresh Token: ', $token->getRefreshToken(); } diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-af.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-af.php index 3c42d78e1..0b2a72d52 100644 --- a/vendor/phpmailer/phpmailer/language/phpmailer.lang-af.php +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-af.php @@ -1,4 +1,5 @@ - * Rewrite and extension of the work by Mikael Stokkebro - * + * Rewrite and extension of the work by Mikael Stokkebro + * */ $PHPMAILER_LANG['authenticate'] = 'SMTP fejl: Login mislykkedes.'; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-de.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-de.php index aa987a9ca..e7e59d2b6 100644 --- a/vendor/phpmailer/phpmailer/language/phpmailer.lang-de.php +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-de.php @@ -1,4 +1,5 @@ */ - + $PHPMAILER_LANG['authenticate'] = 'SMTP त्रुटि: प्रामाणिकता की जांच नहीं हो सका। '; $PHPMAILER_LANG['connect_host'] = 'SMTP त्रुटि: SMTP सर्वर से कनेक्ट नहीं हो सका। '; $PHPMAILER_LANG['data_not_accepted'] = 'SMTP त्रुटि: डेटा स्वीकार नहीं किया जाता है। '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-hr.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-hr.php index 3822920ad..cacb6c37e 100644 --- a/vendor/phpmailer/phpmailer/language/phpmailer.lang-hr.php +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-hr.php @@ -1,4 +1,5 @@ */ - + $PHPMAILER_LANG['authenticate'] = 'SMTP -ի սխալ: չհաջողվեց ստուգել իսկությունը.'; $PHPMAILER_LANG['connect_host'] = 'SMTP -ի սխալ: չհաջողվեց կապ հաստատել SMTP սերվերի հետ.'; $PHPMAILER_LANG['data_not_accepted'] = 'SMTP -ի սխալ: տվյալները ընդունված չեն.'; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-id.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-id.php index ba6ca5fac..212a11f13 100644 --- a/vendor/phpmailer/phpmailer/language/phpmailer.lang-id.php +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-id.php @@ -1,9 +1,11 @@ * @author @januridp + * @author Ian Mustafa */ $PHPMAILER_LANG['authenticate'] = 'Kesalahan SMTP: Tidak dapat mengotentikasi.'; @@ -11,17 +13,19 @@ $PHPMAILER_LANG['data_not_accepted'] = 'Kesalahan SMTP: Data tidak diterima.'; $PHPMAILER_LANG['empty_message'] = 'Isi pesan kosong'; $PHPMAILER_LANG['encoding'] = 'Pengkodean karakter tidak dikenali: '; -$PHPMAILER_LANG['execute'] = 'Tidak dapat menjalankan proses : '; -$PHPMAILER_LANG['file_access'] = 'Tidak dapat mengakses berkas : '; -$PHPMAILER_LANG['file_open'] = 'Kesalahan File: Berkas tidak dapat dibuka : '; -$PHPMAILER_LANG['from_failed'] = 'Alamat pengirim berikut mengakibatkan kesalahan : '; -$PHPMAILER_LANG['instantiate'] = 'Tidak dapat menginisialisasi fungsi surel'; -$PHPMAILER_LANG['invalid_address'] = 'Gagal terkirim, alamat surel tidak benar : '; -$PHPMAILER_LANG['provide_address'] = 'Harus disediakan minimal satu alamat tujuan'; +$PHPMAILER_LANG['execute'] = 'Tidak dapat menjalankan proses: '; +$PHPMAILER_LANG['file_access'] = 'Tidak dapat mengakses berkas: '; +$PHPMAILER_LANG['file_open'] = 'Kesalahan Berkas: Berkas tidak dapat dibuka: '; +$PHPMAILER_LANG['from_failed'] = 'Alamat pengirim berikut mengakibatkan kesalahan: '; +$PHPMAILER_LANG['instantiate'] = 'Tidak dapat menginisialisasi fungsi surel.'; +$PHPMAILER_LANG['invalid_address'] = 'Gagal terkirim, alamat surel tidak sesuai: '; +$PHPMAILER_LANG['invalid_hostentry'] = 'Gagal terkirim, entri host tidak sesuai: '; +$PHPMAILER_LANG['invalid_host'] = 'Gagal terkirim, host tidak sesuai: '; +$PHPMAILER_LANG['provide_address'] = 'Harus tersedia minimal satu alamat tujuan'; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer tidak didukung'; -$PHPMAILER_LANG['recipients_failed'] = 'Kesalahan SMTP: Alamat tujuan berikut menghasilkan kesalahan : '; -$PHPMAILER_LANG['signing'] = 'Kesalahan dalam tanda tangan : '; +$PHPMAILER_LANG['recipients_failed'] = 'Kesalahan SMTP: Alamat tujuan berikut menyebabkan kesalahan: '; +$PHPMAILER_LANG['signing'] = 'Kesalahan dalam penandatangan SSL: '; $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() gagal.'; -$PHPMAILER_LANG['smtp_error'] = 'Kesalahan pada pelayan SMTP : '; -$PHPMAILER_LANG['variable_set'] = 'Tidak dapat mengatur atau mengatur ulang variable : '; -$PHPMAILER_LANG['extension_missing'] = 'Ekstensi hilang: '; +$PHPMAILER_LANG['smtp_error'] = 'Kesalahan pada pelayan SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'Tidak dapat mengatur atau mengatur ulang variabel: '; +$PHPMAILER_LANG['extension_missing'] = 'Ekstensi PHP tidak tersedia: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-it.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-it.php index e67b6f72c..08a6b7333 100644 --- a/vendor/phpmailer/phpmailer/language/phpmailer.lang-it.php +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-it.php @@ -1,4 +1,5 @@ */ + $PHPMAILER_LANG['authenticate'] = 'Hadisoana SMTP: Tsy nahomby ny fanamarinana.'; $PHPMAILER_LANG['connect_host'] = 'SMTP Error: Tsy afaka mampifandray amin\'ny mpampiantrano SMTP.'; $PHPMAILER_LANG['data_not_accepted'] = 'SMTP diso: tsy voarakitra ny angona.'; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php index f12a6ad48..71db33834 100644 --- a/vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php @@ -1,4 +1,5 @@ * @author Filip Š + * @author Blaž Oražem */ $PHPMAILER_LANG['authenticate'] = 'SMTP napaka: Avtentikacija ni uspela.'; @@ -17,8 +19,10 @@ $PHPMAILER_LANG['from_failed'] = 'Neveljaven e-naslov pošiljatelja: '; $PHPMAILER_LANG['instantiate'] = 'Ne morem inicializirati mail funkcije.'; $PHPMAILER_LANG['invalid_address'] = 'E-poštno sporočilo ni bilo poslano. E-naslov je neveljaven: '; +$PHPMAILER_LANG['invalid_hostentry'] = 'Neveljaven vnos gostitelja: '; +$PHPMAILER_LANG['invalid_host'] = 'Neveljaven gostitelj: '; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer ni podprt.'; -$PHPMAILER_LANG['provide_address'] = 'Prosim vnesite vsaj enega naslovnika.'; +$PHPMAILER_LANG['provide_address'] = 'Prosimo, vnesite vsaj enega naslovnika.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP napaka: Sledeči naslovniki so neveljavni: '; $PHPMAILER_LANG['signing'] = 'Napaka pri podpisovanju: '; $PHPMAILER_LANG['smtp_connect_failed'] = 'Ne morem vzpostaviti povezave s SMTP strežnikom.'; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-sr.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-sr.php index 34c1e182a..0b5280f75 100644 --- a/vendor/phpmailer/phpmailer/language/phpmailer.lang-sr.php +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-sr.php @@ -1,4 +1,5 @@ + * @author Miloš Milanović + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP greška: autentifikacija nije uspela.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP greška: povezivanje sa SMTP serverom nije uspelo.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP greška: podaci nisu prihvaćeni.'; +$PHPMAILER_LANG['empty_message'] = 'Sadržaj poruke je prazan.'; +$PHPMAILER_LANG['encoding'] = 'Nepoznato kodiranje: '; +$PHPMAILER_LANG['execute'] = 'Nije moguće izvršiti naredbu: '; +$PHPMAILER_LANG['file_access'] = 'Nije moguće pristupiti datoteci: '; +$PHPMAILER_LANG['file_open'] = 'Nije moguće otvoriti datoteku: '; +$PHPMAILER_LANG['from_failed'] = 'SMTP greška: slanje sa sledećih adresa nije uspelo: '; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP greška: slanje na sledeće adrese nije uspelo: '; +$PHPMAILER_LANG['instantiate'] = 'Nije moguće pokrenuti mail funkciju.'; +$PHPMAILER_LANG['invalid_address'] = 'Poruka nije poslata. Neispravna adresa: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' majler nije podržan.'; +$PHPMAILER_LANG['provide_address'] = 'Definišite bar jednu adresu primaoca.'; +$PHPMAILER_LANG['signing'] = 'Greška prilikom prijave: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Povezivanje sa SMTP serverom nije uspelo.'; +$PHPMAILER_LANG['smtp_error'] = 'Greška SMTP servera: '; +$PHPMAILER_LANG['variable_set'] = 'Nije moguće zadati niti resetovati promenljivu: '; +$PHPMAILER_LANG['extension_missing'] = 'Nedostaje proširenje: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php index c78237e7c..9872c1921 100644 --- a/vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php @@ -1,4 +1,5 @@ + * @author Adriane Justine Tan */ - + $PHPMAILER_LANG['authenticate'] = 'SMTP Error: Hindi mapatotohanan.'; $PHPMAILER_LANG['connect_host'] = 'SMTP Error: Hindi makakonekta sa SMTP host.'; -$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: Ang datos ay hindi maaaring matatanggap.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: Ang datos ay hindi naitanggap.'; $PHPMAILER_LANG['empty_message'] = 'Walang laman ang mensahe'; $PHPMAILER_LANG['encoding'] = 'Hindi alam ang encoding: '; $PHPMAILER_LANG['execute'] = 'Hindi maisasagawa: '; $PHPMAILER_LANG['file_access'] = 'Hindi ma-access ang file: '; -$PHPMAILER_LANG['file_open'] = 'Hindi mabuksan ang file: '; +$PHPMAILER_LANG['file_open'] = 'File Error: Hindi mabuksan ang file: '; $PHPMAILER_LANG['from_failed'] = 'Ang sumusunod na address ay nabigo: '; -$PHPMAILER_LANG['instantiate'] = 'Hindi maaaring magbigay ng institusyon ang mail'; +$PHPMAILER_LANG['instantiate'] = 'Hindi maisimulan ang instance ng mail function.'; $PHPMAILER_LANG['invalid_address'] = 'Hindi wasto ang address na naibigay: '; -$PHPMAILER_LANG['mailer_not_supported'] = 'Ang mailer ay hindi suportado'; -$PHPMAILER_LANG['provide_address'] = 'Kailangan mong magbigay ng kahit isang email address na tatanggap'; +$PHPMAILER_LANG['mailer_not_supported'] = 'Ang mailer ay hindi suportado.'; +$PHPMAILER_LANG['provide_address'] = 'Kailangan mong magbigay ng kahit isang email address na tatanggap.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: Ang mga sumusunod na tatanggap ay nabigo: '; -$PHPMAILER_LANG['signing'] = 'Hindi ma-sign'; -$PHPMAILER_LANG['smtp_connect_failed'] = 'Ang SMTP connect() ay nabigo'; -$PHPMAILER_LANG['smtp_error'] = 'Ang server ng SMTP ay nabigo'; -$PHPMAILER_LANG['variable_set'] = 'Hindi matatakda ang mga variables: '; -$PHPMAILER_LANG['extension_missing'] = 'Nawawala ang extension'; +$PHPMAILER_LANG['signing'] = 'Hindi ma-sign: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Ang SMTP connect() ay nabigo.'; +$PHPMAILER_LANG['smtp_error'] = 'Ang server ng SMTP ay nabigo: '; +$PHPMAILER_LANG['variable_set'] = 'Hindi matatakda o ma-reset ang mga variables: '; +$PHPMAILER_LANG['extension_missing'] = 'Nawawala ang extension: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php index cfe8eaae2..f938f8020 100644 --- a/vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php @@ -1,4 +1,5 @@ + + + + ./test/ + + + + + + + + languages + pop3 + + + + + ./src + + + + + + + + diff --git a/vendor/phpmailer/phpmailer/src/Exception.php b/vendor/phpmailer/phpmailer/src/Exception.php index b1e552f50..a50a8991f 100644 --- a/vendor/phpmailer/phpmailer/src/Exception.php +++ b/vendor/phpmailer/phpmailer/src/Exception.php @@ -1,4 +1,5 @@ * @author Andy Prevost (codeworxtech) * @author Brent R. Matzelle (original founder) - * @copyright 2012 - 2017 Marcus Bointon + * @copyright 2012 - 2020 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License diff --git a/vendor/phpmailer/phpmailer/src/OAuth.php b/vendor/phpmailer/phpmailer/src/OAuth.php index 0271963ce..c93d0be1b 100644 --- a/vendor/phpmailer/phpmailer/src/OAuth.php +++ b/vendor/phpmailer/phpmailer/src/OAuth.php @@ -1,4 +1,5 @@ * @author Andy Prevost (codeworxtech) * @author Brent R. Matzelle (original founder) - * @copyright 2012 - 2015 Marcus Bointon + * @copyright 2012 - 2020 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License @@ -122,7 +123,7 @@ protected function getToken() */ public function getOauth64() { - // Get a new token if it's not available or has expired + //Get a new token if it's not available or has expired if (null === $this->oauthToken || $this->oauthToken->hasExpired()) { $this->oauthToken = $this->getToken(); } diff --git a/vendor/phpmailer/phpmailer/src/PHPMailer.php b/vendor/phpmailer/phpmailer/src/PHPMailer.php index 2d4156f4e..1a65cfd8d 100644 --- a/vendor/phpmailer/phpmailer/src/PHPMailer.php +++ b/vendor/phpmailer/phpmailer/src/PHPMailer.php @@ -1,4 +1,5 @@ * @author Andy Prevost (codeworxtech) * @author Brent R. Matzelle (original founder) - * @copyright 2012 - 2019 Marcus Bointon + * @copyright 2012 - 2020 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License @@ -388,11 +389,11 @@ class PHPMailer * SMTP class debug output mode. * Debug output level. * Options: - * * SMTP::DEBUG_OFF: No output - * * SMTP::DEBUG_CLIENT: Client messages - * * SMTP::DEBUG_SERVER: Client and server messages - * * SMTP::DEBUG_CONNECTION: As SERVER plus connection status - * * SMTP::DEBUG_LOWLEVEL: Noisy, low-level data output, rarely needed + * @see SMTP::DEBUG_OFF: No output + * @see SMTP::DEBUG_CLIENT: Client messages + * @see SMTP::DEBUG_SERVER: Client and server messages + * @see SMTP::DEBUG_CONNECTION: As SERVER plus connection status + * @see SMTP::DEBUG_LOWLEVEL: Noisy, low-level data output, rarely needed * * @see SMTP::$do_debug * @@ -747,7 +748,7 @@ class PHPMailer * * @var string */ - const VERSION = '6.1.7'; + const VERSION = '6.4.0'; /** * Error severity: message only, continue processing. @@ -861,18 +862,25 @@ private function mailPassthru($to, $subject, $body, $header, $params) $subject = $this->encodeHeader($this->secureHeader($subject)); } //Calling mail() with null params breaks + $this->edebug('Sending with mail()'); + $this->edebug('Sendmail path: ' . ini_get('sendmail_path')); + $this->edebug("Envelope sender: {$this->Sender}"); + $this->edebug("To: {$to}"); + $this->edebug("Subject: {$subject}"); + $this->edebug("Headers: {$header}"); if (!$this->UseSendmailOptions || null === $params) { $result = @mail($to, $subject, $body, $header); } else { + $this->edebug("Additional params: {$params}"); $result = @mail($to, $subject, $body, $header, $params); } - + $this->edebug('Result: ' . ($result ? 'true' : 'false')); return $result; } /** - * Output debugging info via user-defined method. - * Only generates output if SMTP debug output is enabled (@see SMTP::$do_debug). + * Output debugging info via a user-defined method. + * Only generates output if debug output is enabled. * * @see PHPMailer::$Debugoutput * @see PHPMailer::$SMTPDebug @@ -899,6 +907,7 @@ protected function edebug($str) switch ($this->Debugoutput) { case 'error_log': //Don't output, just log + /** @noinspection ForgottenDebugOutputInspection */ error_log($str); break; case 'html': @@ -1068,7 +1077,7 @@ protected function addOrEnqueueAnAddress($kind, $address, $name) $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim $pos = strrpos($address, '@'); if (false === $pos) { - // At-sign is missing. + //At-sign is missing. $error_message = sprintf( '%s (%s): %s', $this->lang('invalid_address'), @@ -1084,7 +1093,7 @@ protected function addOrEnqueueAnAddress($kind, $address, $name) return false; } $params = [$kind, $address, $name]; - // Enqueue addresses with IDN until we know the PHPMailer::$CharSet. + //Enqueue addresses with IDN until we know the PHPMailer::$CharSet. if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) { if ('Reply-To' !== $kind) { if (!array_key_exists($address, $this->RecipientsQueue)) { @@ -1101,7 +1110,7 @@ protected function addOrEnqueueAnAddress($kind, $address, $name) return false; } - // Immediately add standard addresses without IDN. + //Immediately add standard addresses without IDN. return call_user_func_array([$this, 'addAnAddress'], $params); } @@ -1184,9 +1193,20 @@ public static function parseAddresses($addrstr, $useimap = true) //Use this built-in parser if it's available $list = imap_rfc822_parse_adrlist($addrstr, ''); foreach ($list as $address) { - if (('.SYNTAX-ERROR.' !== $address->host) && static::validateAddress( - $address->mailbox . '@' . $address->host - )) { + if ( + ('.SYNTAX-ERROR.' !== $address->host) && static::validateAddress( + $address->mailbox . '@' . $address->host + ) + ) { + //Decode the name part if it's present and encoded + if ( + property_exists($address, 'personal') && + extension_loaded('mbstring') && + preg_match('/^=\?.*\?=$/', $address->personal) + ) { + $address->personal = mb_decode_mimeheader($address->personal); + } + $addresses[] = [ 'name' => (property_exists($address, 'personal') ? $address->personal : ''), 'address' => $address->mailbox . '@' . $address->host, @@ -1210,9 +1230,15 @@ public static function parseAddresses($addrstr, $useimap = true) } else { list($name, $email) = explode('<', $address); $email = trim(str_replace('>', '', $email)); + $name = trim($name); if (static::validateAddress($email)) { + //If this name is encoded, decode it + if (preg_match('/^=\?.*\?=$/', $name)) { + $name = mb_decode_mimeheader($name); + } $addresses[] = [ - 'name' => trim(str_replace(['"', "'"], '', $name)), + //Remove any surrounding quotes and spaces from the name + 'name' => trim($name, '\'" '), 'address' => $email, ]; } @@ -1238,9 +1264,10 @@ public function setFrom($address, $name = '', $auto = true) { $address = trim($address); $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim - // Don't validate now addresses with IDN. Will be done in send(). + //Don't validate now addresses with IDN. Will be done in send(). $pos = strrpos($address, '@'); - if ((false === $pos) + if ( + (false === $pos) || ((!$this->has8bitChars(substr($address, ++$pos)) || !static::idnSupported()) && !static::validateAddress($address)) ) { @@ -1350,7 +1377,7 @@ public static function validateAddress($address, $patternselect = null) /* * This is the pattern used in the HTML5 spec for validation of 'email' type form input elements. * - * @see http://www.whatwg.org/specs/web-apps/current-work/#e-mail-state-(type=email) + * @see https://html.spec.whatwg.org/#e-mail-state-(type=email) */ return (bool) preg_match( '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' . @@ -1390,23 +1417,28 @@ public static function idnSupported() */ public function punyencodeAddress($address) { - // Verify we have required functions, CharSet, and at-sign. + //Verify we have required functions, CharSet, and at-sign. $pos = strrpos($address, '@'); - if (!empty($this->CharSet) && + if ( + !empty($this->CharSet) && false !== $pos && static::idnSupported() ) { $domain = substr($address, ++$pos); - // Verify CharSet string is a valid one, and domain properly encoded in this CharSet. + //Verify CharSet string is a valid one, and domain properly encoded in this CharSet. if ($this->has8bitChars($domain) && @mb_check_encoding($domain, $this->CharSet)) { - $domain = mb_convert_encoding($domain, 'UTF-8', $this->CharSet); + //Convert the domain from whatever charset it's in to UTF-8 + $domain = mb_convert_encoding($domain, self::CHARSET_UTF8, $this->CharSet); //Ignore IDE complaints about this line - method signature changed in PHP 5.4 $errorcode = 0; if (defined('INTL_IDNA_VARIANT_UTS46')) { - $punycode = idn_to_ascii($domain, $errorcode, INTL_IDNA_VARIANT_UTS46); + //Use the current punycode standard (appeared in PHP 7.2) + $punycode = idn_to_ascii($domain, $errorcode, \INTL_IDNA_VARIANT_UTS46); } elseif (defined('INTL_IDNA_VARIANT_2003')) { - $punycode = idn_to_ascii($domain, $errorcode, INTL_IDNA_VARIANT_2003); + //Fall back to this old, deprecated/removed encoding + $punycode = idn_to_ascii($domain, $errorcode, \INTL_IDNA_VARIANT_2003); } else { + //Fall back to a default we don't know about $punycode = idn_to_ascii($domain, $errorcode); } if (false !== $punycode) { @@ -1454,8 +1486,9 @@ public function send() */ public function preSend() { - if ('smtp' === $this->Mailer - || ('mail' === $this->Mailer && stripos(PHP_OS, 'WIN') === 0) + if ( + 'smtp' === $this->Mailer + || ('mail' === $this->Mailer && (\PHP_VERSION_ID >= 80000 || stripos(PHP_OS, 'WIN') === 0)) ) { //SMTP mandates RFC-compliant line endings //and it's also used with mail() on Windows @@ -1465,9 +1498,10 @@ public function preSend() static::setLE(PHP_EOL); } //Check for buggy PHP versions that add a header with an incorrect line break - if ('mail' === $this->Mailer - && ((PHP_VERSION_ID >= 70000 && PHP_VERSION_ID < 70017) - || (PHP_VERSION_ID >= 70100 && PHP_VERSION_ID < 70103)) + if ( + 'mail' === $this->Mailer + && ((\PHP_VERSION_ID >= 70000 && \PHP_VERSION_ID < 70017) + || (\PHP_VERSION_ID >= 70100 && \PHP_VERSION_ID < 70103)) && ini_get('mail.add_x_header') === '1' && stripos(PHP_OS, 'WIN') === 0 ) { @@ -1480,10 +1514,10 @@ public function preSend() } try { - $this->error_count = 0; // Reset errors + $this->error_count = 0; //Reset errors $this->mailHeader = ''; - // Dequeue recipient and Reply-To addresses with IDN + //Dequeue recipient and Reply-To addresses with IDN foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) { $params[1] = $this->punyencodeAddress($params[1]); call_user_func_array([$this, 'addAnAddress'], $params); @@ -1492,7 +1526,7 @@ public function preSend() throw new Exception($this->lang('provide_address'), self::STOP_CRITICAL); } - // Validate From, Sender, and ConfirmReadingTo addresses + //Validate From, Sender, and ConfirmReadingTo addresses foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) { $this->$address_kind = trim($this->$address_kind); if (empty($this->$address_kind)) { @@ -1516,29 +1550,29 @@ public function preSend() } } - // Set whether the message is multipart/alternative + //Set whether the message is multipart/alternative if ($this->alternativeExists()) { $this->ContentType = static::CONTENT_TYPE_MULTIPART_ALTERNATIVE; } $this->setMessageType(); - // Refuse to send an empty message unless we are specifically allowing it + //Refuse to send an empty message unless we are specifically allowing it if (!$this->AllowEmpty && empty($this->Body)) { throw new Exception($this->lang('empty_message'), self::STOP_CRITICAL); } //Trim subject consistently $this->Subject = trim($this->Subject); - // Create body before headers in case body makes changes to headers (e.g. altering transfer encoding) + //Create body before headers in case body makes changes to headers (e.g. altering transfer encoding) $this->MIMEHeader = ''; $this->MIMEBody = $this->createBody(); - // createBody may have added some headers, so retain them + //createBody may have added some headers, so retain them $tempheaders = $this->MIMEHeader; $this->MIMEHeader = $this->createHeader(); $this->MIMEHeader .= $tempheaders; - // To capture the complete message when using mail(), create - // an extra header list which createHeader() doesn't fold in + //To capture the complete message when using mail(), create + //an extra header list which createHeader() doesn't fold in if ('mail' === $this->Mailer) { if (count($this->to) > 0) { $this->mailHeader .= $this->addrAppend('To', $this->to); @@ -1551,8 +1585,9 @@ public function preSend() ); } - // Sign with DKIM if enabled - if (!empty($this->DKIM_domain) + //Sign with DKIM if enabled + if ( + !empty($this->DKIM_domain) && !empty($this->DKIM_selector) && (!empty($this->DKIM_private_string) || (!empty($this->DKIM_private) @@ -1591,7 +1626,7 @@ public function preSend() public function postSend() { try { - // Choose the mailer and send through it + //Choose the mailer and send through it switch ($this->Mailer) { case 'sendmail': case 'qmail': @@ -1609,6 +1644,9 @@ public function postSend() return $this->mailSend($this->MIMEHeader, $this->MIMEBody); } } catch (Exception $exc) { + if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true) { + $this->smtp->reset(); + } $this->setError($exc->getMessage()); $this->edebug($exc->getMessage()); if ($this->exceptions) { @@ -1633,22 +1671,44 @@ public function postSend() */ protected function sendmailSend($header, $body) { + if ($this->Mailer === 'qmail') { + $this->edebug('Sending with qmail'); + } else { + $this->edebug('Sending with sendmail'); + } $header = static::stripTrailingWSP($header) . static::$LE . static::$LE; - - // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped. - if (!empty($this->Sender) && self::isShellSafe($this->Sender)) { - if ('qmail' === $this->Mailer) { + //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver + //A space after `-f` is optional, but there is a long history of its presence + //causing problems, so we don't use one + //Exim docs: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html + //Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html + //Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html + //Example problem: https://www.drupal.org/node/1057954 + if (empty($this->Sender) && !empty(ini_get('sendmail_from'))) { + //PHP config has a sender address we can use + $this->Sender = ini_get('sendmail_from'); + } + //CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped. + if (!empty($this->Sender) && static::validateAddress($this->Sender) && self::isShellSafe($this->Sender)) { + if ($this->Mailer === 'qmail') { $sendmailFmt = '%s -f%s'; } else { $sendmailFmt = '%s -oi -f%s -t'; } - } elseif ('qmail' === $this->Mailer) { - $sendmailFmt = '%s'; } else { + //allow sendmail to choose a default envelope sender. It may + //seem preferable to force it to use the From header as with + //SMTP, but that introduces new problems (see + //), and + //it has historically worked this way. $sendmailFmt = '%s -oi -t'; } $sendmail = sprintf($sendmailFmt, escapeshellcmd($this->Sendmail), $this->Sender); + $this->edebug('Sendmail path: ' . $this->Sendmail); + $this->edebug('Sendmail command: ' . $sendmail); + $this->edebug('Envelope sender: ' . $this->Sender); + $this->edebug("Headers: {$header}"); if ($this->SingleTo) { foreach ($this->SingleToArray as $toAddr) { @@ -1656,6 +1716,7 @@ protected function sendmailSend($header, $body) if (!$mail) { throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); } + $this->edebug("To: {$toAddr}"); fwrite($mail, 'To: ' . $toAddr . "\n"); fwrite($mail, $header); fwrite($mail, $body); @@ -1670,6 +1731,7 @@ protected function sendmailSend($header, $body) $this->From, [] ); + $this->edebug("Result: " . ($result === 0 ? 'true' : 'false')); if (0 !== $result) { throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); } @@ -1692,6 +1754,7 @@ protected function sendmailSend($header, $body) $this->From, [] ); + $this->edebug("Result: " . ($result === 0 ? 'true' : 'false')); if (0 !== $result) { throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); } @@ -1712,8 +1775,9 @@ protected function sendmailSend($header, $body) */ protected static function isShellSafe($string) { - // Future-proof - if (escapeshellcmd($string) !== $string + //Future-proof + if ( + escapeshellcmd($string) !== $string || !in_array(escapeshellarg($string), ["'$string'", "\"$string\""]) ) { return false; @@ -1724,9 +1788,9 @@ protected static function isShellSafe($string) for ($i = 0; $i < $length; ++$i) { $c = $string[$i]; - // All other characters have a special meaning in at least one common shell, including = and +. - // Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here. - // Note that this does permit non-Latin alphanumeric characters based on the current locale. + //All other characters have a special meaning in at least one common shell, including = and +. + //Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here. + //Note that this does permit non-Latin alphanumeric characters based on the current locale. if (!ctype_alnum($c) && strpos('@_-.', $c) === false) { return false; } @@ -1749,6 +1813,23 @@ protected static function isPermittedPath($path) return !preg_match('#^[a-z]+://#i', $path); } + /** + * Check whether a file path is safe, accessible, and readable. + * + * @param string $path A relative or absolute path to a file + * + * @return bool + */ + protected static function fileIsAccessible($path) + { + $readable = file_exists($path); + //If not a UNC path (expected to start with \\), check read permission, see #2069 + if (strpos($path, '\\\\') !== 0) { + $readable = $readable && is_readable($path); + } + return static::isPermittedPath($path) && $readable; + } + /** * Send mail using the PHP mail() function. * @@ -1779,11 +1860,15 @@ protected function mailSend($header, $body) //Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html //Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html //Example problem: https://www.drupal.org/node/1057954 - // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped. - if (!empty($this->Sender) && static::validateAddress($this->Sender) && self::isShellSafe($this->Sender)) { - $params = sprintf('-f%s', $this->Sender); + //CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped. + if (empty($this->Sender) && !empty(ini_get('sendmail_from'))) { + //PHP config has a sender address we can use + $this->Sender = ini_get('sendmail_from'); } if (!empty($this->Sender) && static::validateAddress($this->Sender)) { + if (self::isShellSafe($this->Sender)) { + $params = sprintf('-f%s', $this->Sender); + } $old_from = ini_get('sendmail_from'); ini_set('sendmail_from', $this->Sender); } @@ -1869,7 +1954,7 @@ protected function smtpSend($header, $body) } $callbacks = []; - // Attempt to send to all recipients + //Attempt to send to all recipients foreach ([$this->to, $this->cc, $this->bcc] as $togroup) { foreach ($togroup as $to) { if (!$this->smtp->recipient($to[0], $this->dsn)) { @@ -1880,11 +1965,11 @@ protected function smtpSend($header, $body) $isSent = true; } - $callbacks[] = ['issent'=>$isSent, 'to'=>$to[0]]; + $callbacks[] = ['issent' => $isSent, 'to' => $to[0]]; } } - // Only send the DATA command if we have viable recipients + //Only send the DATA command if we have viable recipients if ((count($this->all_recipients) > count($bad_rcpt)) && !$this->smtp->data($header . $body)) { throw new Exception($this->lang('data_not_accepted'), self::STOP_CRITICAL); } @@ -1946,7 +2031,7 @@ public function smtpConnect($options = null) $options = $this->SMTPOptions; } - // Already connected? + //Already connected? if ($this->smtp->connected()) { return true; } @@ -1960,20 +2045,22 @@ public function smtpConnect($options = null) foreach ($hosts as $hostentry) { $hostinfo = []; - if (!preg_match( - '/^(?:(ssl|tls):\/\/)?(.+?)(?::(\d+))?$/', - trim($hostentry), - $hostinfo - )) { + if ( + !preg_match( + '/^(?:(ssl|tls):\/\/)?(.+?)(?::(\d+))?$/', + trim($hostentry), + $hostinfo + ) + ) { $this->edebug($this->lang('invalid_hostentry') . ' ' . trim($hostentry)); - // Not a valid host entry + //Not a valid host entry continue; } - // $hostinfo[1]: optional ssl or tls prefix - // $hostinfo[2]: the hostname - // $hostinfo[3]: optional port number - // The host string prefix can temporarily override the current setting for SMTPSecure - // If it's not specified, the default value is used + //$hostinfo[1]: optional ssl or tls prefix + //$hostinfo[2]: the hostname + //$hostinfo[3]: optional port number + //The host string prefix can temporarily override the current setting for SMTPSecure + //If it's not specified, the default value is used //Check the host name is a valid name or IP address before trying to use it if (!static::isValidHost($hostinfo[2])) { @@ -1985,11 +2072,11 @@ public function smtpConnect($options = null) $tls = (static::ENCRYPTION_STARTTLS === $this->SMTPSecure); if ('ssl' === $hostinfo[1] || ('' === $hostinfo[1] && static::ENCRYPTION_SMTPS === $this->SMTPSecure)) { $prefix = 'ssl://'; - $tls = false; // Can't have SSL and TLS at the same time + $tls = false; //Can't have SSL and TLS at the same time $secure = static::ENCRYPTION_SMTPS; } elseif ('tls' === $hostinfo[1]) { $tls = true; - // tls doesn't use a prefix + //TLS doesn't use a prefix $secure = static::ENCRYPTION_STARTTLS; } //Do we need the OpenSSL extension? @@ -2002,7 +2089,12 @@ public function smtpConnect($options = null) } $host = $hostinfo[2]; $port = $this->Port; - if (array_key_exists(3, $hostinfo) && is_numeric($hostinfo[3]) && $hostinfo[3] > 0 && $hostinfo[3] < 65536) { + if ( + array_key_exists(3, $hostinfo) && + is_numeric($hostinfo[3]) && + $hostinfo[3] > 0 && + $hostinfo[3] < 65536 + ) { $port = (int) $hostinfo[3]; } if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) { @@ -2014,10 +2106,10 @@ public function smtpConnect($options = null) } $this->smtp->hello($hello); //Automatically enable TLS encryption if: - // * it's not disabled - // * we have openssl extension - // * we are not already using SSL - // * the server offers STARTTLS + //* it's not disabled + //* we have openssl extension + //* we are not already using SSL + //* the server offers STARTTLS if ($this->SMTPAutoTLS && $sslext && 'ssl' !== $secure && $this->smtp->getServerExt('STARTTLS')) { $tls = true; } @@ -2025,15 +2117,17 @@ public function smtpConnect($options = null) if (!$this->smtp->startTLS()) { throw new Exception($this->lang('connect_host')); } - // We must resend EHLO after TLS negotiation + //We must resend EHLO after TLS negotiation $this->smtp->hello($hello); } - if ($this->SMTPAuth && !$this->smtp->authenticate( - $this->Username, - $this->Password, - $this->AuthType, - $this->oauth - )) { + if ( + $this->SMTPAuth && !$this->smtp->authenticate( + $this->Username, + $this->Password, + $this->AuthType, + $this->oauth + ) + ) { throw new Exception($this->lang('authenticate')); } @@ -2041,14 +2135,14 @@ public function smtpConnect($options = null) } catch (Exception $exc) { $lastexception = $exc; $this->edebug($exc->getMessage()); - // We must have connected, but then failed TLS or Auth, so close connection nicely + //We must have connected, but then failed TLS or Auth, so close connection nicely $this->smtp->quit(); } } } - // If we get here, all connection attempts have failed, so close connection hard + //If we get here, all connection attempts have failed, so close connection hard $this->smtp->close(); - // As we've caught all exceptions, just report whatever the last one was + //As we've caught all exceptions, just report whatever the last one was if ($this->exceptions && null !== $lastexception) { throw $lastexception; } @@ -2079,7 +2173,7 @@ public function smtpClose() */ public function setLanguage($langcode = 'en', $lang_path = '') { - // Backwards compatibility for renamed language codes + //Backwards compatibility for renamed language codes $renamed_langcodes = [ 'br' => 'pt_br', 'cz' => 'cs', @@ -2091,11 +2185,11 @@ public function setLanguage($langcode = 'en', $lang_path = '') 'am' => 'hy', ]; - if (isset($renamed_langcodes[$langcode])) { + if (array_key_exists($langcode, $renamed_langcodes)) { $langcode = $renamed_langcodes[$langcode]; } - // Define full set of translatable strings in English + //Define full set of translatable strings in English $PHPMAILER_LANG = [ 'authenticate' => 'SMTP Error: Could not authenticate.', 'connect_host' => 'SMTP Error: Could not connect to SMTP host.', @@ -2120,7 +2214,7 @@ public function setLanguage($langcode = 'en', $lang_path = '') 'extension_missing' => 'Extension missing: ', ]; if (empty($lang_path)) { - // Calculate an absolute path so it can work if CWD is not here + //Calculate an absolute path so it can work if CWD is not here $lang_path = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR; } //Validate $langcode @@ -2129,20 +2223,20 @@ public function setLanguage($langcode = 'en', $lang_path = '') } $foundlang = true; $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php'; - // There is no English translation file + //There is no English translation file if ('en' !== $langcode) { - // Make sure language file path is readable - if (!static::isPermittedPath($lang_file) || !file_exists($lang_file)) { + //Make sure language file path is readable + if (!static::fileIsAccessible($lang_file)) { $foundlang = false; } else { - // Overwrite language-specific strings. - // This way we'll never have missing translation keys. + //Overwrite language-specific strings. + //This way we'll never have missing translation keys. $foundlang = include $lang_file; } } $this->language = $PHPMAILER_LANG; - return (bool) $foundlang; // Returns false if language not found + return (bool) $foundlang; //Returns false if language not found } /** @@ -2186,7 +2280,7 @@ public function addrAppend($type, $addr) */ public function addrFormat($addr) { - if (empty($addr[1])) { // No name provided + if (empty($addr[1])) { //No name provided return $this->secureHeader($addr[0]); } @@ -2213,8 +2307,8 @@ public function wrapText($message, $length, $qp_mode = false) } else { $soft_break = static::$LE; } - // If utf-8 encoding is used, we will need to make sure we don't - // split multibyte characters when we wrap + //If utf-8 encoding is used, we will need to make sure we don't + //split multibyte characters when we wrap $is_utf8 = static::CHARSET_UTF8 === strtolower($this->CharSet); $lelen = strlen(static::$LE); $crlflen = strlen(static::$LE); @@ -2314,29 +2408,29 @@ public function utf8CharBoundary($encodedText, $maxLength) $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); $encodedCharPos = strpos($lastChunk, '='); if (false !== $encodedCharPos) { - // Found start of encoded character byte within $lookBack block. - // Check the encoded byte value (the 2 chars after the '=') + //Found start of encoded character byte within $lookBack block. + //Check the encoded byte value (the 2 chars after the '=') $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2); $dec = hexdec($hex); if ($dec < 128) { - // Single byte character. - // If the encoded char was found at pos 0, it will fit - // otherwise reduce maxLength to start of the encoded char + //Single byte character. + //If the encoded char was found at pos 0, it will fit + //otherwise reduce maxLength to start of the encoded char if ($encodedCharPos > 0) { $maxLength -= $lookBack - $encodedCharPos; } $foundSplitPos = true; } elseif ($dec >= 192) { - // First byte of a multi byte character - // Reduce maxLength to split at start of character + //First byte of a multi byte character + //Reduce maxLength to split at start of character $maxLength -= $lookBack - $encodedCharPos; $foundSplitPos = true; } elseif ($dec < 192) { - // Middle byte of a multi byte character, look further back + //Middle byte of a multi byte character, look further back $lookBack += 3; } } else { - // No encoded character found + //No encoded character found $foundSplitPos = true; } } @@ -2380,30 +2474,28 @@ public function createHeader() $result .= $this->headerLine('Date', '' === $this->MessageDate ? self::rfcDate() : $this->MessageDate); - // To be created automatically by mail() - if ($this->SingleTo) { - if ('mail' !== $this->Mailer) { + //The To header is created automatically by mail(), so needs to be omitted here + if ('mail' !== $this->Mailer) { + if ($this->SingleTo) { foreach ($this->to as $toaddr) { $this->SingleToArray[] = $this->addrFormat($toaddr); } - } - } elseif (count($this->to) > 0) { - if ('mail' !== $this->Mailer) { + } elseif (count($this->to) > 0) { $result .= $this->addrAppend('To', $this->to); + } elseif (count($this->cc) === 0) { + $result .= $this->headerLine('To', 'undisclosed-recipients:;'); } - } elseif (count($this->cc) === 0) { - $result .= $this->headerLine('To', 'undisclosed-recipients:;'); } - $result .= $this->addrAppend('From', [[trim($this->From), $this->FromName]]); - // sendmail and mail() extract Cc from the header before sending + //sendmail and mail() extract Cc from the header before sending if (count($this->cc) > 0) { $result .= $this->addrAppend('Cc', $this->cc); } - // sendmail and mail() extract Bcc from the header before sending - if (( + //sendmail and mail() extract Bcc from the header before sending + if ( + ( 'sendmail' === $this->Mailer || 'qmail' === $this->Mailer || 'mail' === $this->Mailer ) && count($this->bcc) > 0 @@ -2415,13 +2507,13 @@ public function createHeader() $result .= $this->addrAppend('Reply-To', $this->ReplyTo); } - // mail() sets the subject itself + //mail() sets the subject itself if ('mail' !== $this->Mailer) { $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject))); } - // Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4 - // https://tools.ietf.org/html/rfc5322#section-3.6.4 + //Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4 + //https://tools.ietf.org/html/rfc5322#section-3.6.4 if ('' !== $this->MessageID && preg_match('/^<.*@.*>$/', $this->MessageID)) { $this->lastMessageID = $this->MessageID; } else { @@ -2447,7 +2539,7 @@ public function createHeader() $result .= $this->headerLine('Disposition-Notification-To', '<' . $this->ConfirmReadingTo . '>'); } - // Add custom headers + //Add custom headers foreach ($this->CustomHeader as $header) { $result .= $this->headerLine( trim($header[0]), @@ -2489,28 +2581,24 @@ public function getMailMIME() $result .= $this->textLine(' boundary="' . $this->boundary[1] . '"'); break; default: - // Catches case 'plain': and case '': + //Catches case 'plain': and case '': $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet); $ismultipart = false; break; } - // RFC1341 part 5 says 7bit is assumed if not specified + //RFC1341 part 5 says 7bit is assumed if not specified if (static::ENCODING_7BIT !== $this->Encoding) { - // RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE + //RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE if ($ismultipart) { if (static::ENCODING_8BIT === $this->Encoding) { $result .= $this->headerLine('Content-Transfer-Encoding', static::ENCODING_8BIT); } - // The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible + //The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible } else { $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding); } } - if ('mail' !== $this->Mailer) { -// $result .= static::$LE; - } - return $result; } @@ -2779,7 +2867,7 @@ public function createBody() $body .= $this->attachAll('attachment', $this->boundary[1]); break; default: - // Catch case 'plain' and case '', applies to simple `text/plain` and `text/html` body content types + //Catch case 'plain' and case '', applies to simple `text/plain` and `text/html` body content types //Reset the `Encoding` property in case we changed it for line length reasons $this->Encoding = $bodyEncoding; $body .= $this->encodeString($this->Body, $this->Encoding); @@ -2870,7 +2958,7 @@ protected function getBoundary($boundary, $charSet, $contentType, $encoding) $result .= $this->textLine('--' . $boundary); $result .= sprintf('Content-Type: %s; charset=%s', $contentType, $charSet); $result .= static::$LE; - // RFC1341 part 5 says 7bit is assumed if not specified + //RFC1341 part 5 says 7bit is assumed if not specified if (static::ENCODING_7BIT !== $encoding) { $result .= $this->headerLine('Content-Transfer-Encoding', $encoding); } @@ -2949,7 +3037,7 @@ public function textLine($value) * @param string $path Path to the attachment * @param string $name Overrides the attachment name * @param string $encoding File encoding (see $Encoding) - * @param string $type File extension (MIME) type + * @param string $type MIME type, e.g. `image/jpeg`; determined automatically from $path if not specified * @param string $disposition Disposition to use * * @throws Exception @@ -2964,11 +3052,11 @@ public function addAttachment( $disposition = 'attachment' ) { try { - if (!static::isPermittedPath($path) || !@is_file($path) || !is_readable($path)) { + if (!static::fileIsAccessible($path)) { throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE); } - // If a MIME type is not specified, try to work it out from the file name + //If a MIME type is not specified, try to work it out from the file name if ('' === $type) { $type = static::filenameToType($path); } @@ -2987,7 +3075,7 @@ public function addAttachment( 2 => $name, 3 => $encoding, 4 => $type, - 5 => false, // isStringAttachment + 5 => false, //isStringAttachment 6 => $disposition, 7 => $name, ]; @@ -3027,16 +3115,16 @@ public function getAttachments() */ protected function attachAll($disposition_type, $boundary) { - // Return text of body + //Return text of body $mime = []; $cidUniq = []; $incl = []; - // Add all attachments + //Add all attachments foreach ($this->attachment as $attachment) { - // Check if it is a valid disposition_filter + //Check if it is a valid disposition_filter if ($attachment[6] === $disposition_type) { - // Check for string attachment + //Check for string attachment $string = ''; $path = ''; $bString = $attachment[5]; @@ -3077,7 +3165,7 @@ protected function attachAll($disposition_type, $boundary) static::$LE ); } - // RFC1341 part 5 says 7bit is assumed if not specified + //RFC1341 part 5 says 7bit is assumed if not specified if (static::ENCODING_7BIT !== $encoding) { $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, static::$LE); } @@ -3087,7 +3175,7 @@ protected function attachAll($disposition_type, $boundary) $mime[] = 'Content-ID: <' . $this->encodeHeader($this->secureHeader($cid)) . '>' . static::$LE; } - // Allow for bypassing the Content-Disposition header + //Allow for bypassing the Content-Disposition header if (!empty($disposition)) { $encoded_name = $this->encodeHeader($this->secureHeader($name)); if (!empty($encoded_name)) { @@ -3108,7 +3196,7 @@ protected function attachAll($disposition_type, $boundary) $mime[] = static::$LE; } - // Encode as string attachment + //Encode as string attachment if ($bString) { $mime[] = $this->encodeString($string, $encoding); } else { @@ -3138,7 +3226,7 @@ protected function attachAll($disposition_type, $boundary) protected function encodeFile($path, $encoding = self::ENCODING_BASE64) { try { - if (!static::isPermittedPath($path) || !file_exists($path) || !is_readable($path)) { + if (!static::fileIsAccessible($path)) { throw new Exception($this->lang('file_open') . $path, self::STOP_CONTINUE); } $file_buffer = file_get_contents($path); @@ -3184,7 +3272,7 @@ public function encodeString($str, $encoding = self::ENCODING_BASE64) case static::ENCODING_7BIT: case static::ENCODING_8BIT: $encoded = static::normalizeBreaks($str); - // Make sure it ends with a line break + //Make sure it ends with a line break if (substr($encoded, -(strlen(static::$LE))) !== static::$LE) { $encoded .= static::$LE; } @@ -3222,7 +3310,7 @@ public function encodeHeader($str, $position = 'text') switch (strtolower($position)) { case 'phrase': if (!preg_match('/[\200-\377]/', $str)) { - // Can't use addslashes as we don't know the value of magic_quotes_sybase + //Can't use addslashes as we don't know the value of magic_quotes_sybase $encoded = addcslashes($str, "\0..\37\177\\\""); if (($str === $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) { return $encoded; @@ -3248,7 +3336,7 @@ public function encodeHeader($str, $position = 'text') $charset = static::CHARSET_ASCII; } - // Q/B encoding adds 8 chars and the charset ("` =??[QB]??=`"). + //Q/B encoding adds 8 chars and the charset ("` =??[QB]??=`"). $overhead = 8 + strlen($charset); if ('mail' === $this->Mailer) { @@ -3257,26 +3345,26 @@ public function encodeHeader($str, $position = 'text') $maxlen = static::MAX_LINE_LENGTH - $overhead; } - // Select the encoding that produces the shortest output and/or prevents corruption. + //Select the encoding that produces the shortest output and/or prevents corruption. if ($matchcount > strlen($str) / 3) { - // More than 1/3 of the content needs encoding, use B-encode. + //More than 1/3 of the content needs encoding, use B-encode. $encoding = 'B'; } elseif ($matchcount > 0) { - // Less than 1/3 of the content needs encoding, use Q-encode. + //Less than 1/3 of the content needs encoding, use Q-encode. $encoding = 'Q'; } elseif (strlen($str) > $maxlen) { - // No encoding needed, but value exceeds max line length, use Q-encode to prevent corruption. + //No encoding needed, but value exceeds max line length, use Q-encode to prevent corruption. $encoding = 'Q'; } else { - // No reformatting needed + //No reformatting needed $encoding = false; } switch ($encoding) { case 'B': if ($this->hasMultiBytes($str)) { - // Use a custom function which correctly encodes and wraps long - // multibyte strings without breaking lines within a character + //Use a custom function which correctly encodes and wraps long + //multibyte strings without breaking lines within a character $encoded = $this->base64EncodeWrapMB($str, "\n"); } else { $encoded = base64_encode($str); @@ -3311,7 +3399,7 @@ public function hasMultiBytes($str) return strlen($str) > mb_strlen($str, $this->CharSet); } - // Assume no multibytes (we can't handle without mbstring functions anyway) + //Assume no multibytes (we can't handle without mbstring functions anyway) return false; } @@ -3349,11 +3437,11 @@ public function base64EncodeWrapMB($str, $linebreak = null) } $mb_length = mb_strlen($str, $this->CharSet); - // Each line must have length <= 75, including $start and $end + //Each line must have length <= 75, including $start and $end $length = 75 - strlen($start) - strlen($end); - // Average multi-byte ratio + //Average multi-byte ratio $ratio = $mb_length / strlen($str); - // Base64 has a 4:3 ratio + //Base64 has a 4:3 ratio $avgLength = floor($length * $ratio * .75); $offset = 0; @@ -3368,7 +3456,7 @@ public function base64EncodeWrapMB($str, $linebreak = null) $encoded .= $chunk . $linebreak; } - // Chomp the last linefeed + //Chomp the last linefeed return substr($encoded, 0, -strlen($linebreak)); } @@ -3397,12 +3485,12 @@ public function encodeQP($string) */ public function encodeQ($str, $position = 'text') { - // There should not be any EOL in the string + //There should not be any EOL in the string $pattern = ''; $encoded = str_replace(["\r", "\n"], '', $str); switch (strtolower($position)) { case 'phrase': - // RFC 2047 section 5.3 + //RFC 2047 section 5.3 $pattern = '^A-Za-z0-9!*+\/ -'; break; /* @@ -3415,15 +3503,15 @@ public function encodeQ($str, $position = 'text') /* Intentional fall through */ case 'text': default: - // RFC 2047 section 5.1 - // Replace every high ascii, control, =, ? and _ characters + //RFC 2047 section 5.1 + //Replace every high ascii, control, =, ? and _ characters $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern; break; } $matches = []; if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) { - // If the string contains an '=', make sure it's the first thing we replace - // so as to avoid double-encoding + //If the string contains an '=', make sure it's the first thing we replace + //so as to avoid double-encoding $eqkey = array_search('=', $matches[0], true); if (false !== $eqkey) { unset($matches[0][$eqkey]); @@ -3433,8 +3521,8 @@ public function encodeQ($str, $position = 'text') $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded); } } - // Replace spaces with _ (more readable than =20) - // RFC 2047 section 4.2(2) + //Replace spaces with _ (more readable than =20) + //RFC 2047 section 4.2(2) return str_replace(' ', '_', $encoded); } @@ -3461,7 +3549,7 @@ public function addStringAttachment( $disposition = 'attachment' ) { try { - // If a MIME type is not specified, try to work it out from the file name + //If a MIME type is not specified, try to work it out from the file name if ('' === $type) { $type = static::filenameToType($filename); } @@ -3470,14 +3558,14 @@ public function addStringAttachment( throw new Exception($this->lang('encoding') . $encoding); } - // Append to $attachment array + //Append to $attachment array $this->attachment[] = [ 0 => $string, 1 => $filename, 2 => static::mb_pathinfo($filename, PATHINFO_BASENAME), 3 => $encoding, 4 => $type, - 5 => true, // isStringAttachment + 5 => true, //isStringAttachment 6 => $disposition, 7 => 0, ]; @@ -3524,11 +3612,11 @@ public function addEmbeddedImage( $disposition = 'inline' ) { try { - if (!static::isPermittedPath($path) || !@is_file($path) || !is_readable($path)) { + if (!static::fileIsAccessible($path)) { throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE); } - // If a MIME type is not specified, try to work it out from the file name + //If a MIME type is not specified, try to work it out from the file name if ('' === $type) { $type = static::filenameToType($path); } @@ -3542,14 +3630,14 @@ public function addEmbeddedImage( $name = $filename; } - // Append to $attachment array + //Append to $attachment array $this->attachment[] = [ 0 => $path, 1 => $filename, 2 => $name, 3 => $encoding, 4 => $type, - 5 => false, // isStringAttachment + 5 => false, //isStringAttachment 6 => $disposition, 7 => $cid, ]; @@ -3594,7 +3682,7 @@ public function addStringEmbeddedImage( $disposition = 'inline' ) { try { - // If a MIME type is not specified, try to work it out from the name + //If a MIME type is not specified, try to work it out from the name if ('' === $type && !empty($name)) { $type = static::filenameToType($name); } @@ -3603,14 +3691,14 @@ public function addStringEmbeddedImage( throw new Exception($this->lang('encoding') . $encoding); } - // Append to $attachment array + //Append to $attachment array $this->attachment[] = [ 0 => $string, 1 => $name, 2 => $name, 3 => $encoding, 4 => $type, - 5 => true, // isStringAttachment + 5 => true, //isStringAttachment 6 => $disposition, 7 => $cid, ]; @@ -3830,8 +3918,8 @@ protected function setError($msg) */ public static function rfcDate() { - // Set the time zone to whatever the default is to avoid 500 errors - // Will default to UTC if it's not set properly in php.ini + //Set the time zone to whatever the default is to avoid 500 errors + //Will default to UTC if it's not set properly in php.ini date_default_timezone_set(@date_default_timezone_get()); return date('D, j M Y H:i:s O'); @@ -3873,7 +3961,8 @@ protected function serverHostname() public static function isValidHost($host) { //Simple syntax limits - if (empty($host) + if ( + empty($host) || !is_string($host) || strlen($host) > 256 || !preg_match('/^([a-zA-Z\d.-]*|\[[a-fA-F\d:]+])$/', $host) @@ -3908,13 +3997,13 @@ public static function isValidHost($host) protected function lang($key) { if (count($this->language) < 1) { - $this->setLanguage(); // set the default language + $this->setLanguage(); //Set the default language } if (array_key_exists($key, $this->language)) { if ('smtp_connect_failed' === $key) { - //Include a link to troubleshooting docs on SMTP connection failure - //this is by far the biggest cause of support questions + //Include a link to troubleshooting docs on SMTP connection failure. + //This is by far the biggest cause of support questions //but it's usually not PHPMailer's fault. return $this->language[$key] . ' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting'; } @@ -3949,7 +4038,7 @@ public function isError() public function addCustomHeader($name, $value = null) { if (null === $value && strpos($name, ':') !== false) { - // Value passed in as name:value + //Value passed in as name:value list($name, $value) = explode(':', $name, 2); } $name = trim($name); @@ -4003,11 +4092,11 @@ public function msgHTML($message, $basedir = '', $advanced = false) preg_match_all('/(? 1 && '/' !== substr($basedir, -1)) { - // Ensure $basedir has a trailing / + //Ensure $basedir has a trailing / $basedir .= '/'; } foreach ($images[2] as $imgindex => $url) { - // Convert data URIs into embedded images + //Convert data URIs into embedded images //e.g. "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" $match = []; if (preg_match('#^data:(image/(?:jpe?g|gif|png));?(base64)?,(.+)#', $url, $match)) { @@ -4021,7 +4110,7 @@ public function msgHTML($message, $basedir = '', $advanced = false) } //Hash the decoded data, not the URL, so that the same data-URI image used in multiple places //will only be embedded once, even if it used a different encoding - $cid = substr(hash('sha256', $data), 0, 32) . '@phpmailer.0'; // RFC2392 S 2 + $cid = substr(hash('sha256', $data), 0, 32) . '@phpmailer.0'; //RFC2392 S 2 if (!$this->cidExists($cid)) { $this->addStringEmbeddedImage( @@ -4039,13 +4128,14 @@ public function msgHTML($message, $basedir = '', $advanced = false) ); continue; } - if (// Only process relative URLs if a basedir is provided (i.e. no absolute local paths) + if ( + //Only process relative URLs if a basedir is provided (i.e. no absolute local paths) !empty($basedir) - // Ignore URLs containing parent dir traversal (..) + //Ignore URLs containing parent dir traversal (..) && (strpos($url, '..') === false) - // Do not change urls that are already inline images + //Do not change urls that are already inline images && 0 !== strpos($url, 'cid:') - // Do not change absolute URLs, including anonymous protocol + //Do not change absolute URLs, including anonymous protocol && !preg_match('#^[a-z][a-z0-9+.-]*:?//#i', $url) ) { $filename = static::mb_pathinfo($url, PATHINFO_BASENAME); @@ -4053,7 +4143,7 @@ public function msgHTML($message, $basedir = '', $advanced = false) if ('.' === $directory) { $directory = ''; } - // RFC2392 S 2 + //RFC2392 S 2 $cid = substr(hash('sha256', $url), 0, 32) . '@phpmailer.0'; if (strlen($basedir) > 1 && '/' !== substr($basedir, -1)) { $basedir .= '/'; @@ -4061,13 +4151,14 @@ public function msgHTML($message, $basedir = '', $advanced = false) if (strlen($directory) > 1 && '/' !== substr($directory, -1)) { $directory .= '/'; } - if ($this->addEmbeddedImage( - $basedir . $directory . $filename, - $cid, - $filename, - static::ENCODING_BASE64, - static::_mime_types((string) static::mb_pathinfo($filename, PATHINFO_EXTENSION)) - ) + if ( + $this->addEmbeddedImage( + $basedir . $directory . $filename, + $cid, + $filename, + static::ENCODING_BASE64, + static::_mime_types((string) static::mb_pathinfo($filename, PATHINFO_EXTENSION)) + ) ) { $message = preg_replace( '/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui', @@ -4079,7 +4170,7 @@ public function msgHTML($message, $basedir = '', $advanced = false) } } $this->isHTML(); - // Convert all message body line breaks to LE, makes quoted-printable encoding work much better + //Convert all message body line breaks to LE, makes quoted-printable encoding work much better $this->Body = static::normalizeBreaks($message); $this->AltBody = static::normalizeBreaks($this->html2text($message, $advanced)); if (!$this->alternativeExists()) { @@ -4098,9 +4189,9 @@ public function msgHTML($message, $basedir = '', $advanced = false) * Example usage: * * ```php - * // Use default conversion + * //Use default conversion * $plain = $mail->html2text($html); - * // Use your own custom converter + * //Use your own custom converter * $plain = $mail->html2text($html, function($html) { * $converter = new MyHtml2text($html); * return $converter->get_text(); @@ -4215,6 +4306,7 @@ public static function _mime_types($ext = '') 'tiff' => 'image/tiff', 'tif' => 'image/tiff', 'webp' => 'image/webp', + 'avif' => 'image/avif', 'heif' => 'image/heif', 'heifs' => 'image/heif-sequence', 'heic' => 'image/heic', @@ -4266,7 +4358,7 @@ public static function _mime_types($ext = '') */ public static function filenameToType($filename) { - // In case the path is a URL, strip any query string before getting extension + //In case the path is a URL, strip any query string before getting extension $qpos = strpos($filename, '?'); if (false !== $qpos) { $filename = substr($filename, 0, $qpos); @@ -4377,9 +4469,9 @@ public static function normalizeBreaks($text, $breaktype = null) if (null === $breaktype) { $breaktype = static::$LE; } - // Normalise to \n + //Normalise to \n $text = str_replace([self::CRLF, "\r"], "\n", $text); - // Now convert LE as needed + //Now convert LE as needed if ("\n" !== $breaktype) { $text = str_replace("\n", $breaktype, $text); } @@ -4485,11 +4577,15 @@ public function DKIM_Sign($signHeader) $privKey = openssl_pkey_get_private($privKeyStr); } if (openssl_sign($signHeader, $signature, $privKey, 'sha256WithRSAEncryption')) { - openssl_pkey_free($privKey); + if (\PHP_MAJOR_VERSION < 8) { + openssl_pkey_free($privKey); + } return base64_encode($signature); } - openssl_pkey_free($privKey); + if (\PHP_MAJOR_VERSION < 8) { + openssl_pkey_free($privKey); + } return ''; } @@ -4554,7 +4650,7 @@ public function DKIM_BodyC($body) if (empty($body)) { return self::CRLF; } - // Normalize line endings to CRLF + //Normalize line endings to CRLF $body = static::normalizeBreaks($body, self::CRLF); //Reduce multiple trailing line breaks to a single one @@ -4574,9 +4670,9 @@ public function DKIM_BodyC($body) */ public function DKIM_Add($headers_line, $subject, $body) { - $DKIMsignatureType = 'rsa-sha256'; // Signature & hash algorithms - $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization methods of header & body - $DKIMquery = 'dns/txt'; // Query method + $DKIMsignatureType = 'rsa-sha256'; //Signature & hash algorithms + $DKIMcanonicalization = 'relaxed/simple'; //Canonicalization methods of header & body + $DKIMquery = 'dns/txt'; //Query method $DKIMtime = time(); //Always sign these headers without being asked //Recommended list from https://tools.ietf.org/html/rfc6376#section-5.4.1 @@ -4677,7 +4773,8 @@ public function DKIM_Add($headers_line, $subject, $body) $headerKeys = ' h=' . implode(':', $headersToSignKeys) . ';' . static::$LE; $headerValues = implode(static::$LE, $headersToSign); $body = $this->DKIM_BodyC($body); - $DKIMb64 = base64_encode(pack('H*', hash('sha256', $body))); // Base64 of packed binary SHA-256 hash of body + //Base64 of packed binary SHA-256 hash of body + $DKIMb64 = base64_encode(pack('H*', hash('sha256', $body))); $ident = ''; if ('' !== $this->DKIM_identity) { $ident = ' i=' . $this->DKIM_identity . ';' . static::$LE; diff --git a/vendor/phpmailer/phpmailer/src/POP3.php b/vendor/phpmailer/phpmailer/src/POP3.php index 9a3b07cca..9bd319865 100644 --- a/vendor/phpmailer/phpmailer/src/POP3.php +++ b/vendor/phpmailer/phpmailer/src/POP3.php @@ -1,4 +1,5 @@ * @author Andy Prevost (codeworxtech) * @author Brent R. Matzelle (original founder) - * @copyright 2012 - 2019 Marcus Bointon + * @copyright 2012 - 2020 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License @@ -45,7 +46,7 @@ class POP3 * * @var string */ - const VERSION = '6.1.7'; + const VERSION = '6.4.0'; /** * Default POP3 port number. @@ -62,12 +63,16 @@ class POP3 const DEFAULT_TIMEOUT = 30; /** - * Debug display level. - * Options: 0 = no, 1+ = yes. + * POP3 class debug output mode. + * Debug output level. + * Options: + * @see POP3::DEBUG_OFF: No output + * @see POP3::DEBUG_SERVER: Server messages, connection/server errors + * @see POP3::DEBUG_CLIENT: Client and Server messages, connection/server errors * * @var int */ - public $do_debug = 0; + public $do_debug = self::DEBUG_OFF; /** * POP3 mail server hostname. @@ -130,6 +135,28 @@ class POP3 */ const LE = "\r\n"; + /** + * Debug level for no output. + * + * @var int + */ + const DEBUG_OFF = 0; + + /** + * Debug level to show server -> client messages + * also shows clients connection errors or errors from server + * + * @var int + */ + const DEBUG_SERVER = 1; + + /** + * Debug level to show client -> server and server -> client messages. + * + * @var int + */ + const DEBUG_CLIENT = 2; + /** * Simple static wrapper for all-in-one POP before SMTP. * @@ -172,13 +199,13 @@ public static function popBeforeSmtp( public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0) { $this->host = $host; - // If no port value provided, use default + //If no port value provided, use default if (false === $port) { $this->port = static::DEFAULT_PORT; } else { $this->port = (int) $port; } - // If no timeout value provided, use default + //If no timeout value provided, use default if (false === $timeout) { $this->tval = static::DEFAULT_TIMEOUT; } else { @@ -187,9 +214,9 @@ public function authorise($host, $port = false, $timeout = false, $username = '' $this->do_debug = $debug_level; $this->username = $username; $this->password = $password; - // Reset the error log + //Reset the error log $this->errors = []; - // connect + //Connect $result = $this->connect($this->host, $this->port, $this->tval); if ($result) { $login_result = $this->login($this->username, $this->password); @@ -199,7 +226,7 @@ public function authorise($host, $port = false, $timeout = false, $username = '' return true; } } - // We need to disconnect regardless of whether the login succeeded + //We need to disconnect regardless of whether the login succeeded $this->disconnect(); return false; @@ -216,7 +243,7 @@ public function authorise($host, $port = false, $timeout = false, $username = '' */ public function connect($host, $port = false, $tval = 30) { - // Are we already connected? + //Are we already connected? if ($this->connected) { return true; } @@ -229,22 +256,22 @@ public function connect($host, $port = false, $tval = 30) $port = static::DEFAULT_PORT; } - // connect to the POP3 server + //Connect to the POP3 server $errno = 0; $errstr = ''; $this->pop_conn = fsockopen( - $host, // POP3 Host - $port, // Port # - $errno, // Error Number - $errstr, // Error Message + $host, //POP3 Host + $port, //Port # + $errno, //Error Number + $errstr, //Error Message $tval - ); // Timeout (seconds) - // Restore the error handler + ); //Timeout (seconds) + //Restore the error handler restore_error_handler(); - // Did we connect? + //Did we connect? if (false === $this->pop_conn) { - // It would appear not... + //It would appear not... $this->setError( "Failed to connect to server $host on port $port. errno: $errno; errstr: $errstr" ); @@ -252,14 +279,14 @@ public function connect($host, $port = false, $tval = 30) return false; } - // Increase the stream time-out + //Increase the stream time-out stream_set_timeout($this->pop_conn, $tval, 0); - // Get the POP3 server response + //Get the POP3 server response $pop3_response = $this->getResponse(); - // Check for the +OK + //Check for the +OK if ($this->checkResponse($pop3_response)) { - // The connection is established and the POP3 server is talking + //The connection is established and the POP3 server is talking $this->connected = true; return true; @@ -289,11 +316,11 @@ public function login($username = '', $password = '') $password = $this->password; } - // Send the Username + //Send the Username $this->sendString("USER $username" . static::LE); $pop3_response = $this->getResponse(); if ($this->checkResponse($pop3_response)) { - // Send the Password + //Send the Password $this->sendString("PASS $password" . static::LE); $pop3_response = $this->getResponse(); if ($this->checkResponse($pop3_response)) { @@ -329,7 +356,7 @@ public function disconnect() protected function getResponse($size = 128) { $response = fgets($this->pop_conn, $size); - if ($this->do_debug >= 1) { + if ($this->do_debug >= self::DEBUG_SERVER) { echo 'Server -> Client: ', $response; } @@ -346,7 +373,7 @@ protected function getResponse($size = 128) protected function sendString($string) { if ($this->pop_conn) { - if ($this->do_debug >= 2) { //Show client messages when debug >= 2 + if ($this->do_debug >= self::DEBUG_CLIENT) { //Show client messages when debug >= 2 echo 'Client -> Server: ', $string; } @@ -384,7 +411,7 @@ protected function checkResponse($string) protected function setError($error) { $this->errors[] = $error; - if ($this->do_debug >= 1) { + if ($this->do_debug >= self::DEBUG_SERVER) { echo '
';
             foreach ($this->errors as $e) {
                 print_r($e);
diff --git a/vendor/phpmailer/phpmailer/src/SMTP.php b/vendor/phpmailer/phpmailer/src/SMTP.php
index 6b0b73ddd..9d85929dd 100644
--- a/vendor/phpmailer/phpmailer/src/SMTP.php
+++ b/vendor/phpmailer/phpmailer/src/SMTP.php
@@ -1,4 +1,5 @@
 
  * @author    Andy Prevost (codeworxtech) 
  * @author    Brent R. Matzelle (original founder)
- * @copyright 2012 - 2019 Marcus Bointon
+ * @copyright 2012 - 2020 Marcus Bointon
  * @copyright 2010 - 2012 Jim Jagielski
  * @copyright 2004 - 2009 Andy Prevost
  * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
@@ -34,7 +35,7 @@ class SMTP
      *
      * @var string
      */
-    const VERSION = '6.1.7';
+    const VERSION = '6.4.0';
 
     /**
      * SMTP line break constant.
@@ -311,11 +312,11 @@ protected function edebug($str, $level = 0)
      */
     public function connect($host, $port = null, $timeout = 30, $options = [])
     {
-        // Clear errors to avoid confusion
+        //Clear errors to avoid confusion
         $this->setError('');
-        // Make sure we are __not__ connected
+        //Make sure we are __not__ connected
         if ($this->connected()) {
-            // Already connected, generate error
+            //Already connected, generate error
             $this->setError('Already connected to a server');
 
             return false;
@@ -323,7 +324,7 @@ public function connect($host, $port = null, $timeout = 30, $options = [])
         if (empty($port)) {
             $port = self::DEFAULT_PORT;
         }
-        // Connect to the SMTP server
+        //Connect to the SMTP server
         $this->edebug(
             "Connection: opening to $host:$port, timeout=$timeout, options=" .
             (count($options) > 0 ? var_export($options, true) : 'array()'),
@@ -339,11 +340,23 @@ public function connect($host, $port = null, $timeout = 30, $options = [])
 
         $this->edebug('Connection: opened', self::DEBUG_CONNECTION);
 
-        // Get any announcement
+        //Get any announcement
         $this->last_reply = $this->get_lines();
         $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
-
-        return true;
+        $responseCode = (int)substr($this->last_reply, 0, 3);
+        if ($responseCode === 220) {
+            return true;
+        }
+        //Anything other than a 220 response means something went wrong
+        //RFC 5321 says the server will wait for us to send a QUIT in response to a 554 error
+        //https://tools.ietf.org/html/rfc5321#section-3.1
+        if ($responseCode === 554) {
+            $this->quit();
+        }
+        //This will handle 421 responses which may not wait for a QUIT (e.g. if the server is being shut down)
+        $this->edebug('Connection: closing due to error', self::DEBUG_CONNECTION);
+        $this->close();
+        return false;
     }
 
     /**
@@ -396,7 +409,7 @@ protected function getSMTPConnection($host, $port = null, $timeout = 30, $option
             restore_error_handler();
         }
 
-        // Verify we connected properly
+        //Verify we connected properly
         if (!is_resource($connection)) {
             $this->setError(
                 'Failed to connect to server',
@@ -413,12 +426,12 @@ protected function getSMTPConnection($host, $port = null, $timeout = 30, $option
             return false;
         }
 
-        // SMTP server can take longer to respond, give longer timeout for first read
-        // Windows does not have support for this timeout function
+        //SMTP server can take longer to respond, give longer timeout for first read
+        //Windows does not have support for this timeout function
         if (strpos(PHP_OS, 'WIN') !== 0) {
             $max = (int)ini_get('max_execution_time');
-            // Don't bother if unlimited
-            if (0 !== $max && $timeout > $max) {
+            //Don't bother if unlimited, or if set_time_limit is disabled
+            if (0 !== $max && $timeout > $max && strpos(ini_get('disable_functions'), 'set_time_limit') === false) {
                 @set_time_limit($timeout);
             }
             stream_set_timeout($connection, $timeout, 0);
@@ -448,7 +461,7 @@ public function startTLS()
             $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
         }
 
-        // Begin encrypted connection
+        //Begin encrypted connection
         set_error_handler([$this, 'errorHandler']);
         $crypto_ok = stream_socket_enable_crypto(
             $this->smtp_conn,
@@ -486,11 +499,11 @@ public function authenticate(
         }
 
         if (array_key_exists('EHLO', $this->server_caps)) {
-            // SMTP extensions are available; try to find a proper authentication method
+            //SMTP extensions are available; try to find a proper authentication method
             if (!array_key_exists('AUTH', $this->server_caps)) {
                 $this->setError('Authentication is not allowed at this stage');
-                // 'at this stage' means that auth may be allowed after the stage changes
-                // e.g. after STARTTLS
+                //'at this stage' means that auth may be allowed after the stage changes
+                //e.g. after STARTTLS
 
                 return false;
             }
@@ -534,22 +547,25 @@ public function authenticate(
         }
         switch ($authtype) {
             case 'PLAIN':
-                // Start authentication
+                //Start authentication
                 if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {
                     return false;
                 }
-                // Send encoded username and password
-                if (!$this->sendCommand(
-                    'User & Password',
-                    base64_encode("\0" . $username . "\0" . $password),
-                    235
-                )
+                //Send encoded username and password
+                if (
+                    //Format from https://tools.ietf.org/html/rfc4616#section-2
+                    //We skip the first field (it's forgery), so the string starts with a null byte
+                    !$this->sendCommand(
+                        'User & Password',
+                        base64_encode("\0" . $username . "\0" . $password),
+                        235
+                    )
                 ) {
                     return false;
                 }
                 break;
             case 'LOGIN':
-                // Start authentication
+                //Start authentication
                 if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) {
                     return false;
                 }
@@ -561,17 +577,17 @@ public function authenticate(
                 }
                 break;
             case 'CRAM-MD5':
-                // Start authentication
+                //Start authentication
                 if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {
                     return false;
                 }
-                // Get the challenge
+                //Get the challenge
                 $challenge = base64_decode(substr($this->last_reply, 4));
 
-                // Build the response
+                //Build the response
                 $response = $username . ' ' . $this->hmac($challenge, $password);
 
-                // send encoded credentials
+                //send encoded credentials
                 return $this->sendCommand('Username', base64_encode($response), 235);
             case 'XOAUTH2':
                 //The OAuth instance must be set up prior to requesting auth.
@@ -580,7 +596,7 @@ public function authenticate(
                 }
                 $oauth = $OAuth->getOauth64();
 
-                // Start authentication
+                //Start authentication
                 if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
                     return false;
                 }
@@ -610,15 +626,15 @@ protected function hmac($data, $key)
             return hash_hmac('md5', $data, $key);
         }
 
-        // The following borrowed from
-        // http://php.net/manual/en/function.mhash.php#27225
+        //The following borrowed from
+        //http://php.net/manual/en/function.mhash.php#27225
 
-        // RFC 2104 HMAC implementation for php.
-        // Creates an md5 HMAC.
-        // Eliminates the need to install mhash to compute a HMAC
-        // by Lance Rushing
+        //RFC 2104 HMAC implementation for php.
+        //Creates an md5 HMAC.
+        //Eliminates the need to install mhash to compute a HMAC
+        //by Lance Rushing
 
-        $bytelen = 64; // byte length for md5
+        $bytelen = 64; //byte length for md5
         if (strlen($key) > $bytelen) {
             $key = pack('H*', md5($key));
         }
@@ -641,7 +657,7 @@ public function connected()
         if (is_resource($this->smtp_conn)) {
             $sock_status = stream_get_meta_data($this->smtp_conn);
             if ($sock_status['eof']) {
-                // The socket is valid but we are not connected
+                //The socket is valid but we are not connected
                 $this->edebug(
                     'SMTP NOTICE: EOF caught while checking if connected',
                     self::DEBUG_CLIENT
@@ -651,7 +667,7 @@ public function connected()
                 return false;
             }
 
-            return true; // everything looks good
+            return true; //everything looks good
         }
 
         return false;
@@ -669,7 +685,7 @@ public function close()
         $this->server_caps = null;
         $this->helo_rply = null;
         if (is_resource($this->smtp_conn)) {
-            // close the connection and cleanup
+            //Close the connection and cleanup
             fclose($this->smtp_conn);
             $this->smtp_conn = null; //Makes for cleaner serialization
             $this->edebug('Connection: closed', self::DEBUG_CONNECTION);
@@ -704,7 +720,7 @@ public function data($msg_data)
          * NOTE: this does not count towards line-length limit.
          */
 
-        // Normalize line breaks before exploding
+        //Normalize line breaks before exploding
         $lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data));
 
         /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field
@@ -750,7 +766,8 @@ public function data($msg_data)
 
             //Send the lines to the server
             foreach ($lines_out as $line_out) {
-                //RFC2821 section 4.5.2
+                //Dot-stuffing as per RFC5321 section 4.5.2
+                //https://tools.ietf.org/html/rfc5321#section-4.5.2
                 if (!empty($line_out) && $line_out[0] === '.') {
                     $line_out = '.' . $line_out;
                 }
@@ -784,7 +801,16 @@ public function data($msg_data)
     public function hello($host = '')
     {
         //Try extended hello first (RFC 2821)
-        return $this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host);
+        if ($this->sendHello('EHLO', $host)) {
+            return true;
+        }
+
+        //Some servers shut down the SMTP service here (RFC 5321)
+        if (substr($this->helo_rply, 0, 3) == '421') {
+            return false;
+        }
+
+        return $this->sendHello('HELO', $host);
     }
 
     /**
@@ -974,12 +1000,12 @@ protected function sendCommand($command, $commandstring, $expect)
         $this->client_send($commandstring . static::LE, $command);
 
         $this->last_reply = $this->get_lines();
-        // Fetch SMTP code and possible error code explanation
+        //Fetch SMTP code and possible error code explanation
         $matches = [];
         if (preg_match('/^([\d]{3})[ -](?:([\d]\\.[\d]\\.[\d]{1,2}) )?/', $this->last_reply, $matches)) {
             $code = (int) $matches[1];
             $code_ex = (count($matches) > 2 ? $matches[2] : null);
-            // Cut off error code from each response line
+            //Cut off error code from each response line
             $detail = preg_replace(
                 "/{$code}[ -]" .
                 ($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . '/m',
@@ -987,7 +1013,7 @@ protected function sendCommand($command, $commandstring, $expect)
                 $this->last_reply
             );
         } else {
-            // Fall back to simple parsing if regex fails
+            //Fall back to simple parsing if regex fails
             $code = (int) substr($this->last_reply, 0, 3);
             $code_ex = null;
             $detail = substr($this->last_reply, 4);
@@ -1086,8 +1112,10 @@ public function client_send($data, $command = '')
     {
         //If SMTP transcripts are left enabled, or debug output is posted online
         //it can leak credentials, so hide credentials in all but lowest level
-        if (self::DEBUG_LOWLEVEL > $this->do_debug &&
-            in_array($command, ['User & Password', 'Username', 'Password'], true)) {
+        if (
+            self::DEBUG_LOWLEVEL > $this->do_debug &&
+            in_array($command, ['User & Password', 'Username', 'Password'], true)
+        ) {
             $this->edebug('CLIENT -> SERVER: [credentials hidden]', self::DEBUG_CLIENT);
         } else {
             $this->edebug('CLIENT -> SERVER: ' . $data, self::DEBUG_CLIENT);
@@ -1180,7 +1208,7 @@ public function getLastReply()
      */
     protected function get_lines()
     {
-        // If the connection is bad, give up straight away
+        //If the connection is bad, give up straight away
         if (!is_resource($this->smtp_conn)) {
             return '';
         }
@@ -1207,7 +1235,8 @@ protected function get_lines()
                     self::DEBUG_LOWLEVEL
                 );
 
-                //stream_select returns false when the `select` system call is interrupted by an incoming signal, try the select again
+                //stream_select returns false when the `select` system call is interrupted
+                //by an incoming signal, try the select again
                 if (stripos($message, 'interrupted system call') !== false) {
                     $this->edebug(
                         'SMTP -> get_lines(): retrying stream_select',
@@ -1232,13 +1261,13 @@ protected function get_lines()
             $str = @fgets($this->smtp_conn, self::MAX_REPLY_LENGTH);
             $this->edebug('SMTP INBOUND: "' . trim($str) . '"', self::DEBUG_LOWLEVEL);
             $data .= $str;
-            // If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled),
-            // or 4th character is a space or a line break char, we are done reading, break the loop.
-            // String array access is a significant micro-optimisation over strlen
+            //If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled),
+            //or 4th character is a space or a line break char, we are done reading, break the loop.
+            //String array access is a significant micro-optimisation over strlen
             if (!isset($str[3]) || $str[3] === ' ' || $str[3] === "\r" || $str[3] === "\n") {
                 break;
             }
-            // Timed-out? Log and break
+            //Timed-out? Log and break
             $info = stream_get_meta_data($this->smtp_conn);
             if ($info['timed_out']) {
                 $this->edebug(
@@ -1247,7 +1276,7 @@ protected function get_lines()
                 );
                 break;
             }
-            // Now check if reads took too long
+            //Now check if reads took too long
             if ($endtime && time() > $endtime) {
                 $this->edebug(
                     'SMTP -> get_lines(): timelimit reached (' .
diff --git a/vendor/qiniu/php-sdk/.scrutinizer.yml b/vendor/qiniu/php-sdk/.scrutinizer.yml
index 8d9304c52..6a2d0d80c 100644
--- a/vendor/qiniu/php-sdk/.scrutinizer.yml
+++ b/vendor/qiniu/php-sdk/.scrutinizer.yml
@@ -33,3 +33,10 @@ tools:
     php_cpd:
         enabled: true
         excluded_dirs: [vendor, tests]
+build:
+    nodes:
+        analysis:
+            tests:
+                override:
+                    - php-scrutinizer-run
+
diff --git a/vendor/qiniu/php-sdk/.travis.yml b/vendor/qiniu/php-sdk/.travis.yml
index e4eee7bea..1f0ba2738 100644
--- a/vendor/qiniu/php-sdk/.travis.yml
+++ b/vendor/qiniu/php-sdk/.travis.yml
@@ -1,4 +1,3 @@
-sudo: false
 language: php
 
 php:
@@ -8,6 +7,7 @@ php:
   - 7.0
 
 dist: trusty
+os: linux
 
 before_script:
   - export QINIU_TEST_ENV="travis"
@@ -18,13 +18,12 @@ script:
   - ./vendor/bin/phpcs --standard=PSR2 src
   - ./vendor/bin/phpcs --standard=PSR2 examples
   - ./vendor/bin/phpcs --standard=PSR2 tests
-  - ./vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover tests/Qiniu/Tests/
-
-after_script:
-  - wget https://scrutinizer-ci.com/ocular.phar
-  - php ocular.phar code-coverage:upload --format=php-clover coverage.clover
+  - ./vendor/bin/phpunit --coverage-clover=coverage.xml
 
 env:
   global:
+    - QINIU_ACCESS_KEY=vHg2e7nOh7Jsucv2Azr5FH6omPgX22zoJRWa0FN5
     - secure: "V9BsntXQZwvO9EOD6itzaae2uq+GemzyTUTxMTJx1/jFoUNpCU2O2UAgjA2XSEr5sgci0KWDV4Krbzv3EBB4uplOFLMI3w32256UHbT9E0x3YjhfPJZk68MH1iS1be7X81LDHON7yveavK8987s3qzjeUcbfLSPgccT+cvf7+dc="
-    - QINIU_ACCESS_KEY=vHg2e7nOh7Jsucv2Azr5FH6omPgX22zoJRWa0FN5
\ No newline at end of file
+
+after_success:
+  - bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/qiniu/php-sdk/CHANGELOG.md b/vendor/qiniu/php-sdk/CHANGELOG.md
index 8a284bdf6..469ae4b9c 100644
--- a/vendor/qiniu/php-sdk/CHANGELOG.md
+++ b/vendor/qiniu/php-sdk/CHANGELOG.md
@@ -1,5 +1,32 @@
 # Changelog
 
+## 7.3.0 (2020-09-24)
+### 新增
+* 【对象存储】增加异步抓取方法与demo
+* 【融合cdn】增加查询CDN刷新记录、查询CDN预取记录方法与demo
+* 【云短信】增加查询短信发送记录的方法 
+* 【实时音视频】增加rtc停止房间的合流转推方法
+* 【内容审核】增加图片审核、视频审核方法与demo
+ 
+### 修复
+* 【对象存储】修复签算 token 时上传策略中的 forceSaveKey 字段不生效的问题
+* 【对象存储】修复更新空间事件通知规则方法
+
+### 优化
+* 【对象存储】创建空间迁移到mkbucketv3 api
+* 优化对 http2 返回头的判断
+* 优化 demo 中的文档注释说明
+* docs 目录下的 rtc demo 移动至 examples/rtc 目录下
+* docs 目录下的 sms demo 移动至 examples/sms 目录下
+
+## 7.2.10 (2019-10-28)
+* 去除云短信类类型指定
+* 修改不传文件名时存在表单上传错误的情况
+
+## 7.2.9 (2019-07-09)
+* 添加空间管理、云短信接口
+* 去除无效参数
+
 ## 7.2.7 (2018-11-06)
 * 添加 QVM 内网上传到 KODO 的 zone 设置
 
diff --git a/vendor/qiniu/php-sdk/README.md b/vendor/qiniu/php-sdk/README.md
index 16c8b49f5..447a07d9f 100644
--- a/vendor/qiniu/php-sdk/README.md
+++ b/vendor/qiniu/php-sdk/README.md
@@ -1,21 +1,22 @@
 # Qiniu Cloud SDK for PHP
-[![doxygen.io](http://doxygen.io/github.com/qiniu/php-sdk/?status.svg)](http://doxygen.io/github.com/qiniu/php-sdk/)
 [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE)
 [![Build Status](https://travis-ci.org/qiniu/php-sdk.svg)](https://travis-ci.org/qiniu/php-sdk)
+[![GitHub release](https://img.shields.io/github/v/tag/qiniu/php-sdk.svg?label=release)](https://github.com/qiniu/php-sdk/releases)
 [![Latest Stable Version](https://img.shields.io/packagist/v/qiniu/php-sdk.svg)](https://packagist.org/packages/qiniu/php-sdk)
 [![Total Downloads](https://img.shields.io/packagist/dt/qiniu/php-sdk.svg)](https://packagist.org/packages/qiniu/php-sdk)
 [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/qiniu/php-sdk/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/qiniu/php-sdk/?branch=master)
-[![Code Coverage](https://scrutinizer-ci.com/g/qiniu/php-sdk/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/qiniu/php-sdk/?branch=master)
+[![Coverage Status](https://codecov.io/gh/qiniu/php-sdk/branch/master/graph/badge.svg)](https://codecov.io/gh/qiniu/php-sdk)
 [![Join Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/qiniu/php-sdk?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 [![@qiniu on weibo](http://img.shields.io/badge/weibo-%40qiniutek-blue.svg)](http://weibo.com/qiniutek)
 
+
 ## 安装
 
-* 通过composer,这是推荐的方式,可以使用composer.json 声明依赖,或者运行下面的命令。SDK 包已经放到这里 [`qiniu/php-sdk`][install-packagist] 。
+* 推荐使用 `composer` 进行安装。可以使用 composer.json 声明依赖,或者运行下面的命令。SDK 包已经放到这里 [`qiniu/php-sdk`][install-packagist] 。
 ```bash
 $ composer require qiniu/php-sdk
 ```
-* 直接下载安装,SDK 没有依赖其他第三方库,但需要参照 composer的autoloader,增加一个自己的autoloader程序。
+* 直接下载安装,SDK 没有依赖其他第三方库,但需要参照 composer 的 autoloader,增加一个自己的 autoloader 程序。
 
 ## 运行环境
 
@@ -31,10 +32,10 @@ $ composer require qiniu/php-sdk
 use Qiniu\Storage\UploadManager;
 use Qiniu\Auth;
 ...
-    $upManager = new UploadManager();
+    $uploadMgr = new UploadManager();
     $auth = new Auth($accessKey, $secretKey);
-    $token = $auth->uploadToken($bucketName);
-    list($ret, $error) = $upManager->put($token, 'formput', 'hello world');
+    $token = $auth->uploadToken($bucket);
+    list($ret, $error) = $uploadMgr->putFile($token, 'key', 'filePath');
 ...
 ```
 
@@ -46,8 +47,8 @@ $ ./vendor/bin/phpunit tests/Qiniu/Tests/
 
 ## 常见问题
 
-- $error保留了请求响应的信息,失败情况下ret 为none, 将$error可以打印出来,提交给我们。
-- API 的使用 demo 可以参考 [单元测试](https://github.com/qiniu/php-sdk/blob/master/tests)。
+- `$error` 保留了请求响应的信息,失败情况下 `ret` 为 `none`, 将 `$error` 可以打印出来,提交给我们。
+- API 的使用 demo 可以参考 [examples](https://github.com/qiniu/php-sdk/tree/master/examples)。
 
 ## 代码贡献
 
@@ -60,12 +61,12 @@ $ ./vendor/bin/phpunit tests/Qiniu/Tests/
 ## 联系我们
 
 - 如果需要帮助,请提交工单(在portal右侧点击咨询和建议提交工单,或者直接向 support@qiniu.com 发送邮件)
-- 如果有什么问题,可以到问答社区提问,[问答社区](http://qiniu.segmentfault.com/)
-- 更详细的文档,见[官方文档站](http://developer.qiniu.com/)
-- 如果发现了bug, 欢迎提交 [issue](https://github.com/qiniu/php-sdk/issues)
+- 如果有什么问题,可以到问答社区提问,[问答社区](https://qiniu.segmentfault.com/)
+- 更详细的文档,见[官方文档站](https://developer.qiniu.com/)
+- 如果发现了 bug, 欢迎提交 [issue](https://github.com/qiniu/php-sdk/issues)
 - 如果有功能需求,欢迎提交 [issue](https://github.com/qiniu/php-sdk/issues)
 - 如果要提交代码,欢迎提交 pull request
-- 欢迎关注我们的[微信](http://www.qiniu.com/#weixin) [微博](http://weibo.com/qiniutek),及时获取动态信息。
+- 欢迎关注我们的[微信](https://www.qiniu.com/#weixin) [微博](https://weibo.com/qiniutek),及时获取动态信息。
 
 ## 代码许可
 
diff --git a/vendor/qiniu/php-sdk/docs/rtc/README.md b/vendor/qiniu/php-sdk/docs/rtc/README.md
deleted file mode 100755
index 7b98ca0f9..000000000
--- a/vendor/qiniu/php-sdk/docs/rtc/README.md
+++ /dev/null
@@ -1,71 +0,0 @@
-# Rtc Streaming Cloud Server-Side Library For PHP
-
-## Features
-
-- Appclient
-    - [x] 创建房间: client->createApp()
-    - [x] 查看房间: client->getApp()
-    - [x] 删除房间: client->deleteApp()
-    - [x] 生成房间token: client->appToken()
-
-
-
-## Contents
-
-- [Installation](#installation)
-- [Usage](#usage)
-    - [Configuration](#configuration)
-    - [App](#app)
-        - [Create a app](#create-a-app)
-        - [Get a app](#get-a-app)
-        - [Delete a app](#delete-a-app)
-        - [Generate a app token](#generate-a-app-token)
-
-
-## Usage
-
-### App
-
-#### Create a app
-
-```php
-$ak = "gwd_gV4gPKZZsmEOvAuNU1AcumicmuHooTfu64q5";
-$sk = "xxxx";
-$auth = new Auth($ak, $sk);
-$client = new Qiniu\Rtc\AppClient($auth);
-$resp=$client->createApp("901","testApp");
-print_r($resp);
-```
-
-#### Get an app
-
-```php
-$ak = "gwd_gV4gPKZZsmEOvAuNU1AcumicmuHooTfu64q5";
-$sk = "xxxx";
-$auth = new Auth($ak, $sk);
-$client = new Qiniu\Rtc\AppClient($auth);
-$resp=$client->getApp("deq02uhb6");
-print_r($resp);
-```
-
-#### Delete an app
-
-```php
-$ak = "gwd_gV4gPKZZsmEOvAuNU1AcumicmuHooTfu64q5";
-$sk = "xxxx";
-$auth = new Auth($ak, $sk);
-$client = new Qiniu\Rtc\AppClient($auth);
-$resp=$client->deleteApp("deq02uhb6");
-print_r($resp);
-```
-
-#### Generate an app token
-
-```php
-$ak = "gwd_gV4gPKZZsmEOvAuNU1AcumicmuHooTfu64q5";
-$sk = "xxxx";
-$auth = new Auth($ak, $sk);
-$client = new Qiniu\Rtc\AppClient($auth);
-$resp=$client->appToken("deq02uhb6", "lfx", '1111', (time()+3600), 'user');
-print_r($resp);
-```
\ No newline at end of file
diff --git a/vendor/qiniu/php-sdk/docs/rtc/example.php b/vendor/qiniu/php-sdk/docs/rtc/example.php
deleted file mode 100755
index f30b9b415..000000000
--- a/vendor/qiniu/php-sdk/docs/rtc/example.php
+++ /dev/null
@@ -1,42 +0,0 @@
-createApp($hub, $title, $maxUsers);
-    print_r($resp);
-    // 获取app状态
-    $resp = $client->getApp('dgdl5ge8y');
-    print_r($resp);
-    //修改app状态
-    $mergePublishRtmp = null;
-    $mergePublishRtmp['enable'] = true;
-    $resp = $client->updateApp('dgdl5ge8y', $hub, $title, $maxUsers, $mergePublishRtmp);
-    print_r($resp);
-    //删除app
-    $resp = $client->deleteApp('dgdl5ge8y');
-    print_r($resp);
-    //获取房间连麦的成员
-    $resp=$client->listUser("dgbfvvzid", 'lfxl');
-    print_r($resp);
-    //剔除房间的连麦成员
-    $resp=$client->kickUser("dgbfvvzid", 'lfx', "qiniu-f6e07b78-4dc8-45fb-a701-a9e158abb8e6");
-    print_r($resp);
-    // 列举房间
-    $resp=$client->listActiveRooms("dgbfvvzid", 'lfx', null, null);
-    print_r($resp);
-    //鉴权的有效时间: 1个小时.
-    $resp = $client->appToken("dgd4vecde", "lfxl", '1111', (time()+3600), 'user');
-    print_r($resp);
-} catch (\Exception $e) {
-    echo "Error:", $e, "\n";
-}
diff --git a/vendor/qiniu/php-sdk/docs/sms/example.php b/vendor/qiniu/php-sdk/docs/sms/example.php
deleted file mode 100644
index 541c0d6c2..000000000
--- a/vendor/qiniu/php-sdk/docs/sms/example.php
+++ /dev/null
@@ -1,70 +0,0 @@
- 'code' );
-try {
-    //发送短信
-    $resp = $client->sendMessage($template_id, $mobiles, $code);
-    print_r($resp);
-} catch (\Exception $e) {
-    echo "Error:", $e, "\n";
-}exit;
-//模板模块
-$name="tstest001";
-$template="tesy001 ${code}";
-$type="notification";
-$description="tstest001";
-$signature_id="1131464448834277376";
-$id="1131810682442883072";
-
-try {
-    //创建模板
-    $resp = $client->createTemplate($name, $template, $type, $description, $signature_id);
-    print_r($resp);
-    //查询模板
-    $resp = $client->queryTemplate();
-    print_r($resp);
-    //修改模板
-    $resp = $client->updateTemplate($id, $name, $template, $description, $signature_id);
-    print_r($resp);
-    //删除模板
-    $resp = $client->deleteTemplate($id);
-    print_r($resp);
-} catch (\Exception $e) {
-    echo "Error:", $e, "\n";
-}
-//签名模块
-$signature = 'lfxlive2';
-$source = 'enterprises_and_institutions';
-$pic="/Users/Desktop/sss.jpg";
-$audit_status="passed";
-$page=1;
-$page_size=1;
-$id="1131464448834277376";
-
-try {
-    //创建签名
-    $resp = $client->createSignature($signature, $source, $pic);
-    print_r($resp);
-     //查询签名
-    $resp = $client->checkSignature($audit_status);
-    //修改签名
-    $resp = $client->updateSignature($id, $signature, $source, $pic);
-    print_r($resp);
-    //删除ID
-    $resp = $client->deleteSignature($id);
-    print_r($resp);
-} catch (\Exception $e) {
-    echo "Error:", $e, "\n";
-}
diff --git a/vendor/qiniu/php-sdk/examples/README.md b/vendor/qiniu/php-sdk/examples/README.md
index 6cf8e30af..b7b4f98ee 100644
--- a/vendor/qiniu/php-sdk/examples/README.md
+++ b/vendor/qiniu/php-sdk/examples/README.md
@@ -1,10 +1,10 @@
 # examples
 
-这些 examples 旨在帮助你快速了解使用七牛的sdk。这些demo都是可以直接运行的, 但是在运行之前需要填上您自己的参数。
+这些 examples 旨在帮助你快速了解使用七牛的 SDK。这些 demo 都是可以直接运行的, 但是在运行之前需要填上您自己的参数。
 
 比如:
 
-* `$bucket`  需要填上您想操作的 [bucket名字](http://developer.qiniu.com/docs/v6/api/overview/concepts.html#bucket)。
-* `$accessKey` 和 `$secretKey` 可以在我们的[管理后台](https://portal.qiniu.com/setting/key)找到。
-* 在进行`视频转码`, `压缩文件`等异步操作时 需要使用到的队列名称也可以在我们[管理后台](https://portal.qiniu.com/mps/pipeline)新建。
+* `$bucket`  需要填上您想操作的 [bucket名字](https://portal.qiniu.com/kodo/bucket)。
+* `$accessKey` 和 `$secretKey` 可以在我们的[管理后台](https://portal.qiniu.com/user/key)找到。
+* 在进行`视频转码`, `压缩文件`等异步操作时 需要使用到的队列名称也可以在我们[管理后台](https://portal.qiniu.com/dora/media-gate/pipeline)新建。
 
diff --git a/vendor/qiniu/php-sdk/examples/bucket_lifecycleRule.php b/vendor/qiniu/php-sdk/examples/bucket_lifecycleRule.php
index 3f7fefd5b..8827207a1 100644
--- a/vendor/qiniu/php-sdk/examples/bucket_lifecycleRule.php
+++ b/vendor/qiniu/php-sdk/examples/bucket_lifecycleRule.php
@@ -2,29 +2,35 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$bucket = 'xxxx';
-$name = 'demo';
-$prefix = 'test';
-$delete_after_days = 80;
-$to_line_after_days =70;
+// 存储空间 - 新增生命周期规则
+// 参考文档:https://developer.qiniu.com/kodo/manual/3699/life-cycle-management
 
-list($Info, $err) = $bucketManager->bucketLifecycleRule(
+$bucket = 'xxxx'; // 存储空间名称
+$name = 'demo';   // 生命周期规则名称
+$prefix = 'test'; // 规则策略中的前缀
+$delete_after_days = 80; // 用户新创建的文件将在该设定时间之后自动删除
+$to_line_after_days = 70; // 用户新创建的文件将在该设定的时间之后自动转为低频存储
+
+list($ret, $err) = $bucketManager->bucketLifecycleRule(
     $bucket,
     $name,
     $prefix,
     $delete_after_days,
     $to_line_after_days
 );
-if ($err) {
-    print_r($err);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/cdn_get_bandwidth.php b/vendor/qiniu/php-sdk/examples/cdn_get_bandwidth.php
index 4d2ccf6f6..c9de0e69b 100644
--- a/vendor/qiniu/php-sdk/examples/cdn_get_bandwidth.php
+++ b/vendor/qiniu/php-sdk/examples/cdn_get_bandwidth.php
@@ -2,29 +2,30 @@
 
 require_once __DIR__ . '/../autoload.php';
 
-use \Qiniu\Cdn\CdnManager;
+use Qiniu\Auth;
+use Qiniu\Cdn\CdnManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
-$auth = new Qiniu\Auth($accessKey, $secretKey);
+$auth = new Auth($accessKey, $secretKey);
 $cdnManager = new CdnManager($auth);
 
-//获取流量和带宽数据
-//参考文档:http://developer.qiniu.com/article/fusion/api/traffic-bandwidth.html
+// 获取流量和带宽数据
+// 参考文档:https://developer.qiniu.com/fusion/api/1230/traffic-bandwidth
 
 $domains = array(
     "javasdk.qiniudn.com",
     "phpsdk.qiniudn.com"
 );
 
-$startDate = "2017-08-20";
-$endDate = "2017-08-21";
+$startDate = "2020-08-03";
+$endDate = "2020-08-05";
 
-//5min or hour or day
+// 5min or hour or day
 $granularity = "day";
 
-//获取带宽数据
 list($bandwidthData, $getBandwidthErr) = $cdnManager->getBandwidthData(
     $domains,
     $startDate,
diff --git a/vendor/qiniu/php-sdk/examples/cdn_get_flux.php b/vendor/qiniu/php-sdk/examples/cdn_get_flux.php
index 56da550a1..57df80855 100644
--- a/vendor/qiniu/php-sdk/examples/cdn_get_flux.php
+++ b/vendor/qiniu/php-sdk/examples/cdn_get_flux.php
@@ -2,29 +2,30 @@
 
 require_once __DIR__ . '/../autoload.php';
 
+use Qiniu\Auth;
 use \Qiniu\Cdn\CdnManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
-$auth = new Qiniu\Auth($accessKey, $secretKey);
+$auth = new Auth($accessKey, $secretKey);
 $cdnManager = new CdnManager($auth);
 
-//获取流量和带宽数据
-//参考文档:http://developer.qiniu.com/article/fusion/api/traffic-bandwidth.html
+// 获取流量和带宽数据
+// 参考文档:https://developer.qiniu.com/fusion/api/1230/traffic-bandwidth
 
 $domains = array(
     "javasdk.qiniudn.com",
     "phpsdk.qiniudn.com"
 );
 
-$startDate = "2017-08-20";
-$endDate = "2017-08-21";
+$startDate = "2020-08-03";
+$endDate = "2020-08-05";
 
 //5min or hour or day
 $granularity = "day";
 
-//获取流量数据
 list($fluxData, $getFluxErr) = $cdnManager->getFluxData($domains, $startDate, $endDate, $granularity);
 if ($getFluxErr != null) {
     var_dump($getFluxErr);
diff --git a/vendor/qiniu/php-sdk/examples/cdn_get_log_list.php b/vendor/qiniu/php-sdk/examples/cdn_get_log_list.php
index 4e5c9424f..2b3f7dd81 100644
--- a/vendor/qiniu/php-sdk/examples/cdn_get_log_list.php
+++ b/vendor/qiniu/php-sdk/examples/cdn_get_log_list.php
@@ -2,23 +2,25 @@
 
 require_once __DIR__ . '/../autoload.php';
 
-use \Qiniu\Cdn\CdnManager;
+use Qiniu\Auth;
+use Qiniu\Cdn\CdnManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
-$auth = new Qiniu\Auth($accessKey, $secretKey);
+$auth = new Auth($accessKey, $secretKey);
 $cdnManager = new CdnManager($auth);
 
+// 获取日志下载链接
+// 参考文档:https://developer.qiniu.com/fusion/api/1226/download-the-log
+
 $domains = array(
     "javasdk.qiniudn.com",
     "phpsdk.qiniudn.com"
 );
 
-$logDate = '2017-08-20';
-
-//获取日志下载链接
-//参考文档:http://developer.qiniu.com/article/fusion/api/log.html
+$logDate = '2020-08-05';
 
 list($logListData, $getLogErr) = $cdnManager->getCdnLogList($domains, $logDate);
 if ($getLogErr != null) {
diff --git a/vendor/qiniu/php-sdk/examples/cdn_get_prefetch_list.php b/vendor/qiniu/php-sdk/examples/cdn_get_prefetch_list.php
new file mode 100644
index 000000000..958e5eb49
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/cdn_get_prefetch_list.php
@@ -0,0 +1,46 @@
+getCdnPrefetchList(
+    $requestId,
+    $urls,
+    $state,
+    $pageNo,
+    $pageSize,
+    $startTime,
+    $endTime
+);
+echo "\n====> query prefetch list: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/cdn_get_refresh_list.php b/vendor/qiniu/php-sdk/examples/cdn_get_refresh_list.php
new file mode 100644
index 000000000..ad4fca2fb
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/cdn_get_refresh_list.php
@@ -0,0 +1,48 @@
+getCdnRefreshList(
+    $requestId,
+    $isDir,
+    $urls,
+    $state,
+    $pageNo,
+    $pageSize,
+    $startTime,
+    $endTime
+);
+echo "\n====> query refresh list: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/cdn_refresh_urls_dirs.php b/vendor/qiniu/php-sdk/examples/cdn_refresh_urls_dirs.php
index c05e75f2f..214037861 100644
--- a/vendor/qiniu/php-sdk/examples/cdn_refresh_urls_dirs.php
+++ b/vendor/qiniu/php-sdk/examples/cdn_refresh_urls_dirs.php
@@ -2,29 +2,32 @@
 
 require_once __DIR__ . '/../autoload.php';
 
-use \Qiniu\Cdn\CdnManager;
+use Qiniu\Auth;
+use Qiniu\Cdn\CdnManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
-$auth = new Qiniu\Auth($accessKey, $secretKey);
+$auth = new Auth($accessKey, $secretKey);
+
+//---------------------------------------- demo1 ----------------------------------------
+// 刷新文件和目录
+// 文件列表一次最多提交 60 个,目录一次最多提交 10 个
+// 参考文档:https://developer.qiniu.com/fusion/api/1229/cache-refresh
 
-//待刷新的文件列表和目录,文件列表最多一次100个,目录最多一次10个
-//参考文档:http://developer.qiniu.com/article/fusion/api/refresh.html
 $urls = array(
     "http://phpsdk.qiniudn.com/qiniu.jpg",
     "http://phpsdk.qiniudn.com/qiniu2.jpg",
 );
 
-//刷新目录需要联系七牛技术支持开通账户权限
 $dirs = array(
     "http://phpsdk.qiniudn.com/test/"
 );
 
 $cdnManager = new CdnManager($auth);
 
-// 目前客户默认没有目录刷新权限,刷新会有400038报错,参考:https://developer.qiniu.com/fusion/api/1229/cache-refresh
-// 需要刷新目录请工单联系技术支持 https://support.qiniu.com/tickets/category
+// 如果刷新返回 400038 报错,则需要联系七牛技术支持开通刷新目录权限,参考:https://developer.qiniu.com/fusion/api/1229/cache-refresh,
 list($refreshResult, $refreshErr) = $cdnManager->refreshUrlsAndDirs($urls, $dirs);
 if ($refreshErr != null) {
     var_dump($refreshErr);
@@ -33,20 +36,24 @@
     print_r($refreshResult);
 }
 
-//如果只有刷新链接或者目录的需求,可以分布使用
+//---------------------------------------- demo2 ----------------------------------------
+// 刷新文件
 
 list($refreshResult, $refreshErr) = $cdnManager->refreshUrls($urls);
 if ($refreshErr != null) {
     var_dump($refreshErr);
 } else {
-    echo "refresh request sent\n";
+    echo "refresh urls request sent\n";
     print_r($refreshResult);
 }
 
+//---------------------------------------- demo3 ----------------------------------------
+// 刷新目录
+
 list($refreshResult, $refreshErr) = $cdnManager->refreshDirs($dirs);
 if ($refreshErr != null) {
     var_dump($refreshErr);
 } else {
-    echo "refresh request sent\n";
+    echo "refresh dirs request sent\n";
     print_r($refreshResult);
 }
diff --git a/vendor/qiniu/php-sdk/examples/cdn_timestamp_antileech.php b/vendor/qiniu/php-sdk/examples/cdn_timestamp_antileech.php
index d9fd02346..f2d785581 100644
--- a/vendor/qiniu/php-sdk/examples/cdn_timestamp_antileech.php
+++ b/vendor/qiniu/php-sdk/examples/cdn_timestamp_antileech.php
@@ -2,17 +2,18 @@
 
 require_once __DIR__ . '/../autoload.php';
 
-use \Qiniu\Cdn\CdnManager;
+use Qiniu\Cdn\CdnManager;
+
+// 创建带时间戳防盗链的 URL
+// 参考文档:https://developer.qiniu.com/fusion/manual/3841/timestamp-hotlinking-prevention-fusion
 
-//创建时间戳防盗链
-//时间戳防盗链密钥,后台获取
 $encryptKey = 'your_domain_timestamp_antileech_encryptkey';
 
-//带访问协议的域名
-$url1 = 'http://phpsdk.qiniuts.com/24.jpg?avinfo';
+// 一定要带访问协议,也就是 http:// 或者 https://
+$url1 = 'http://phpsdk.qiniuts.com/24.jpg?imageInfo';
 $url2 = 'http://phpsdk.qiniuts.com/24.jpg';
 
-//有效期时间(单位秒)
+// 有效期时间(单位秒)
 $durationInSeconds = 3600;
 
 $signedUrl = CdnManager::createTimestampAntiLeechUrl($url1, $encryptKey, $durationInSeconds);
diff --git a/vendor/qiniu/php-sdk/examples/censor_image.php b/vendor/qiniu/php-sdk/examples/censor_image.php
new file mode 100644
index 000000000..06e0522c9
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/censor_image.php
@@ -0,0 +1,42 @@
+censorImage($body);
+echo "\n====> Result is: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/censor_video.php b/vendor/qiniu/php-sdk/examples/censor_video.php
new file mode 100755
index 000000000..7ac056fae
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/censor_video.php
@@ -0,0 +1,52 @@
+censorVideo($body);
+echo "\n====> Result is: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "job_id is: $jobid\n";
+}
+
+// 查询视频审核结果
+list($ret, $err) = $argusManager->censorStatus($jobid);
+echo "\n====> job status: \n";
+
+if ($err != null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/delete_bucket.php b/vendor/qiniu/php-sdk/examples/delete_bucket.php
index dc2e30505..325a47a7e 100644
--- a/vendor/qiniu/php-sdk/examples/delete_bucket.php
+++ b/vendor/qiniu/php-sdk/examples/delete_bucket.php
@@ -2,19 +2,26 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$name = 'xxxx';
+// 删除指定的 Bucket
+// 1、空间绑定了自定义域名,禁止删除,需要先解绑域名
+// 2、空间不为空,禁止删除,需要先把空间内的文件删除完毕
 
-list($Info, $err) = $bucketManager->deleteBucket($name);
-if ($err) {
-    print_r($err);
+$bucket = 'xxxx'; // 存储空间名称
+
+list($ret, $err) = $bucketManager->deleteBucket($bucket);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/delete_bucketEvent.php b/vendor/qiniu/php-sdk/examples/delete_bucketEvent.php
index 00df6cae2..7eb744def 100644
--- a/vendor/qiniu/php-sdk/examples/delete_bucketEvent.php
+++ b/vendor/qiniu/php-sdk/examples/delete_bucketEvent.php
@@ -2,20 +2,27 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$bucket = 'xxxx';
-$name = 'demo';
+// 删除 bucket 事件通知规则
+// 参考文档:https://developer.qiniu.com/kodo/manual/6095/event-notification
 
-list($Info, $err) = $bucketManager->deleteBucketEvent($bucket, $name);
-if ($err) {
-    print_r($err);
+$bucket = 'xxxx';  // 存储空间名称
+
+$name = 'demo'; // 规则名称 bucket 内唯一,由 1 ~ 50 个字符组成,可包含:字母、数字和下划线
+
+list($ret, $err) = $bucketManager->deleteBucketEvent($bucket, $name);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/delete_bucketLifecycleRule.php b/vendor/qiniu/php-sdk/examples/delete_bucketLifecycleRule.php
index a53699267..2146b1b54 100644
--- a/vendor/qiniu/php-sdk/examples/delete_bucketLifecycleRule.php
+++ b/vendor/qiniu/php-sdk/examples/delete_bucketLifecycleRule.php
@@ -2,20 +2,26 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$bucket = 'xxxx';
-$name = 'demo';
+// 删除存储空间 - 生命周期规则
+// 参考文档:https://developer.qiniu.com/kodo/manual/3699/life-cycle-management
 
-list($Info, $err) = $bucketManager->deleteBucketLifecycleRule($bucket, $name);
-if ($err) {
-    print_r($err);
+$bucket = 'xxxx'; // 存储空间名称
+$name = 'demo'; // 生命周期规则名称
+
+list($ret, $err) = $bucketManager->deleteBucketLifecycleRule($bucket, $name);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/get_bucketEvents.php b/vendor/qiniu/php-sdk/examples/get_bucketEvents.php
index 53a5c88d2..23795847a 100644
--- a/vendor/qiniu/php-sdk/examples/get_bucketEvents.php
+++ b/vendor/qiniu/php-sdk/examples/get_bucketEvents.php
@@ -2,19 +2,25 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$bucket = 'xxxx';
+// 获取存储空间 - 事件通知规则
+// 参考文档:https://developer.qiniu.com/kodo/manual/6095/event-notification
 
-list($Info, $err) = $bucketManager->getBucketEvents($bucket);
-if ($err) {
-    print_r($err);
+$bucket = 'xxxx'; // 存储空间名称
+
+list($ret, $err) = $bucketManager->getBucketEvents($bucket);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/get_bucketLifecycleRules.php b/vendor/qiniu/php-sdk/examples/get_bucketLifecycleRules.php
index 652bee8ce..a35feed4b 100644
--- a/vendor/qiniu/php-sdk/examples/get_bucketLifecycleRules.php
+++ b/vendor/qiniu/php-sdk/examples/get_bucketLifecycleRules.php
@@ -2,19 +2,25 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$bucket = 'xxxx';
+// 获取存储空间 - 生命周期规则
+// 参考文档:https://developer.qiniu.com/kodo/manual/3699/life-cycle-management
 
-list($Info, $err) = $bucketManager->getBucketLifecycleRules($bucket);
-if ($err) {
-    print_r($err);
+$bucket = 'xxxx'; // 存储空间名称
+
+list($ret, $err) = $bucketManager->getBucketLifecycleRules($bucket);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/get_bucketList.php b/vendor/qiniu/php-sdk/examples/get_bucketList.php
index 74aaa65f3..6a2f7b088 100644
--- a/vendor/qiniu/php-sdk/examples/get_bucketList.php
+++ b/vendor/qiniu/php-sdk/examples/get_bucketList.php
@@ -2,19 +2,25 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$region = 'z1';
+// 列举空间,返回 bucket 列表
+// 存储区域参考文档:https://developer.qiniu.com/kodo/manual/1671/region-endpoint
 
-list($Info, $err) = $bucketManager->listbuckets($region);
-if ($err) {
-    print_r($err);
+$region = 'z1';  // 华东:z0,华北:z1,华南:z2,北美:na0,东南亚:as0
+
+list($ret, $err) = $bucketManager->listbuckets($region);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/get_bucketQuota.php b/vendor/qiniu/php-sdk/examples/get_bucketQuota.php
index 563395d61..93474b53b 100644
--- a/vendor/qiniu/php-sdk/examples/get_bucketQuota.php
+++ b/vendor/qiniu/php-sdk/examples/get_bucketQuota.php
@@ -2,19 +2,25 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$bucket = 'xxxx';
+// 获取用户 bucket 配额限制
+// size 表示空间存储量配额,count 表示空间文件数配额,新创建的空间默认没有限额
 
-list($Info, $err) = $bucketManager->getBucketQuota($bucket);
-if ($err) {
-    print_r($err);
+$bucket = 'xxxx'; // 存储空间名称
+
+list($ret, $err) = $bucketManager->getBucketQuota($bucket);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/get_bucketinfo.php b/vendor/qiniu/php-sdk/examples/get_bucketinfo.php
index ff052a436..98fd9f731 100644
--- a/vendor/qiniu/php-sdk/examples/get_bucketinfo.php
+++ b/vendor/qiniu/php-sdk/examples/get_bucketinfo.php
@@ -2,19 +2,24 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$bucket = 'xxxx';
+// 获取指定空间的相关信息
 
-list($Info, $err) = $bucketManager->bucketInfo($bucket);
-if ($err) {
-    print_r($err);
+$bucket = 'xxxx'; // 存储空间名称
+
+list($ret, $err) = $bucketManager->bucketInfo($bucket);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/get_bucketinfos.php b/vendor/qiniu/php-sdk/examples/get_bucketinfos.php
index 0ad650325..5eec1d8b6 100644
--- a/vendor/qiniu/php-sdk/examples/get_bucketinfos.php
+++ b/vendor/qiniu/php-sdk/examples/get_bucketinfos.php
@@ -2,19 +2,25 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$region = 'z1';
+// 获取指定 zone(存储区域)的空间信息列表
+// 存储区域,参考文档:https://developer.qiniu.com/kodo/manual/1671/region-endpoint
 
-list($Info, $err) = $bucketManager->bucketInfos($region);
-if ($err) {
-    print_r($err);
+$region = 'z1';  // 华东:z0,华北:z1,华南:z2,北美:na0,东南亚:as0
+
+list($ret, $err) = $bucketManager->bucketInfos($region);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/get_corsRules.php b/vendor/qiniu/php-sdk/examples/get_corsRules.php
index fbfde2d21..58e28bedc 100644
--- a/vendor/qiniu/php-sdk/examples/get_corsRules.php
+++ b/vendor/qiniu/php-sdk/examples/get_corsRules.php
@@ -2,19 +2,25 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$bucket = 'xxxx';
+// 获取 bucket 设置的跨域信息
+// 参考文档:https://developer.qiniu.com/kodo/manual/6094/set-cors
 
-list($Info, $err) = $bucketManager->getCorsRules($bucket);
-if ($err) {
-    print_r($err);
+$bucket = 'xxxx'; // 存储空间名称
+
+list($ret, $err) = $bucketManager->getCorsRules($bucket);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/image_url_builder.php b/vendor/qiniu/php-sdk/examples/image_url_builder.php
index e99a72868..20e2b00f0 100644
--- a/vendor/qiniu/php-sdk/examples/image_url_builder.php
+++ b/vendor/qiniu/php-sdk/examples/image_url_builder.php
@@ -6,7 +6,7 @@
 
 $imageUrlBuilder = new ImageUrlBuilder();
 
-// 要处理图片
+// 要处理的图片
 $url = 'http://78re52.com1.z0.glb.clouddn.com/resource/gogopher.jpg';
 $url2 = 'http://78re52.com1.z0.glb.clouddn.com/resource/gogopher.jpg?watermark/1/gravity/SouthEast/dx/0/dy/0/image/'
     . 'aHR0cDovL2Fkcy1jZG4uY2h1Y2h1amllLmNvbS9Ga1R6bnpIY2RLdmRBUFc5cHZZZ3pTc21UY0tB';
@@ -38,12 +38,12 @@
  *
  * @param  string $url 图片链接
  * @param  string $image 水印图片链接
- * @param  numeric $dissolve 透明度 [可选]
+ * @param  int $dissolve 透明度 [可选]
  * @param  string $gravity 水印位置 [可选]
- * @param  numeric $dx 横轴边距 [可选]
- * @param  numeric $dy 纵轴边距 [可选]
- * @param  numeric $watermarkScale 自适应原图的短边比例 [可选]
- * @link   http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html
+ * @param  int $dx 横轴边距 [可选]
+ * @param  int $dy 纵轴边距 [可选]
+ * @param  int $watermarkScale 自适应原图的短边比例 [可选]
+ * @link   https://developer.qiniu.com/dora/api/1316/image-watermarking-processing-watermark
  * @return string
  * @author Sherlock Ren 
  */
@@ -60,10 +60,10 @@
  * @param  string $font 文字字体
  * @param  string $fontSize 文字字号
  * @param  string $fontColor 文字颜色 [可选]
- * @param  numeric $dissolve 透明度 [可选]
+ * @param  int $dissolve 透明度 [可选]
  * @param  string $gravity 水印位置 [可选]
- * @param  numeric $dx 横轴边距 [可选]
- * @param  numeric $dy 纵轴边距 [可选]
+ * @param  int $dx 横轴边距 [可选]
+ * @param  int $dy 纵轴边距 [可选]
  * @link   http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html#text-watermark
  * @return string
  * @author Sherlock Ren 
diff --git a/vendor/qiniu/php-sdk/examples/persistent_fop_init.php b/vendor/qiniu/php-sdk/examples/persistent_fop_init.php
index 2df01e9fe..baca84642 100644
--- a/vendor/qiniu/php-sdk/examples/persistent_fop_init.php
+++ b/vendor/qiniu/php-sdk/examples/persistent_fop_init.php
@@ -3,17 +3,16 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
 use Qiniu\Processing\PersistentFop;
 
-$accessKey = 'Access_Key';
-$secretKey = 'Secret_Key';
+// 控制台获取密钥:https://portal.qiniu.com/user/key
+$accessKey = getenv('QINIU_ACCESS_KEY');
+$secretKey = getenv('QINIU_SECRET_KEY');
 $auth = new Auth($accessKey, $secretKey);
 
-// 要转码的文件所在的空间。
-$bucket = 'Bucket_Name';
-
-// 转码是使用的队列名称。 https://portal.qiniu.com/mps/pipeline
-$pipeline = 'pipeline_name';
+$config = new Config();
+$config->useHTTPS=true;
 
 // 初始化
-$pfop = new PersistentFop($auth, $bucket, $pipeline);
+$pfop = new PersistentFop($auth, $config);
diff --git a/vendor/qiniu/php-sdk/examples/persistent_fop_status.php b/vendor/qiniu/php-sdk/examples/persistent_fop_status.php
index 0c26f7a88..73e85a384 100644
--- a/vendor/qiniu/php-sdk/examples/persistent_fop_status.php
+++ b/vendor/qiniu/php-sdk/examples/persistent_fop_status.php
@@ -5,14 +5,15 @@
 
 $pfop = new Qiniu\Processing\PersistentFop(null, null);
 
-// 触发持久化处理后返回的 Id
-$persistentId = 'z1.5b8a48e5856db843bc24cfc3';
+// 通过 persistentId 来主动查询持久化处理(prefop)的执行状态
+// 参考文档:https://developer.qiniu.com/dora/api/1294/persistent-processing-status-query-prefop
 
-// 通过persistentId查询该 触发持久化处理的状态
-list($ret, $err) = $pfop->status($persistentId);
+// 触发持久化处理后返回的 persistentId
+$persistentId = 'z2.01z201c4oyre6q1hgy00murnel0002nh';
 
-if ($err) {
-    print_r($err);
+list($ret, $err) = $pfop->status($persistentId);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($ret);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/pfop_mkzip.php b/vendor/qiniu/php-sdk/examples/pfop_mkzip.php
index 746b3568e..fb95cc22a 100644
--- a/vendor/qiniu/php-sdk/examples/pfop_mkzip.php
+++ b/vendor/qiniu/php-sdk/examples/pfop_mkzip.php
@@ -4,30 +4,39 @@
 use Qiniu\Auth;
 use Qiniu\Processing\PersistentFop;
 
-// 去我们的portal 后台来获取AK, SK
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
+
+$auth = new Auth($accessKey, $secretKey);
+
+// 将七牛存储空间中的资源进行批量压缩
+// 参考文档:https://developer.qiniu.com/dora/api/1667/mkzip
+
+// 要压缩的文件所在的空间和文件名
 $bucket = getenv('QINIU_TEST_BUCKET');
 $key = 'qiniu.png';
 
-$auth = new Auth($accessKey, $secretKey);
-// 异步任务的队列, 去后台新建: https://portal.qiniu.com/mps/pipeline
+// 用户默认没有私有队列,需要在这里创建然后填写 https://portal.qiniu.com/dora/media-gate/pipeline
 $pipeline = 'sdktest';
 
 $pfop = new PersistentFop($auth, null);
 
-// 进行zip压缩的url
+// 进行 zip 压缩的 url
 $url1 = 'http://phpsdk.qiniudn.com/php-logo.png';
 $url2 = 'http://phpsdk.qiniudn.com/1.png';
 
-//压缩后的key
+// 压缩后的 key
 $zipKey = 'test.zip';
 
 $fops = 'mkzip/2/url/' . \Qiniu\base64_urlSafeEncode($url1);
 $fops .= '/url/' . \Qiniu\base64_urlSafeEncode($url2);
 $fops .= '|saveas/' . \Qiniu\base64_urlSafeEncode("$bucket:$zipKey");
 
+// 处理完成后通知到你的业务服务器(需要可以公网访问,并能够相应 200 OK)
 $notify_url = null;
+
+// 当转码后的文件名与源文件名相同时,是否覆盖源文件
 $force = false;
 
 list($id, $err) = $pfop->execute($bucket, $key, $fops, $pipeline, $notify_url, $force);
@@ -37,7 +46,13 @@
     var_dump($err);
 } else {
     echo "PersistentFop Id: $id\n";
+}
 
-    $res = "http://api.qiniu.com/status/get/prefop?id=$id";
-    echo "Processing result: $res";
+// 查询转码的进度和状态
+list($ret, $err) = $pfop->status($id);
+echo "\n====> pfop mkzip status: \n";
+if ($err != null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/pfop_vframe.php b/vendor/qiniu/php-sdk/examples/pfop_vframe.php
index e1df2d54d..49fd36d8d 100644
--- a/vendor/qiniu/php-sdk/examples/pfop_vframe.php
+++ b/vendor/qiniu/php-sdk/examples/pfop_vframe.php
@@ -2,31 +2,40 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
 use Qiniu\Processing\PersistentFop;
 
-//对已经上传到七牛的视频发起异步转码操作 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
-$bucket = getenv('QINIU_TEST_BUCKET');
 $auth = new Auth($accessKey, $secretKey);
 
-//要转码的文件所在的空间和文件名。
+// 对已经上传到七牛的视频发起异步转码操作
+// 视频帧缩略图参考文档:https://developer.qiniu.com/dora/api/1313/video-frame-thumbnails-vframe
+
+// 要转码的文件所在的空间和文件名
+$bucket = getenv('QINIU_TEST_BUCKET');
 $key = 'qiniu.mp4';
 
-//转码是使用的队列名称。 https://portal.qiniu.com/mps/pipeline
+// 用户默认没有私有队列,需要在这里创建然后填写 https://portal.qiniu.com/dora/media-gate/pipeline
 $pipeline = 'sdktest';
 
-//转码完成后通知到你的业务服务器。
+// 转码完成后通知到你的业务服务器(需要可以公网访问,并能够相应 200 OK)
 $notifyUrl = 'http://375dec79.ngrok.com/notify.php';
+
+// 当转码后的文件名与源文件名相同时,是否覆盖源文件
 $force = false;
 
-$config = new \Qiniu\Config();
+$config = new Config();
 $config->useHTTPS = true;
 $pfop = new PersistentFop($auth, $config);
 
-//要进行视频截图操作
+// 视频处理完毕后保存到空间中的名称
+$saveasKey = 'qiniu_480x360.jpg';
+
+// 进行视频截帧操作
 $fops = "vframe/jpg/offset/1/w/480/h/360/rotate/90|saveas/" .
-    \Qiniu\base64_urlSafeEncode($bucket . ":qiniu_480x360.jpg");
+    \Qiniu\base64_urlSafeEncode("$bucket:$saveasKey");
 
 list($id, $err) = $pfop->execute($bucket, $key, $fops, $pipeline, $notifyUrl, $force);
 echo "\n====> pfop avthumb result: \n";
@@ -36,7 +45,7 @@
     echo "PersistentFop Id: $id\n";
 }
 
-//查询转码的进度和状态
+// 查询转码的进度和状态
 list($ret, $err) = $pfop->status($id);
 echo "\n====> pfop avthumb status: \n";
 if ($err != null) {
diff --git a/vendor/qiniu/php-sdk/examples/pfop_video_avthumb.php b/vendor/qiniu/php-sdk/examples/pfop_video_avthumb.php
index aebe81545..986aa8cc3 100644
--- a/vendor/qiniu/php-sdk/examples/pfop_video_avthumb.php
+++ b/vendor/qiniu/php-sdk/examples/pfop_video_avthumb.php
@@ -2,32 +2,40 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
 use Qiniu\Processing\PersistentFop;
 
-//对已经上传到七牛的视频发起异步转码操作
-
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
-$bucket = getenv('QINIU_TEST_BUCKET');
 
 $auth = new Auth($accessKey, $secretKey);
 
-//要转码的文件所在的空间和文件名。
+// 对已经上传到七牛的视频发起异步转码操作
+// 普通音视频转码参考文档:https://developer.qiniu.com/dora/api/1248/audio-and-video-transcoding-avthumb
+
+// 要转码的文件所在的空间和文件名。
+$bucket = getenv('QINIU_TEST_BUCKET');
 $key = 'qiniu.mp4';
 
-//转码是使用的队列名称。 https://portal.qiniu.com/mps/pipeline
+// 用户默认没有私有队列,需要在这里创建然后填写 https://portal.qiniu.com/dora/media-gate/pipeline
 $pipeline = 'sdktest';
+
+// 当转码后的文件名与源文件名相同时,是否覆盖源文件
 $force = false;
 
-//转码完成后通知到你的业务服务器。
+// 转码完成后通知到你的业务服务器(需要可以公网访问,并能够相应 200 OK)
 $notifyUrl = 'http://375dec79.ngrok.com/notify.php';
-$config = new \Qiniu\Config();
-//$config->useHTTPS=true;
+$config = new Config();
+$config->useHTTPS=true;
+
+// 视频处理完毕后保存到空间中的名称
+$saveasKey = 'qiniu_640x360.mp4';
 
 $pfop = new PersistentFop($auth, $config);
 
-//要进行转码的转码操作。 http://developer.qiniu.com/docs/v6/api/reference/fop/av/avthumb.html
-$fops = "avthumb/mp4/s/640x360/vb/1.4m|saveas/" . \Qiniu\base64_urlSafeEncode($bucket . ":qiniu_640x360.mp4");
+// 进行视频转码操作
+$fops = "avthumb/mp4/s/640x360/vb/1.4m|saveas/" . \Qiniu\base64_urlSafeEncode("$bucket:$saveasKey");
 
 list($id, $err) = $pfop->execute($bucket, $key, $fops, $pipeline, $notifyUrl, $force);
 echo "\n====> pfop avthumb result: \n";
@@ -37,7 +45,7 @@
     echo "PersistentFop Id: $id\n";
 }
 
-//查询转码的进度和状态
+// 查询转码的进度和状态
 list($ret, $err) = $pfop->status($id);
 echo "\n====> pfop avthumb status: \n";
 if ($err != null) {
diff --git a/vendor/qiniu/php-sdk/examples/pfop_watermark.php b/vendor/qiniu/php-sdk/examples/pfop_watermark.php
index 72aa6c443..ea3d6bc88 100644
--- a/vendor/qiniu/php-sdk/examples/pfop_watermark.php
+++ b/vendor/qiniu/php-sdk/examples/pfop_watermark.php
@@ -2,37 +2,44 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
 use Qiniu\Processing\PersistentFop;
 
-//对已经上传到七牛的视频发起异步转码操作 
-
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
-$bucket = getenv('QINIU_TEST_BUCKET');
 
 $auth = new Auth($accessKey, $secretKey);
 
-//要转码的文件所在的空间和文件名。
+// 对已经上传到七牛的视频发起异步转码操作
+// 视频水印参考文档:https://developer.qiniu.com/dora/api/1314/video-watermarking
+
+// 要转码的文件所在的空间和文件名
+$bucket = getenv('QINIU_TEST_BUCKET');
 $key = 'qiniu.mp4';
 
-//转码是使用的队列名称。 https://portal.qiniu.com/mps/pipeline
+// 用户默认没有私有队列,需要在这里创建然后填写 https://portal.qiniu.com/dora/media-gate/pipeline
 $pipeline = 'sdktest';
 
-//转码完成后通知到你的业务服务器。
+// 转码完成后通知到你的业务服务器(需要可以公网访问,并能够相应 200 OK)
 $notifyUrl = 'http://375dec79.ngrok.com/notify.php';
+
+// 当转码后的文件名与源文件名相同时,是否覆盖源文件
 $force = false;
 
-$config = new \Qiniu\Config();
-//$config->useHTTPS=true;
+$config = new Config();
+$config->useHTTPS=true;
 $pfop = new PersistentFop($auth, $config);
 
-//需要添加水印的图片UrlSafeBase64
-//可以参考http://developer.qiniu.com/code/v6/api/dora-api/av/video-watermark.html
-$base64URL = Qiniu\base64_urlSafeEncode('http://devtools.qiniu.com/qiniu.png');
+// 图片水印的源路径,也就是给视频打图片水印的图片
+$base64URL = Qiniu\base64_urlSafeEncode('http://test-2.qiniudn.com/logo.png');
+
+// 视频处理完毕后保存到空间中的名称
+$saveasKey = 'qiniu_watermark.mp4';
 
-//水印参数
-$fops = "avthumb/mp4/s/640x360/vb/1.4m/image/" . $base64URL . "|saveas/"
-    . \Qiniu\base64_urlSafeEncode($bucket . ":qiniu_wm.mp4");
+// 进行视频打图片水印操作
+$fops = "avthumb/mp4/wmImage/" . $base64URL . "|saveas/"
+    . \Qiniu\base64_urlSafeEncode("$bucket:$saveasKey");
 
 list($id, $err) = $pfop->execute($bucket, $key, $fops, $pipeline, $notifyUrl, $force);
 echo "\n====> pfop avthumb result: \n";
@@ -42,7 +49,7 @@
     echo "PersistentFop Id: $id\n";
 }
 
-//查询转码的进度和状态
+// 查询转码的进度和状态
 list($ret, $err) = $pfop->status($id);
 echo "\n====> pfop avthumb status: \n";
 if ($err != null) {
diff --git a/vendor/qiniu/php-sdk/examples/prefop.php b/vendor/qiniu/php-sdk/examples/prefop.php
index ae61a5f7d..1b8950ae2 100644
--- a/vendor/qiniu/php-sdk/examples/prefop.php
+++ b/vendor/qiniu/php-sdk/examples/prefop.php
@@ -2,24 +2,22 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
 use Qiniu\Processing\PersistentFop;
 
-$accessKey = 'Access_Key';
-$secretKey = 'Secret_Key';
+// 控制台获取密钥:https://portal.qiniu.com/user/key
+$accessKey = getenv('QINIU_ACCESS_KEY');
+$secretKey = getenv('QINIU_SECRET_KEY');
 $auth = new Auth($accessKey, $secretKey);
 
-//要持久化处理的文件所在的空间和文件名。
-$bucket = 'Bucket_Name';
+$config = new Config();
+$config->useHTTPS=true;
 
-//持久化处理使用的队列名称。 https://portal.qiniu.com/mps/pipeline
-$pipeline = 'pipeline_name';
+$pfop = new PersistentFop($auth, $config);
 
-//持久化处理完成后通知到你的业务服务器。
-$notifyUrl = 'http://375dec79.ngrok.com/notify.php';
-$pfop = new PersistentFop($auth, $bucket, $pipeline, $notifyUrl);
+$id = "z2.01z201c4oyre6q1hgy00murnel0002nh";
 
-$id = "z2.5955c739e3d0041bf80c9baa";
-//查询持久化处理的进度和状态
+// 查询持久化处理的进度和状态
 list($ret, $err) = $pfop->status($id);
 echo "\n====> pfop avthumb status: \n";
 if ($err != null) {
diff --git a/vendor/qiniu/php-sdk/examples/pulpvideo.php b/vendor/qiniu/php-sdk/examples/pulpvideo.php
deleted file mode 100755
index bad8821c5..000000000
--- a/vendor/qiniu/php-sdk/examples/pulpvideo.php
+++ /dev/null
@@ -1,55 +0,0 @@
- 'pulp',
-        'params' => array(
-            'labels' => array(
-                array(
-                    'label' => "1",
-                    'select' => 1,
-                    'score' => 2,
-                ),
-            )
-        )
-    ),
-);
-
-$params = array();
-$params = array(
-    'async' => false,
-    'vframe' => array(
-        'mode' => 1,
-        'interval' => 8,
-    )
-);
-
-$req = array();
-$req['data'] = $reqBody;
-$req['ops'] = $ops;
-$req['params'] = $params;
-$body = json_encode($req);
-
-$vid = "xxxx";
-list($ret, $err) = $argusManager->pulpVideo($body, $vid);
-
-if ($err !== null) {
-    var_dump($err);
-} else {
-    var_dump($ret);
-}
diff --git a/vendor/qiniu/php-sdk/examples/put_bucketAccessMode.php b/vendor/qiniu/php-sdk/examples/put_bucketAccessMode.php
index b4539264a..638ae3c30 100644
--- a/vendor/qiniu/php-sdk/examples/put_bucketAccessMode.php
+++ b/vendor/qiniu/php-sdk/examples/put_bucketAccessMode.php
@@ -2,20 +2,26 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$bucket = 'xxxx';
-$private = 1;
+$bucket = 'xxxx'; // 存储空间名称
+$private = 1; // 公开:0,私有:1
 
-list($Info, $err) = $bucketManager->putBucketAccessMode($bucket, $private);
-if ($err) {
-    print_r($err);
+// 设置 Bucket 访问权限
+// 参考文档:https://developer.qiniu.com/kodo/api/3946/set-bucket-private
+
+list($ret, $err) = $bucketManager->putBucketAccessMode($bucket, $private);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/put_bucketAccessStyleMode.php b/vendor/qiniu/php-sdk/examples/put_bucketAccessStyleMode.php
index 2f7c27f2b..3cc2aec71 100644
--- a/vendor/qiniu/php-sdk/examples/put_bucketAccessStyleMode.php
+++ b/vendor/qiniu/php-sdk/examples/put_bucketAccessStyleMode.php
@@ -2,20 +2,26 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$bucket = 'xxxx';
-$mode = 1;
+$bucket = 'xxxx'; // 存储空间名称
+$mode = 1; // 关闭:0 ,开启:1
 
-list($Info, $err) = $bucketManager->putBucketAccessStyleMode($bucket, $mode);
-if ($err) {
-    print_r($err);
+// 存储空间 - 原图保护开关
+// 原图保护:https://developer.qiniu.com/kodo/kb/1359/what-is-the-original-protection
+
+list($ret, $err) = $bucketManager->putBucketAccessStyleMode($bucket, $mode);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/put_bucketEvent.php b/vendor/qiniu/php-sdk/examples/put_bucketEvent.php
index 33dbb44c0..f3c830d58 100644
--- a/vendor/qiniu/php-sdk/examples/put_bucketEvent.php
+++ b/vendor/qiniu/php-sdk/examples/put_bucketEvent.php
@@ -2,24 +2,31 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
 
-$bucket = 'xxxx';
-$name = 'testdemo';
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
+
+// 增加 bucket 事件通知规则
+// 参考文档:https://developer.qiniu.com/kodo/manual/6095/event-notification
+
+$bucket = getenv('QINIU_TEST_BUCKET');
+$name = 'testnotification';
 $prefix = 'test1';
 $suffix = 'mp3';
 $event = array("move","copy");
-$callbackURL = 'http://www.qiniu.com';
+$callbackURL = 'http://www.qiniu.com'; // 回调服务器地址,需要可以公网访问,并能够相应 200 OK
 
-list($Info, $err) = $bucketManager->putBucketEvent($bucket, $name, $prefix, $suffix, $event, $callbackURL);
-if ($err) {
-    print_r($err);
+list($ret, $err) = $bucketManager->putBucketEvent($bucket, $name, $prefix, $suffix, $event, $callbackURL);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/put_bucketMaxAge.php b/vendor/qiniu/php-sdk/examples/put_bucketMaxAge.php
index 77092e90a..489017467 100644
--- a/vendor/qiniu/php-sdk/examples/put_bucketMaxAge.php
+++ b/vendor/qiniu/php-sdk/examples/put_bucketMaxAge.php
@@ -2,20 +2,26 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-$bucket = 'xxxx';
-$maxAge = 15768000;
+// 设置 Bucket 的 maxAge
+// 参考文档:https://developer.qiniu.com/kodo/kb/1475/space-maxage-attribute-to-the-cache-control
 
-list($Info, $err) = $bucketManager->putBucketMaxAge($bucket, $maxAge);
-if ($err) {
-    print_r($err);
+$bucket = getenv('QINIU_TEST_BUCKET');
+$maxAge = 31536000;
+
+list($ret, $err) = $bucketManager->putBucketMaxAge($bucket, $maxAge);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/put_bucketQuota.php b/vendor/qiniu/php-sdk/examples/put_bucketQuota.php
index 18082b631..b00ec4892 100644
--- a/vendor/qiniu/php-sdk/examples/put_bucketQuota.php
+++ b/vendor/qiniu/php-sdk/examples/put_bucketQuota.php
@@ -2,21 +2,28 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
+$bucket = getenv('QINIU_TEST_BUCKET');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
 
-$bucket = 'xxxx';
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
+
+// 设置 bucket 配额
+// size 表示空间存储量配额,count 表示空间文件数配额,新创建的空间默认没有限额
+
 $size = 99999;
 $count = 99;
 
-list($Info, $err) = $bucketManager->putBucketQuota($bucket, $size, $count);
-if ($err) {
-    print_r($err);
+list($ret, $err) = $bucketManager->putBucketQuota($bucket, $size, $count);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/put_referAntiLeech.php b/vendor/qiniu/php-sdk/examples/put_referAntiLeech.php
index 6828bc9ac..7d56d1ed9 100644
--- a/vendor/qiniu/php-sdk/examples/put_referAntiLeech.php
+++ b/vendor/qiniu/php-sdk/examples/put_referAntiLeech.php
@@ -2,22 +2,29 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
 
-$bucket = 'xxxx';
-$mode = 1;
-$norefer = "1";
-$pattern = "*.qiniu.com";
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
 
-list($Info, $err) = $bucketManager->putReferAntiLeech($bucket, $mode, $norefer, $pattern);
-if ($err) {
-    print_r($err);
+// 存储空间 - 设置 referer 防盗链
+// 参考文档:https://developer.qiniu.com/kodo/manual/6093/set-the-hotlinking-prevention
+
+$bucket = getenv('QINIU_TEST_BUCKET');
+$mode = 1; // 关闭Referer(使用此选项将会忽略以下参数并将恢复默认值):0,设置Referer白名单:1,表示设置Referer黑名单:2
+$norefer = "1"; // 表示不允许空 Refer 访问:0,表示允许空 Refer 访问:1
+$pattern = "*.qiniu.com"; // 当前仅支持这三种格式:a.b.com,*.b.com,*
+
+list($ret, $err) = $bucketManager->putReferAntiLeech($bucket, $mode, $norefer, $pattern);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/qetag.php b/vendor/qiniu/php-sdk/examples/qetag.php
index f6aff8a72..1fe90d16e 100644
--- a/vendor/qiniu/php-sdk/examples/qetag.php
+++ b/vendor/qiniu/php-sdk/examples/qetag.php
@@ -2,10 +2,13 @@
 require_once __DIR__ . '/../autoload.php';
 use Qiniu\Etag;
 
-$localFile = "/Users/jemy/Documents/qiniu.mp4";
-list($etag, $err) = Etag::sum($localFile);
-if ($err == null) {
-    echo "Etag: $etag";
-} else {
+// 计算文件的 ETag
+// 参考文档:https://developer.qiniu.com/kodo/manual/1231/appendix#3
+
+$localFile = "./php-logo.png";
+list($ret, $err) = Etag::sum($localFile);
+if ($err != null) {
     var_dump($err);
+} else {
+    echo "Etag: $ret";
 }
diff --git a/vendor/qiniu/php-sdk/examples/rs_asynch_fetch.php b/vendor/qiniu/php-sdk/examples/rs_asynch_fetch.php
new file mode 100644
index 000000000..7bee00c77
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/rs_asynch_fetch.php
@@ -0,0 +1,71 @@
+useHTTPS = true; // 接口是否使用 HTTPS 协议
+
+$bucketManager = new BucketManager($auth, $config);
+
+// 异步第三方资源抓取
+// 参考文档:https://developer.qiniu.com/kodo/api/4097/asynch-fetch
+
+// 需要抓取的文件 URL
+$url = 'http://devtools.qiniu.com/qiniu.png';
+
+//回调 URL(需要可以公网访问,并能够相应 200 OK)
+$callbackurl = "http://your.domain.com/upload_verify_callback.php";
+
+// 回调Body
+$callbackbody = '{"key":"$(key)","hash":"$(etag)","w":"$(imageInfo.width)","h":"$(imageInfo.height)"}';
+
+
+//---------------------------------------- demo1 ----------------------------------------
+// 指定抓取的文件保存到七牛云空间中的名称
+
+$key = time() . '.png';
+list($ret, $err) = $bucketManager->asynchFetch($url, $bucket, null, $key, null, null, $callbackurl, $callbackbody);
+echo "=====> asynch fetch $url to bucket: $bucket  key: $key\n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    $id = $ret['id'];
+    echo "id is: $id\n";
+}
+
+//---------------------------------------- demo2 ----------------------------------------
+// 不指定 key 时,以文件内容的 hash 作为文件名
+
+$key = null;
+list($ret, $err) = $bucketManager->asynchFetch($url, $bucket, null, $key, null, null, $callbackurl, $callbackbody);
+echo "=====> asynch fetch $url to bucket: $bucket  key: $(etag)\n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    $id = $ret['id'];
+    echo "id is: $id\n";
+}
+
+// 查询异步抓取的进度和状态
+
+// 华东:z0,华北:z1,华南:z2,北美:na0,东南亚:as0
+$zone = 'z2';
+
+sleep(10); // 由于异步抓取需要耗时,等待 10 秒后再查询状态
+list($ret, $err) = $bucketManager->asynchFetchStatus($zone, $id);
+echo "\n====> asynch fetch status: \n";
+if ($err != null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/rs_batch_change_mime.php b/vendor/qiniu/php-sdk/examples/rs_batch_change_mime.php
index d7d07cf77..c5bd6b458 100644
--- a/vendor/qiniu/php-sdk/examples/rs_batch_change_mime.php
+++ b/vendor/qiniu/php-sdk/examples/rs_batch_change_mime.php
@@ -1,18 +1,22 @@
  'video/x-mp4',
     'qiniu.png' => 'image/x-png',
@@ -21,8 +25,8 @@
 
 $ops = $bucketManager->buildBatchChangeMime($bucket, $keyMimePairs);
 list($ret, $err) = $bucketManager->batch($ops);
-if ($err) {
-    print_r($err);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($ret);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/rs_batch_change_type.php b/vendor/qiniu/php-sdk/examples/rs_batch_change_type.php
index 5f3f1cdb0..8a2248333 100644
--- a/vendor/qiniu/php-sdk/examples/rs_batch_change_type.php
+++ b/vendor/qiniu/php-sdk/examples/rs_batch_change_type.php
@@ -1,18 +1,22 @@
 buildBatchChangeType($bucket, $keyTypePairs);
 list($ret, $err) = $bucketManager->batch($ops);
-if ($err) {
-    print_r($err);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($ret);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/rs_batch_copy.php b/vendor/qiniu/php-sdk/examples/rs_batch_copy.php
index 988c642fd..66c4d4d4a 100644
--- a/vendor/qiniu/php-sdk/examples/rs_batch_copy.php
+++ b/vendor/qiniu/php-sdk/examples/rs_batch_copy.php
@@ -1,18 +1,22 @@
 buildBatchCopy($srcBucket, $keyPairs, $destBucket, true);
 list($ret, $err) = $bucketManager->batch($ops);
-if ($err) {
-    print_r($err);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($ret);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/rs_batch_delete.php b/vendor/qiniu/php-sdk/examples/rs_batch_delete.php
index 4f15586a2..ebcdbe663 100644
--- a/vendor/qiniu/php-sdk/examples/rs_batch_delete.php
+++ b/vendor/qiniu/php-sdk/examples/rs_batch_delete.php
@@ -1,18 +1,22 @@
 buildBatchDelete($bucket, $keys);
 list($ret, $err) = $bucketManager->batch($ops);
-if ($err) {
-    print_r($err);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($ret);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/rs_batch_delete_after_days.php b/vendor/qiniu/php-sdk/examples/rs_batch_delete_after_days.php
index dabfe84e4..928dd149f 100644
--- a/vendor/qiniu/php-sdk/examples/rs_batch_delete_after_days.php
+++ b/vendor/qiniu/php-sdk/examples/rs_batch_delete_after_days.php
@@ -1,18 +1,22 @@
 buildBatchDeleteAfterDays($bucket, $keyDayPairs);
 list($ret, $err) = $bucketManager->batch($ops);
-if ($err) {
-    print_r($err);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($ret);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/rs_batch_move.php b/vendor/qiniu/php-sdk/examples/rs_batch_move.php
index 89225221e..01d8c9198 100644
--- a/vendor/qiniu/php-sdk/examples/rs_batch_move.php
+++ b/vendor/qiniu/php-sdk/examples/rs_batch_move.php
@@ -1,18 +1,22 @@
 buildBatchMove($srcBucket, $keyPairs, $destBucket, true);
 list($ret, $err) = $bucketManager->batch($ops);
-if ($err) {
-    print_r($err);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($ret);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/rs_batch_stat.php b/vendor/qiniu/php-sdk/examples/rs_batch_stat.php
index a95fee7b2..88bc32e03 100644
--- a/vendor/qiniu/php-sdk/examples/rs_batch_stat.php
+++ b/vendor/qiniu/php-sdk/examples/rs_batch_stat.php
@@ -1,18 +1,22 @@
 buildBatchStat($bucket, $keys);
 list($ret, $err) = $bucketManager->batch($ops);
-if ($err) {
-    print_r($err);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($ret);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/rs_bucket_domains.php b/vendor/qiniu/php-sdk/examples/rs_bucket_domains.php
index ea27cdc03..3cc9cb3e1 100644
--- a/vendor/qiniu/php-sdk/examples/rs_bucket_domains.php
+++ b/vendor/qiniu/php-sdk/examples/rs_bucket_domains.php
@@ -1,19 +1,26 @@
 domains($bucket);
-if ($err) {
-    print_r($err);
+
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
+
+// 获取指定空间绑定的所有的域名
+// 参考文档:https://developer.qiniu.com/kodo/api/3949/get-the-bucket-space-domain
+
+list($ret, $err) = $bucketManager->domains($bucket);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($domains);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/rs_buckets.php b/vendor/qiniu/php-sdk/examples/rs_buckets.php
index 5fe1304d6..84263a90d 100644
--- a/vendor/qiniu/php-sdk/examples/rs_buckets.php
+++ b/vendor/qiniu/php-sdk/examples/rs_buckets.php
@@ -1,19 +1,25 @@
 buckets(true);
-if ($err) {
-    print_r($err);
+
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
+
+// 获取指定账号下所有的空间名
+// 参考文档:https://developer.qiniu.com/kodo/api/3926/get-service
+
+list($ret, $err) = $bucketManager->buckets(true);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($buckets);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/rs_change_mime.php b/vendor/qiniu/php-sdk/examples/rs_change_mime.php
index 0d3f3ad09..399143de2 100644
--- a/vendor/qiniu/php-sdk/examples/rs_change_mime.php
+++ b/vendor/qiniu/php-sdk/examples/rs_change_mime.php
@@ -1,19 +1,26 @@
 changeMime($bucket, $key, $newMime);
 if ($err) {
     print_r($err);
diff --git a/vendor/qiniu/php-sdk/examples/rs_change_status.php b/vendor/qiniu/php-sdk/examples/rs_change_status.php
index cbcea5c28..40d243bf2 100644
--- a/vendor/qiniu/php-sdk/examples/rs_change_status.php
+++ b/vendor/qiniu/php-sdk/examples/rs_change_status.php
@@ -1,18 +1,25 @@
 changeStatus($bucket, $key, $status);
 if ($err) {
diff --git a/vendor/qiniu/php-sdk/examples/rs_change_type.php b/vendor/qiniu/php-sdk/examples/rs_change_type.php
index acb896351..4b87c6fd7 100644
--- a/vendor/qiniu/php-sdk/examples/rs_change_type.php
+++ b/vendor/qiniu/php-sdk/examples/rs_change_type.php
@@ -1,18 +1,27 @@
 changeType($bucket, $key, $fileType);
 if ($err) {
diff --git a/vendor/qiniu/php-sdk/examples/rs_copy.php b/vendor/qiniu/php-sdk/examples/rs_copy.php
index 10e7de8e4..2e5937417 100644
--- a/vendor/qiniu/php-sdk/examples/rs_copy.php
+++ b/vendor/qiniu/php-sdk/examples/rs_copy.php
@@ -1,21 +1,30 @@
 copy($srcBucket, $srcKey, $destBucket, $destKey, true);
 if ($err) {
     print_r($err);
diff --git a/vendor/qiniu/php-sdk/examples/rs_delete.php b/vendor/qiniu/php-sdk/examples/rs_delete.php
index 365d3bec1..a41cf22bb 100644
--- a/vendor/qiniu/php-sdk/examples/rs_delete.php
+++ b/vendor/qiniu/php-sdk/examples/rs_delete.php
@@ -1,16 +1,24 @@
 delete($bucket, $key);
 if ($err) {
     print_r($err);
diff --git a/vendor/qiniu/php-sdk/examples/rs_delete_after_days.php b/vendor/qiniu/php-sdk/examples/rs_delete_after_days.php
index ba0b58697..546d7ccb6 100644
--- a/vendor/qiniu/php-sdk/examples/rs_delete_after_days.php
+++ b/vendor/qiniu/php-sdk/examples/rs_delete_after_days.php
@@ -1,19 +1,23 @@
 deleteAfterDays($bucket, $key, $days);
 if ($err) {
     print_r($err);
diff --git a/vendor/qiniu/php-sdk/examples/rs_download_urls.php b/vendor/qiniu/php-sdk/examples/rs_download_urls.php
index 522b9f2ff..e803ddcb7 100644
--- a/vendor/qiniu/php-sdk/examples/rs_download_urls.php
+++ b/vendor/qiniu/php-sdk/examples/rs_download_urls.php
@@ -3,15 +3,17 @@
 
 use Qiniu\Auth;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
-// 构建Auth对象
+// 构建 Auth 对象
 $auth = new Auth($accessKey, $secretKey);
 
-// 私有空间中的外链 http:///
+// 私有空间中的外链 http(s):///,一定要带访问协议,也就是 http:// 或者 https://
 $baseUrl = 'http://if-pri.qiniudn.com/qiniu.png?imageView2/1/h/500';
-// 对链接进行签名
+
+// 对链接进行签名,参考文档:https://developer.qiniu.com/kodo/manual/1656/download-private
 $signedUrl = $auth->privateDownloadUrl($baseUrl);
 
 echo $signedUrl;
diff --git a/vendor/qiniu/php-sdk/examples/rs_fetch.php b/vendor/qiniu/php-sdk/examples/rs_fetch.php
index 6792410b1..5c1a5abbd 100644
--- a/vendor/qiniu/php-sdk/examples/rs_fetch.php
+++ b/vendor/qiniu/php-sdk/examples/rs_fetch.php
@@ -4,6 +4,7 @@
 use Qiniu\Auth;
 use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 $bucket = getenv('QINIU_TEST_BUCKET');
@@ -11,10 +12,16 @@
 $auth = new Auth($accessKey, $secretKey);
 $bucketManager = new BucketManager($auth);
 
+// 第三方资源抓取
+// 参考文档:https://developer.qiniu.com/kodo/api/1263/fetch
+
+// 需要抓取的文件 URL
 $url = 'http://devtools.qiniu.com/qiniu.png';
-$key = time() . '.png';
 
-// 指定抓取的文件保存名称
+//---------------------------------------- demo1 ----------------------------------------
+// 指定抓取的文件保存到七牛云空间中的名称
+
+$key = time() . '.png';
 list($ret, $err) = $bucketManager->fetch($url, $bucket, $key);
 echo "=====> fetch $url to bucket: $bucket  key: $key\n";
 if ($err !== null) {
@@ -23,7 +30,9 @@
     print_r($ret);
 }
 
-// 不指定key时,以文件内容的hash作为文件名
+//---------------------------------------- demo2 ----------------------------------------
+// 不指定 key 时,以文件内容的 hash 作为文件名
+
 $key = null;
 list($ret, $err) = $bucketManager->fetch($url, $bucket, $key);
 echo "=====> fetch $url to bucket: $bucket  key: $(etag)\n";
diff --git a/vendor/qiniu/php-sdk/examples/rs_move.php b/vendor/qiniu/php-sdk/examples/rs_move.php
index 56105857b..bffbfb666 100644
--- a/vendor/qiniu/php-sdk/examples/rs_move.php
+++ b/vendor/qiniu/php-sdk/examples/rs_move.php
@@ -1,8 +1,9 @@
 move($srcBucket, $srcKey, $destBucket, $destKey, true);
 if ($err) {
     print_r($err);
diff --git a/vendor/qiniu/php-sdk/examples/rs_prefetch.php b/vendor/qiniu/php-sdk/examples/rs_prefetch.php
index de947a7e9..6ddc3603f 100644
--- a/vendor/qiniu/php-sdk/examples/rs_prefetch.php
+++ b/vendor/qiniu/php-sdk/examples/rs_prefetch.php
@@ -1,16 +1,22 @@
 prefetch($bucket, $key);
 if ($err) {
     print_r($err);
diff --git a/vendor/qiniu/php-sdk/examples/rs_pub_domain.php b/vendor/qiniu/php-sdk/examples/rs_pub_domain.php
deleted file mode 100644
index 2e81922eb..000000000
--- a/vendor/qiniu/php-sdk/examples/rs_pub_domain.php
+++ /dev/null
@@ -1,19 +0,0 @@
-publishDomain($bucket, $domain);
-if ($err) {
-    print_r($err);
-}
diff --git a/vendor/qiniu/php-sdk/examples/rs_stat.php b/vendor/qiniu/php-sdk/examples/rs_stat.php
index 891e4e027..36e863eff 100644
--- a/vendor/qiniu/php-sdk/examples/rs_stat.php
+++ b/vendor/qiniu/php-sdk/examples/rs_stat.php
@@ -1,19 +1,28 @@
 stat($bucket, $key);
-if ($err) {
-    print_r($err);
+
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
+
+// 资源元信息查询
+// 参考文档:https://developer.qiniu.com/kodo/api/1308/stat
+
+$key = "qiniu.mp4";
+
+list($ret, $err) = $bucketManager->stat($bucket, $key);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($fileInfo);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/rsf_list_bucket.php b/vendor/qiniu/php-sdk/examples/rsf_list_bucket.php
index 5ce9a629c..97a5838a0 100644
--- a/vendor/qiniu/php-sdk/examples/rsf_list_bucket.php
+++ b/vendor/qiniu/php-sdk/examples/rsf_list_bucket.php
@@ -4,14 +4,16 @@
 use Qiniu\Auth;
 use Qiniu\Storage\BucketManager;
 
-// http://developer.qiniu.com/docs/v6/api/reference/rs/list.html#list-description
-
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 $bucket = getenv('QINIU_TEST_BUCKET');
+
 $auth = new Auth($accessKey, $secretKey);
 $bucketManager = new BucketManager($auth);
 
+// 资源列举
+// 参考文档:https://developer.qiniu.com/kodo/api/1284/list
 
 // 要列取文件的公共前缀
 $prefix = '';
@@ -19,12 +21,11 @@
 // 上次列举返回的位置标记,作为本次列举的起点信息。
 $marker = '';
 
-// 本次列举的条目数
+// 本次列举的条目数,范围为 1-1000
 $limit = 200;
 
 $delimiter = '/';
 
-// 列举文件
 do {
     list($ret, $err) = $bucketManager->listFiles($bucket, $prefix, $marker, $limit, $delimiter);
     if ($err !== null) {
diff --git a/vendor/qiniu/php-sdk/examples/rsf_list_files.php b/vendor/qiniu/php-sdk/examples/rsf_list_files.php
index a3981c548..31c455b4e 100644
--- a/vendor/qiniu/php-sdk/examples/rsf_list_files.php
+++ b/vendor/qiniu/php-sdk/examples/rsf_list_files.php
@@ -4,14 +4,16 @@
 use Qiniu\Auth;
 use Qiniu\Storage\BucketManager;
 
-// http://developer.qiniu.com/docs/v6/api/reference/rs/list.html#list-description
-
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 $bucket = getenv('QINIU_TEST_BUCKET');
+
 $auth = new Auth($accessKey, $secretKey);
 $bucketManager = new BucketManager($auth);
 
+// 资源列举
+// https://developer.qiniu.com/kodo/api/1284/list
 
 // 要列取文件的公共前缀
 $prefix = '';
@@ -19,7 +21,7 @@
 // 上次列举返回的位置标记,作为本次列举的起点信息。
 $marker = '';
 
-// 本次列举的条目数
+// 本次列举的条目数,,范围为 1-1000
 $limit = 100;
 
 $delimiter = '/';
@@ -34,5 +36,4 @@
         echo "Marker:" . $ret["marker"] . "\n";
     }
     echo "\nList Iterms====>\n";
-    //var_dump($ret['items']);
 }
diff --git a/vendor/qiniu/php-sdk/examples/rsf_v2list_bucket.php b/vendor/qiniu/php-sdk/examples/rsf_v2list_bucket.php
index 4dcf27096..5f9d763ba 100644
--- a/vendor/qiniu/php-sdk/examples/rsf_v2list_bucket.php
+++ b/vendor/qiniu/php-sdk/examples/rsf_v2list_bucket.php
@@ -4,14 +4,16 @@
 use Qiniu\Auth;
 use Qiniu\Storage\BucketManager;
 
-// http://developer.qiniu.com/docs/v6/api/reference/rs/list.html#list-description
-
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
-$bucket = 'xxxx';
+$bucket = getenv('QINIU_TEST_BUCKET');
+
 $auth = new Auth($accessKey, $secretKey);
 $bucketManager = new BucketManager($auth);
 
+// 资源列举 V2
+// https://developer.qiniu.com/kodo/api/4539/v2-list
 
 // 要列取文件的公共前缀
 $prefix = '';
@@ -19,15 +21,14 @@
 // 上次列举返回的位置标记,作为本次列举的起点信息。
 $marker = '';
 
-// 本次列举的条目数
+// 本次列举的条目数,范围为 1-1000
 $limit = 1000;
 
 $delimiter = '';
 
 list($ret, $err) = $bucketManager->listFilesv2($bucket, $prefix, $marker, $limit, $delimiter, true);
-
-if ($err) {
-    print_r($err);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($ret);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/rtc/README.md b/vendor/qiniu/php-sdk/examples/rtc/README.md
new file mode 100755
index 000000000..c7fff4d8f
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/rtc/README.md
@@ -0,0 +1,34 @@
+# Rtc Streaming Cloud Server-Side Library For PHP
+
+## Features
+
+- RoomToken 签发
+    - [x] 生成 RoomToken: client->appToken() 
+
+- App 管理
+    - [x] 创建应用: client->createApp()
+    - [x] 获取应用配置信息: client->getApp()
+    - [x] 更新应用配置信息: client->updateApp()
+    - [x] 删除应用: client->deleteApp()
+
+- 房间管理
+    - [x] 列举房间下的所有用户: client->listUser()
+    - [x] 指定一个用户踢出房间: client->kickUser()
+    - [x] 停止一个房间的合流转推: client->stopMerge()
+    - [x] 获取当前所有活跃的房间: client->listActiveRooms()
+
+## Demo
+- RoomToken 签发
+    - [生成 RoomToken](https://github.com/qiniu/php-sdk/tree/master/examples/rtc/rtc_create_roomToken.php)
+
+- App 管理
+    - [创建应用](https://github.com/qiniu/php-sdk/tree/master/examples/rtc/rtc_createApp.php)
+    - [获取应用配置信息](https://github.com/qiniu/php-sdk/tree/master/examples/rtc/rtc_getApp.php)
+    - [更新应用配置信息](https://github.com/qiniu/php-sdk/tree/master/examples/rtc/rtc_updateApp.php)
+    - [删除应用](https://github.com/qiniu/php-sdk/tree/master/examples/rtc/rtc_deleteApp.php)
+
+- 房间管理
+    - [列举房间下的所有用户](https://github.com/qiniu/php-sdk/tree/master/examples/rtc/rtc_rooms_listUser.php)
+    - [指定一个用户踢出房间](https://github.com/qiniu/php-sdk/tree/master/examples/rtc/rtc_rooms_kickUser.php)
+    - [停止一个房间的合流转推](https://github.com/qiniu/php-sdk/tree/master/examples/rtc/rtc_rooms_stopMerge.php)
+    - [获取当前所有活跃的房间](https://github.com/qiniu/php-sdk/tree/master/examples/rtc/rtc_rooms_listActiveRooms.php)   
\ No newline at end of file
diff --git a/vendor/qiniu/php-sdk/examples/rtc/rtc_createApp.php b/vendor/qiniu/php-sdk/examples/rtc/rtc_createApp.php
new file mode 100644
index 000000000..039eadd9d
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/rtc/rtc_createApp.php
@@ -0,0 +1,32 @@
+createApp($hub, $title, $maxUsers);
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "\n====> Create Successfully: \n";
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/rtc/rtc_create_roomToken.php b/vendor/qiniu/php-sdk/examples/rtc/rtc_create_roomToken.php
new file mode 100644
index 000000000..6a62aa28b
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/rtc/rtc_create_roomToken.php
@@ -0,0 +1,34 @@
+appToken($appId, $roomName, $userId, $expireAt, $permission);
+echo "\n====> Create RoomToken Successfully: \n";
+var_dump($RoomToken);
diff --git a/vendor/qiniu/php-sdk/examples/rtc/rtc_deleteApp.php b/vendor/qiniu/php-sdk/examples/rtc/rtc_deleteApp.php
new file mode 100644
index 000000000..68bff3367
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/rtc/rtc_deleteApp.php
@@ -0,0 +1,25 @@
+deleteApp($appId);
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "\n====> Delete $appId Successfully \n";
+}
diff --git a/vendor/qiniu/php-sdk/examples/rtc/rtc_getApp.php b/vendor/qiniu/php-sdk/examples/rtc/rtc_getApp.php
new file mode 100644
index 000000000..9f8e3748d
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/rtc/rtc_getApp.php
@@ -0,0 +1,26 @@
+getApp($appId);
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "\n====> $appId Conf: \n";
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_kickUser.php b/vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_kickUser.php
new file mode 100644
index 000000000..019c3f21a
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_kickUser.php
@@ -0,0 +1,31 @@
+kickUser($appId, $roomName, $userId);
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "\n====> Kick User $userId Successfully \n";
+}
diff --git a/vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_listActiveRooms.php b/vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_listActiveRooms.php
new file mode 100644
index 000000000..16e602751
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_listActiveRooms.php
@@ -0,0 +1,35 @@
+listActiveRooms($appId, $prefix, $offset, $limit);
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "\n====> Active Rooms:\n";
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_listUser.php b/vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_listUser.php
new file mode 100644
index 000000000..a8397280e
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_listUser.php
@@ -0,0 +1,29 @@
+listUser($appId, $roomName);
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "\n====> User List: \n";
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_stopMerge.php b/vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_stopMerge.php
new file mode 100644
index 000000000..e140907d4
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/rtc/rtc_rooms_stopMerge.php
@@ -0,0 +1,28 @@
+stopMerge($appId, $roomName);
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "\n====> Stop Merge Successfully \n";
+}
diff --git a/vendor/qiniu/php-sdk/examples/rtc/rtc_updateApp.php b/vendor/qiniu/php-sdk/examples/rtc/rtc_updateApp.php
new file mode 100644
index 000000000..f7710754e
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/rtc/rtc_updateApp.php
@@ -0,0 +1,40 @@
+updateApp($appId, $hub, $title, $maxUsers, false, $mergePublishRtmp);
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "\n====> Update $appId Conf Successfully: \n";
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/saveas.php b/vendor/qiniu/php-sdk/examples/saveas.php
index d896f3bcd..5d51ef4be 100644
--- a/vendor/qiniu/php-sdk/examples/saveas.php
+++ b/vendor/qiniu/php-sdk/examples/saveas.php
@@ -4,23 +4,28 @@
 use Qiniu\Auth;
 use Qiniu\Processing\PersistentFop;
 
-// 后台来获取AK, SK
-$accessKey = 'Access_Key';
-$secretKey = 'Secret_Key';
+// 控制台获取密钥:https://portal.qiniu.com/user/key
+$accessKey = getenv('QINIU_ACCESS_KEY');
+$secretKey = getenv('QINIU_SECRET_KEY');
 
-//生成EncodedEntryURI的值
-$entry = ':';//为生成缩略图的文件名
-//生成的值
+// 处理结果另存为
+// 参考文档:https://developer.qiniu.com/dora/api/1305/processing-results-save-saveas
+
+// 生成EncodedEntryURI的值,为生成缩略图的文件名
+$entry = ':';
+
+// 生成的值
 $encodedEntryURI = \Qiniu\base64_urlSafeEncode($entry);
 
-//使用SecretKey对新的下载URL进行HMAC1-SHA1签名
+// 使用 SecretKey 对新的下载 URL 进行 HMAC1-SHA1 签名
 $newurl = "78re52.com1.z0.glb.clouddn.com/resource/Ship.jpg?imageView2/2/w/200/h/200|saveas/" . $encodedEntryURI;
 
 $sign = hash_hmac("sha1", $newurl, $secretKey, true);
 
-//对签名进行URL安全的Base64编码
+// 对签名进行 URL 安全的 Base64 编码
 $encodedSign = \Qiniu\base64_urlSafeEncode($sign);
-//最终得到的完整下载URL
+
+// 最终得到的完整下载 URL
 $finalURL = "http://" . $newurl . "/sign/" . $accessKey . ":" . $encodedSign;
 
 $callbackBody = file_get_contents("$finalURL");
diff --git a/vendor/qiniu/php-sdk/examples/sms/README.md b/vendor/qiniu/php-sdk/examples/sms/README.md
new file mode 100755
index 000000000..8c80a3894
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/sms/README.md
@@ -0,0 +1,45 @@
+# SMS Server-Side Library For PHP
+
+## Features
+
+- 签名管理
+    - [x] 创建签名: client->createSignature() 
+    - [x] 列出签名: client->checkSignature() 
+    - [x] 查询单个签名: client->checkSingleSignature() 
+    - [x] 编辑签名: client->updateSignature() 
+    - [x] 删除签名: client->deleteSignature() 
+
+- 模板管理
+    - [x] 创建模板: client->createTemplate()
+    - [x] 列出模板: client->queryTemplate()
+    - [x] 查询单个模板: client->querySingleTemplate()
+    - [x] 编辑模板: client->updateTemplate()
+    - [x] 删除模板: client->deleteTemplate()
+
+- 发送短信
+    - [x] 发送短信: client->sendMessage()
+
+- 查询发送记录
+    - [x] 查询发送记录: client->querySendSms()   
+
+## Demo
+
+- 签名管理
+    - [创建签名](https://github.com/qiniu/php-sdk/tree/master/examples/sms/sms_create_signature.php) 
+    - [列出签名](https://github.com/qiniu/php-sdk/tree/master/examples/sms/sms_query_signature.php) 
+    - [查询单个签名](https://github.com/qiniu/php-sdk/tree/master/examples/sms/sms_query_single_signature.php) 
+    - [编辑签名](https://github.com/qiniu/php-sdk/tree/master/examples/sms/sms_edit_signature.php) 
+    - [删除签名](https://github.com/qiniu/php-sdk/tree/master/examples/sms/sms_delete_signature.php) 
+
+- 模板管理
+    - [创建模板](https://github.com/qiniu/php-sdk/tree/master/examples/sms/sms_create_template.php)
+    - [列出模板](https://github.com/qiniu/php-sdk/tree/master/examples/sms/sms_query_template.php)
+    - [查询单个模板](https://github.com/qiniu/php-sdk/tree/master/examples/sms/sms_query_single_template.php)
+    - [编辑模板](https://github.com/qiniu/php-sdk/tree/master/examples/sms/sms_edit_template.php)
+    - [删除模板](https://github.com/qiniu/php-sdk/tree/master/examples/sms/sms_delete_template.php)
+
+- 发送短信
+    - [发送短信](https://github.com/qiniu/php-sdk/tree/master/examples/sms/sms_send_message.php)    
+
+- 查询发送记录
+    - [查询发送记录](https://github.com/qiniu/php-sdk/tree/master/examples/sms/sms_query_send_sms.php)
diff --git a/vendor/qiniu/php-sdk/examples/sms/sms_create_signature.php b/vendor/qiniu/php-sdk/examples/sms/sms_create_signature.php
new file mode 100644
index 000000000..ea1f158a8
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/sms/sms_create_signature.php
@@ -0,0 +1,29 @@
+createSignature($signature, $source, $pics);
+
+echo "\n====> create signature result: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/sms/sms_create_template.php b/vendor/qiniu/php-sdk/examples/sms/sms_create_template.php
new file mode 100644
index 000000000..3cb3874df
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/sms/sms_create_template.php
@@ -0,0 +1,33 @@
+createTemplate($name, $template, $type, $description, $signature_id);
+
+echo "\n====> create signature result: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/sms/sms_delete_signature.php b/vendor/qiniu/php-sdk/examples/sms/sms_delete_signature.php
new file mode 100644
index 000000000..fd873fa37
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/sms/sms_delete_signature.php
@@ -0,0 +1,25 @@
+deleteSignature($signature_id);
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "\n====> Delete Signature $signature_id Successfully\n";
+}
diff --git a/vendor/qiniu/php-sdk/examples/sms/sms_delete_template.php b/vendor/qiniu/php-sdk/examples/sms/sms_delete_template.php
new file mode 100644
index 000000000..45908351c
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/sms/sms_delete_template.php
@@ -0,0 +1,25 @@
+deleteTemplate($template_id);
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "\n====> Delete Template $template_id Successfully\n";
+}
diff --git a/vendor/qiniu/php-sdk/examples/sms/sms_edit_signature.php b/vendor/qiniu/php-sdk/examples/sms/sms_edit_signature.php
new file mode 100644
index 000000000..edf14e0c7
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/sms/sms_edit_signature.php
@@ -0,0 +1,30 @@
+updateSignature($id, $signature, $source, $pics);
+
+echo "\n====> edit signature result: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "\n====> Update Signature Successfully\n";
+}
diff --git a/vendor/qiniu/php-sdk/examples/sms/sms_edit_template.php b/vendor/qiniu/php-sdk/examples/sms/sms_edit_template.php
new file mode 100644
index 000000000..1be550988
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/sms/sms_edit_template.php
@@ -0,0 +1,31 @@
+updateTemplate($template_id, $name, $template, $description, $signature_id);
+
+echo "\n====> edit template result: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "\n====> Update Template Successfully\n";
+}
diff --git a/vendor/qiniu/php-sdk/examples/sms/sms_query_send_sms.php b/vendor/qiniu/php-sdk/examples/sms/sms_query_send_sms.php
new file mode 100644
index 000000000..cdbbe71d9
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/sms/sms_query_send_sms.php
@@ -0,0 +1,50 @@
+querySendSms(
+    $job_id,
+    $message_id,
+    $mobile,
+    $status,
+    $template_id,
+    $type,
+    $start,
+    $end,
+    $page,
+    $page_size
+);
+echo "\n====> query send sms result: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/sms/sms_query_signature.php b/vendor/qiniu/php-sdk/examples/sms/sms_query_signature.php
new file mode 100644
index 000000000..224d09bdc
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/sms/sms_query_signature.php
@@ -0,0 +1,28 @@
+querySignature($audit_status, $page, $page_size);
+echo "\n====> query signature result: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/sms/sms_query_single_signature.php b/vendor/qiniu/php-sdk/examples/sms/sms_query_single_signature.php
new file mode 100644
index 000000000..8afb4d585
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/sms/sms_query_single_signature.php
@@ -0,0 +1,26 @@
+checkSingleSignature($signature_id);
+echo "\n====> query single signature result: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/sms/sms_query_single_template.php b/vendor/qiniu/php-sdk/examples/sms/sms_query_single_template.php
new file mode 100644
index 000000000..8e0b2798a
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/sms/sms_query_single_template.php
@@ -0,0 +1,26 @@
+querySingleTemplate($template_id);
+echo "\n====> query single template result: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/sms/sms_query_template.php b/vendor/qiniu/php-sdk/examples/sms/sms_query_template.php
new file mode 100644
index 000000000..6be260e09
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/sms/sms_query_template.php
@@ -0,0 +1,28 @@
+queryTemplate($audit_status, $page, $page_size);
+echo "\n====> query template result: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/sms/sms_send_message.php b/vendor/qiniu/php-sdk/examples/sms/sms_send_message.php
new file mode 100644
index 000000000..d943e5206
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/sms/sms_send_message.php
@@ -0,0 +1,32 @@
+ 'xxxx');
+
+list($ret, $err) = $client->sendMessage($template_id, $mobiles, $code);
+if ($err !== null) {
+    var_dump($err);
+} else {
+    echo "\n====> Send Message Successfully: \n";
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/update_bucketEvent.php b/vendor/qiniu/php-sdk/examples/update_bucketEvent.php
index 26347ac41..7b0d1d05a 100644
--- a/vendor/qiniu/php-sdk/examples/update_bucketEvent.php
+++ b/vendor/qiniu/php-sdk/examples/update_bucketEvent.php
@@ -2,24 +2,30 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
+
+// 更新 bucket 事件通知规则
+// 参考文档:https://developer.qiniu.com/kodo/manual/6095/event-notification
 
 $bucket = 'xxxx';
 $name = 'demo';
 $prefix = 'test';
 $suffix = 'mp4';
-$event = 'mkfile';
+$event = array("move","copy");
 $callbackURL = 'https://www.qiniu.com';
 
-list($Info, $err) = $bucketManager->updateBucketEvent($bucket, $name, $prefix, $suffix, $event, $callbackURL);
-if ($err) {
-    print_r($err);
+list($ret, $err) = $bucketManager->updateBucketEvent($bucket, $name, $prefix, $suffix, $event, $callbackURL);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/update_bucketLifecycleRule.php b/vendor/qiniu/php-sdk/examples/update_bucketLifecycleRule.php
index 85eb07a6b..73f0f5667 100644
--- a/vendor/qiniu/php-sdk/examples/update_bucketLifecycleRule.php
+++ b/vendor/qiniu/php-sdk/examples/update_bucketLifecycleRule.php
@@ -2,13 +2,19 @@
 require_once __DIR__ . '/../autoload.php';
 
 use Qiniu\Auth;
+use Qiniu\Config;
+use Qiniu\Storage\BucketManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 
 $auth = new Auth($accessKey, $secretKey);
-$config = new \Qiniu\Config();
-$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
+$config = new Config();
+$bucketManager = new BucketManager($auth, $config);
+
+// 存储空间 - 更新生命周期规则
+// 参考文档:https://developer.qiniu.com/kodo/manual/3699/life-cycle-management
 
 $bucket = 'xxxx';
 $name = 'demo';
@@ -16,15 +22,15 @@
 $delete_after_days = 90;
 $to_line_after_days =80;
 
-list($Info, $err) = $bucketManager->updateBucketLifecycleRule(
+list($ret, $err) = $bucketManager->updateBucketLifecycleRule(
     $bucket,
     $name,
     $prefix,
     $delete_after_days,
     $to_line_after_days
 );
-if ($err) {
-    print_r($err);
+if ($err != null) {
+    var_dump($err);
 } else {
-    print_r($Info);
+    var_dump($ret);
 }
diff --git a/vendor/qiniu/php-sdk/examples/upload_and_callback.php b/vendor/qiniu/php-sdk/examples/upload_and_callback.php
index 1a7070557..a0c793a1d 100644
--- a/vendor/qiniu/php-sdk/examples/upload_and_callback.php
+++ b/vendor/qiniu/php-sdk/examples/upload_and_callback.php
@@ -3,27 +3,24 @@
 use Qiniu\Auth;
 use Qiniu\Storage\UploadManager;
 
-// use Qiniu\Config;
-// use Qiniu\Zone;
-
-// 指定zone上传
-// $zone = Zone::qvmZonez0(); //华东QVM内网上传指定host
-// $config = new Config($zone);
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 $bucket = getenv('QINIU_TEST_BUCKET');
 $auth = new Auth($accessKey, $secretKey);
-// 上传文件到七牛后, 七牛将文件名和文件大小回调给业务服务器.
-// 可参考文档: http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
+
+// 上传完成后通知到你的业务服务器(需要可以公网访问,并能够相应 200 OK)
+// 上传策略参数:https://developer.qiniu.com/kodo/manual/1206/put-policy
+
 $policy = array(
     'callbackUrl' => 'http://your.domain.com/upload_verify_callback.php',
     'callbackBody' => 'filename=$(fname)&filesize=$(fsize)'
 );
 $uptoken = $auth->uploadToken($bucket, null, 3600, $policy);
-//上传文件的本地路径
+
+// 上传文件的本地路径
 $filePath = './php-logo.png';
-//指定 config
-// $uploadMgr = new UploadManager($config);
+
 $uploadMgr = new UploadManager();
 list($ret, $err) = $uploadMgr->putFile($uptoken, null, $filePath);
 echo "\n====> putFile result: \n";
diff --git a/vendor/qiniu/php-sdk/examples/upload_and_pfop.php b/vendor/qiniu/php-sdk/examples/upload_and_pfop.php
index 898c09c63..32c1eb513 100644
--- a/vendor/qiniu/php-sdk/examples/upload_and_pfop.php
+++ b/vendor/qiniu/php-sdk/examples/upload_and_pfop.php
@@ -4,24 +4,35 @@
 use Qiniu\Auth;
 use Qiniu\Storage\UploadManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 $bucket = getenv('QINIU_TEST_BUCKET');
 $auth = new Auth($accessKey, $secretKey);
 
+// 使用上传策略实现上传文件后,自动对该文件进行转码处理,并持久化生成一个新的文件存储到空间中
 
-// 在七牛保存的文件名
+// 上传到七牛后保存的文件名
 $key = 'php-logo.png';
+
+// 要上传文件的本地路径
+$filePath = './php-logo.png';
+
 $uploadMgr = new UploadManager();
 
-$pfop = "imageMogr2/rotate/90|saveas/" . \Qiniu\base64_urlSafeEncode($bucket . ":php-logo-rotate.png");
+// 视频处理完毕后保存到空间中的名称
+$saveasKey = 'php-logo-rotate.png';
+
+// 处理参数
+$pfop = "imageMogr2/rotate/90|saveas/" . \Qiniu\base64_urlSafeEncode("$bucket:$saveasKey");
 
-//转码完成后通知到你的业务服务器。(公网可以访问,并相应200 OK)
+// 转码完成后通知到你的业务服务器(需要可以公网访问,并能够相应 200 OK)
 $notifyUrl = 'http://notify.fake.com';
 
-//独立的转码队列:https://portal.qiniu.com/mps/pipeline
+// 用户默认没有私有队列,需要在这里创建然后填写 https://portal.qiniu.com/dora/media-gate/pipeline
 $pipeline = 'sdktest';
 
+// 上传策略参数:https://developer.qiniu.com/kodo/manual/1206/put-policy
 $policy = array(
     'persistentOps' => $pfop,
     'persistentNotifyUrl' => $notifyUrl,
@@ -29,7 +40,7 @@
 );
 $token = $auth->uploadToken($bucket, null, 3600, $policy);
 
-list($ret, $err) = $uploadMgr->putFile($token, null, $key);
+list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
 echo "\n====> putFile result: \n";
 if ($err !== null) {
     var_dump($err);
diff --git a/vendor/qiniu/php-sdk/examples/upload_mgr_init.php b/vendor/qiniu/php-sdk/examples/upload_mgr_init.php
index 3459ef1d7..1164c905d 100644
--- a/vendor/qiniu/php-sdk/examples/upload_mgr_init.php
+++ b/vendor/qiniu/php-sdk/examples/upload_mgr_init.php
@@ -4,14 +4,15 @@
 use Qiniu\Auth;
 use Qiniu\Storage\UploadManager;
 
-$accessKey = 'Access_Key';
-$secretKey = 'Secret_Key';
+// 控制台获取密钥:https://portal.qiniu.com/user/key
+$accessKey = getenv('QINIU_ACCESS_KEY');
+$secretKey = getenv('QINIU_SECRET_KEY');
 $auth = new Auth($accessKey, $secretKey);
 
-// 空间名  http://developer.qiniu.com/docs/v6/api/overview/concepts.html#bucket
+// 存储空间名称
 $bucket = 'Bucket_Name';
 
-// 生成上传Token
+// 生成上传 Token
 $token = $auth->uploadToken($bucket);
 
 // 构建 UploadManager 对象
diff --git a/vendor/qiniu/php-sdk/examples/upload_multi_demos.php b/vendor/qiniu/php-sdk/examples/upload_multi_demos.php
index 3bbcd6030..0724d38df 100644
--- a/vendor/qiniu/php-sdk/examples/upload_multi_demos.php
+++ b/vendor/qiniu/php-sdk/examples/upload_multi_demos.php
@@ -4,17 +4,21 @@
 use Qiniu\Auth;
 use Qiniu\Storage\UploadManager;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 $bucket = getenv('QINIU_TEST_BUCKET');
+
+// 用户默认没有私有队列,需要在这里创建然后填写 https://portal.qiniu.com/dora/media-gate/pipeline
 $pipeline = 'sdktest';
 
 $auth = new Auth($accessKey, $secretKey);
 $token = $auth->uploadToken($bucket);
 $uploadMgr = new UploadManager();
 
-//----------------------------------------upload demo1 ----------------------------------------
+//---------------------------------------- upload demo1 ----------------------------------------
 // 上传字符串到七牛
+
 list($ret, $err) = $uploadMgr->put($token, null, 'content string');
 echo "\n====> put result: \n";
 if ($err !== null) {
@@ -24,8 +28,9 @@
 }
 
 
-//----------------------------------------upload demo2 ----------------------------------------
+//---------------------------------------- upload demo2 ----------------------------------------
 // 上传文件到七牛
+
 $filePath = './php-logo.png';
 $key = 'php-logo.png';
 list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
@@ -37,9 +42,10 @@
 }
 
 
-//----------------------------------------upload demo3 ----------------------------------------
+//---------------------------------------- upload demo3 ----------------------------------------
 // 上传文件到七牛后, 七牛将文件名和文件大小回调给业务服务器.
-// 可参考文档: http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
+// 可参考文档: https://developer.qiniu.com/kodo/manual/1206/put-policy
+
 $policy = array(
     'callbackUrl' => 'http://172.30.251.210/upload_verify_callback.php',
     'callbackBody' => 'filename=$(fname)&filesize=$(fsize)'
@@ -58,17 +64,15 @@
 }
 
 
-//----------------------------------------upload demo4 ----------------------------------------
-//上传视频,上传完成后进行m3u8的转码, 并给视频打水印
+//---------------------------------------- upload demo4 ----------------------------------------
+// 上传视频,上传完成后进行 m3u8 的转码, 并给视频打水印
+
 $wmImg = Qiniu\base64_urlSafeEncode('http://devtools.qiniudn.com/qiniu.png');
 $pfop = "avthumb/m3u8/wmImage/$wmImg";
 
-//转码完成后回调到业务服务器。(公网可以访问,并相应200 OK)
+// 转码完成后回调到业务服务器。(公网可以访问,并相应 200 OK)
 $notifyUrl = 'http://notify.fake.com';
 
-//独立的转码队列:https://portal.qiniu.com/mps/pipeline
-
-
 $policy = array(
     'persistentOps' => $pfop,
     'persistentNotifyUrl' => $notifyUrl,
diff --git a/vendor/qiniu/php-sdk/examples/upload_simple_file.php b/vendor/qiniu/php-sdk/examples/upload_simple_file.php
index 9d003f0fb..f495a0275 100644
--- a/vendor/qiniu/php-sdk/examples/upload_simple_file.php
+++ b/vendor/qiniu/php-sdk/examples/upload_simple_file.php
@@ -7,7 +7,7 @@
 // 引入上传类
 use Qiniu\Storage\UploadManager;
 
-// 需要填写你的 Access Key 和 Secret Key
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 $bucket = getenv('QINIU_TEST_BUCKET');
@@ -21,13 +21,13 @@
 // 要上传文件的本地路径
 $filePath = './php-logo.png';
 
-// 上传到七牛后保存的文件名
+// 上传到七牛存储后保存的文件名
 $key = 'my-php-logo.png';
 
 // 初始化 UploadManager 对象并进行文件的上传。
 $uploadMgr = new UploadManager();
 
-// 调用 UploadManager 的 putFile 方法进行文件的上传。
+// 调用 UploadManager 的 putFile 方法进行文件的上传,该方法会判断文件大小,进而决定使用表单上传还是分片上传,无需手动配置。
 list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
 echo "\n====> putFile result: \n";
 if ($err !== null) {
diff --git a/vendor/qiniu/php-sdk/examples/upload_tokens.php b/vendor/qiniu/php-sdk/examples/upload_tokens.php
index 90f24238b..d2cf02c13 100644
--- a/vendor/qiniu/php-sdk/examples/upload_tokens.php
+++ b/vendor/qiniu/php-sdk/examples/upload_tokens.php
@@ -1,34 +1,43 @@
 uploadToken($bucket, null, $expires, $policy, true);
 print($upToken . "\n");
 
+//---------------------------------------- demo2 ----------------------------------------
 // 自定义凭证有效期(示例2小时)
+
 $expires = 7200;
 $upToken = $auth->uploadToken($bucket, null, $expires, $policy, true);
 print($upToken . "\n");
 
+//---------------------------------------- demo3 ----------------------------------------
 // 覆盖上传凭证
+
 $expires = 3600;
 $keyToOverwrite = 'qiniu.mp4';
 $upToken = $auth->uploadToken($bucket, $keyToOverwrite, $expires, $policy, true);
 print($upToken . "\n");
 
-//自定义上传回复(非callback模式)凭证
+//---------------------------------------- demo4 ----------------------------------------
+// 自定义上传回复(非callback模式)凭证
+
 $returnBody = '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}';
 $policy = array(
     'returnBody' => $returnBody
@@ -36,7 +45,9 @@
 $upToken = $auth->uploadToken($bucket, null, $expires, $policy, true);
 print($upToken . "\n");
 
-//带回调业务服务器的凭证(application/json)
+//---------------------------------------- demo5 ----------------------------------------
+// 带回调业务服务器的凭证(application/json)
+
 $policy = array(
     'callbackUrl' => 'http://api.example.com/qiniu/upload/callback',
     'callbackBody' => '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}',
@@ -45,8 +56,9 @@
 $upToken = $auth->uploadToken($bucket, null, $expires, $policy, true);
 print($upToken . "\n");
 
+//---------------------------------------- demo6 ----------------------------------------
+// 带回调业务服务器的凭证(application/x-www-form-urlencoded)
 
-//带回调业务服务器的凭证(application/x-www-form-urlencoded)
 $policy = array(
     'callbackUrl' => 'http://api.example.com/qiniu/upload/callback',
     'callbackBody' => 'key=$(key)&hash=$(etag)&bucket=$(bucket)&fsize=$(fsize)&name=$(x:name)'
@@ -54,7 +66,9 @@
 $upToken = $auth->uploadToken($bucket, null, $expires, $policy, true);
 print($upToken . "\n");
 
-//带数据处理的凭证
+//---------------------------------------- demo7 ----------------------------------------
+// 带数据处理的凭证
+
 $saveMp4Entry = \Qiniu\base64_urlSafeEncode($bucket . ":avthumb_test_target.mp4");
 $saveJpgEntry = \Qiniu\base64_urlSafeEncode($bucket . ":vframe_test_target.jpg");
 $avthumbMp4Fop = "avthumb/mp4|saveas/" . $saveMp4Entry;
diff --git a/vendor/qiniu/php-sdk/examples/upload_verify_callback.php b/vendor/qiniu/php-sdk/examples/upload_verify_callback.php
index ffbbc8063..dcb64c957 100644
--- a/vendor/qiniu/php-sdk/examples/upload_verify_callback.php
+++ b/vendor/qiniu/php-sdk/examples/upload_verify_callback.php
@@ -3,24 +3,26 @@
 
 use Qiniu\Auth;
 
+// 控制台获取密钥:https://portal.qiniu.com/user/key
 $accessKey = getenv('QINIU_ACCESS_KEY');
 $secretKey = getenv('QINIU_SECRET_KEY');
 $bucket = getenv('QINIU_TEST_BUCKET');
 
 $auth = new Auth($accessKey, $secretKey);
 
-//获取回调的body信息
+// 获取回调的 body 信息
 $callbackBody = file_get_contents('php://input');
 
-//回调的contentType
+// 回调的 contentType
 $contentType = 'application/x-www-form-urlencoded';
 
-//回调的签名信息,可以验证该回调是否来自七牛
+// 回调的签名信息,可以验证该回调是否来自七牛
 $authorization = $_SERVER['HTTP_AUTHORIZATION'];
 
-//七牛回调的url,具体可以参考:http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
+// 七牛回调的 url,具体可以参考:https://developer.qiniu.com/kodo/manual/1206/put-policy
 $url = 'http://172.30.251.210/upload_verify_callback.php';
 
+//参考文档:https://developer.qiniu.com/kodo/manual/1653/callback
 $isQiniuCallback = $auth->verifyCallback($contentType, $authorization, $url, $callbackBody);
 
 if ($isQiniuCallback) {
diff --git a/vendor/qiniu/php-sdk/examples/upload_with_qvmzone.php b/vendor/qiniu/php-sdk/examples/upload_with_qvmzone.php
new file mode 100644
index 000000000..ce2b21fde
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/upload_with_qvmzone.php
@@ -0,0 +1,40 @@
+uploadToken($bucket);
+
+// 上传文件的本地路径
+$filePath = './php-logo.png';
+
+// 七牛云主机QVM和七牛对象存储KODO内网上传,目前支持华东1区域(杭州)和华北2区域(北京)的云主机可以访问同区域的对象存储服务
+// 参考文档:https://developer.qiniu.com/qvm/manual/4269/qvm-kodo
+
+$zone = Zone::qvmZonez0(); // 华东:z0,华北:z1
+$config = new Config($zone);
+$config->useHTTPS = true;
+
+// 指定 config
+$uploadMgr = new UploadManager($config);
+
+list($ret, $err) = $uploadMgr->putFile($uptoken, $key, $filePath);
+echo "\n====> putFile result: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/examples/upload_with_zone.php b/vendor/qiniu/php-sdk/examples/upload_with_zone.php
new file mode 100644
index 000000000..619266609
--- /dev/null
+++ b/vendor/qiniu/php-sdk/examples/upload_with_zone.php
@@ -0,0 +1,39 @@
+uploadToken($bucket);
+
+// 上传文件的本地路径
+$filePath = './php-logo.png';
+
+// 指定 zone 上传
+// 参考文档:https://developer.qiniu.com/kodo/manual/1671/region-endpoint
+$zone = Zone::zonez0(); // 华东:z0,华北:z1,华南:z2,北美:na0,东南亚:as0
+$config = new Config($zone);
+$config->useHTTPS = true;
+
+// 指定 config
+$uploadMgr = new UploadManager($config);
+
+list($ret, $err) = $uploadMgr->putFile($uptoken, $key, $filePath);
+echo "\n====> putFile result: \n";
+if ($err !== null) {
+    var_dump($err);
+} else {
+    var_dump($ret);
+}
diff --git a/vendor/qiniu/php-sdk/src/Qiniu/Auth.php b/vendor/qiniu/php-sdk/src/Qiniu/Auth.php
index b5e4a6bcf..8452ac055 100644
--- a/vendor/qiniu/php-sdk/src/Qiniu/Auth.php
+++ b/vendor/qiniu/php-sdk/src/Qiniu/Auth.php
@@ -103,6 +103,7 @@ public function uploadToken($bucket, $key = null, $expires = 3600, $policy = nul
 
         'endUser',
         'saveKey',
+        'forceSaveKey',
         'insertOnly',
 
         'detectMime',
diff --git a/vendor/qiniu/php-sdk/src/Qiniu/Cdn/CdnManager.php b/vendor/qiniu/php-sdk/src/Qiniu/Cdn/CdnManager.php
index 9b462f31a..a6efcedb3 100644
--- a/vendor/qiniu/php-sdk/src/Qiniu/Cdn/CdnManager.php
+++ b/vendor/qiniu/php-sdk/src/Qiniu/Cdn/CdnManager.php
@@ -63,6 +63,45 @@ public function refreshUrlsAndDirs(array $urls, array  $dirs)
         return $this->post($url, $body);
     }
 
+    /**
+     * 查询 CDN 刷新记录
+     *
+     * @param string $requestId 指定要查询记录所在的刷新请求id
+     * @param string $isDir 指定是否查询目录,取值为 yes/no,默认不填则为两种类型记录都查询
+     * @param array $urls 要查询的url列表,每个url可以是文件url,也可以是目录url
+     * @param string $state 指定要查询记录的状态,取值processing/success/failure
+     * @param int $pageNo 要求返回的页号,默认为0
+     * @param int $pageSize 要求返回的页长度,默认为100
+     * @param string $startTime 指定查询的开始日期,格式2006-01-01
+     * @param string $endTime 指定查询的结束日期,格式2006-01-01
+     * @return array
+     * @link https://developer.qiniu.com/fusion/api/1229/cache-refresh#4
+     */
+    public function getCdnRefreshList(
+        $requestId = null,
+        $isDir = null,
+        $urls = array(),
+        $state = null,
+        $pageNo = 0,
+        $pageSize = 100,
+        $startTime = null,
+        $endTime = null
+    ) {
+        $req = array();
+        \Qiniu\setWithoutEmpty($req, 'requestId', $requestId);
+        \Qiniu\setWithoutEmpty($req, 'isDir', $isDir);
+        \Qiniu\setWithoutEmpty($req, 'urls', $urls);
+        \Qiniu\setWithoutEmpty($req, 'state', $state);
+        \Qiniu\setWithoutEmpty($req, 'pageNo', $pageNo);
+        \Qiniu\setWithoutEmpty($req, 'pageSize', $pageSize);
+        \Qiniu\setWithoutEmpty($req, 'startTime', $startTime);
+        \Qiniu\setWithoutEmpty($req, 'endTime', $endTime);
+
+        $body = json_encode($req);
+        $url = $this->server . '/v2/tune/refresh/list';
+        return $this->post($url, $body);
+    }
+
     /**
      * @param array $urls 待预取的文件链接数组
      *
@@ -81,6 +120,42 @@ public function prefetchUrls(array $urls)
         return $this->post($url, $body);
     }
 
+    /**
+     * 查询 CDN 预取记录
+     *
+     * @param string $requestId 指定要查询记录所在的刷新请求id
+     * @param array $urls 要查询的url列表,每个url可以是文件url,也可以是目录url
+     * @param string $state 指定要查询记录的状态,取值processing/success/failure
+     * @param int $pageNo 要求返回的页号,默认为0
+     * @param int $pageSize 要求返回的页长度,默认为100
+     * @param string $startTime 指定查询的开始日期,格式2006-01-01
+     * @param string $endTime 指定查询的结束日期,格式2006-01-01
+     * @return array
+     * @link https://developer.qiniu.com/fusion/api/1227/file-prefetching#4
+     */
+    public function getCdnPrefetchList(
+        $requestId = null,
+        $urls = array(),
+        $state = null,
+        $pageNo = 0,
+        $pageSize = 100,
+        $startTime = null,
+        $endTime = null
+    ) {
+        $req = array();
+        \Qiniu\setWithoutEmpty($req, 'requestId', $requestId);
+        \Qiniu\setWithoutEmpty($req, 'urls', $urls);
+        \Qiniu\setWithoutEmpty($req, 'state', $state);
+        \Qiniu\setWithoutEmpty($req, 'pageNo', $pageNo);
+        \Qiniu\setWithoutEmpty($req, 'pageSize', $pageSize);
+        \Qiniu\setWithoutEmpty($req, 'startTime', $startTime);
+        \Qiniu\setWithoutEmpty($req, 'endTime', $endTime);
+
+        $body = json_encode($req);
+        $url = $this->server . '/v2/tune/prefetch/list';
+        return $this->post($url, $body);
+    }
+
     /**
      * @param array $domains 待获取带宽数据的域名数组
      * @param string $startDate 开始的日期,格式类似 2017-01-01
diff --git a/vendor/qiniu/php-sdk/src/Qiniu/Config.php b/vendor/qiniu/php-sdk/src/Qiniu/Config.php
index c80cd309f..659443eff 100644
--- a/vendor/qiniu/php-sdk/src/Qiniu/Config.php
+++ b/vendor/qiniu/php-sdk/src/Qiniu/Config.php
@@ -3,7 +3,7 @@
 
 final class Config
 {
-    const SDK_VER = '7.2.10';
+    const SDK_VER = '7.3.0';
 
     const BLOCK_SIZE = 4194304; //4*1024*1024 分块上传块大小,该参数为接口规格,不能修改
 
@@ -12,7 +12,7 @@ final class Config
     const RS_HOST = 'rs.qiniu.com';      //RS Host
     const UC_HOST = 'uc.qbox.me';              //UC Host
     const RTCAPI_HOST = 'http://rtc.qiniuapi.com';
-    const ARGUS_HOST = 'argus.atlab.ai';
+    const ARGUS_HOST = 'ai.qiniuapi.com';
     const CASTER_HOST = 'pili-caster.qiniuapi.com';
     const SMS_HOST="https://sms.qiniuapi.com";
     const RTCAPI_VERSION = 'v3';
diff --git a/vendor/qiniu/php-sdk/src/Qiniu/Http/Response.php b/vendor/qiniu/php-sdk/src/Qiniu/Http/Response.php
index f22ab371e..4f54663fe 100644
--- a/vendor/qiniu/php-sdk/src/Qiniu/Http/Response.php
+++ b/vendor/qiniu/php-sdk/src/Qiniu/Http/Response.php
@@ -170,7 +170,7 @@ public function needRetry()
 
     private static function isJson($headers)
     {
-        return array_key_exists('Content-Type', $headers) &&
+        return array_key_exists('content-type', $headers) || array_key_exists('Content-Type', $headers) &&
         strpos($headers['Content-Type'], 'application/json') === 0;
     }
 }
diff --git a/vendor/qiniu/php-sdk/src/Qiniu/Processing/ImageUrlBuilder.php b/vendor/qiniu/php-sdk/src/Qiniu/Processing/ImageUrlBuilder.php
index 1ac5bf717..f5575ed91 100644
--- a/vendor/qiniu/php-sdk/src/Qiniu/Processing/ImageUrlBuilder.php
+++ b/vendor/qiniu/php-sdk/src/Qiniu/Processing/ImageUrlBuilder.php
@@ -1,4 +1,5 @@
 
@@ -105,15 +115,15 @@ public function thumbnail(
     /**
      * 图片水印
      *
-     * @param  string $url 图片链接
-     * @param  string $image 水印图片链接
-     * @param  numeric $dissolve 透明度
-     * @param  string $gravity 水印位置
-     * @param  numeric $dx 横轴边距
-     * @param  numeric $dy 纵轴边距
-     * @param  numeric $watermarkScale 自适应原图的短边比例
-     * @link   http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html
+     * @param string $url 图片链接
+     * @param string $image 水印图片链接
+     * @param int $dissolve 透明度
+     * @param string $gravity 水印位置
+     * @param int $dx 横轴边距
+     * @param int $dy 纵轴边距
+     * @param int $watermarkScale 自适应原图的短边比例
      * @return string
+     * @link   http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html
      * @author Sherlock Ren 
      */
     public function waterImg(
@@ -174,17 +184,17 @@ public function waterImg(
     /**
      * 文字水印
      *
-     * @param  string $url 图片链接
-     * @param  string $text 文字
-     * @param  string $font 文字字体
-     * @param  string $fontSize 文字字号
-     * @param  string $fontColor 文字颜色
-     * @param  numeric $dissolve 透明度
-     * @param  string $gravity 水印位置
-     * @param  numeric $dx 横轴边距
-     * @param  numeric $dy 纵轴边距
-     * @link   http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html#text-watermark
+     * @param string $url 图片链接
+     * @param string $text 文字
+     * @param string $font 文字字体
+     * @param string $fontSize 文字字号
+     * @param string $fontColor 文字颜色
+     * @param int $dissolve 透明度
+     * @param string $gravity 水印位置
+     * @param int $dx 横轴边距
+     * @param int $dy 纵轴边距
      * @return string
+     * @link   http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html#text-watermark
      * @author Sherlock Ren 
      */
     public function waterText(
@@ -252,7 +262,7 @@ public function waterText(
     /**
      * 效验url合法性
      *
-     * @param  string $url url链接
+     * @param string $url url链接
      * @return string
      * @author Sherlock Ren 
      */
@@ -261,15 +271,15 @@ protected function isUrl($url)
         $urlArr = parse_url($url);
 
         return $urlArr['scheme']
-        && in_array($urlArr['scheme'], array('http', 'https'))
-        && $urlArr['host']
-        && $urlArr['path'];
+            && in_array($urlArr['scheme'], array('http', 'https'))
+            && $urlArr['host']
+            && $urlArr['path'];
     }
 
     /**
      * 检测是否有query
      *
-     * @param  string $url url链接
+     * @param string $url url链接
      * @return string
      * @author Sherlock Ren 
      */
diff --git a/vendor/qiniu/php-sdk/src/Qiniu/Processing/Operation.php b/vendor/qiniu/php-sdk/src/Qiniu/Processing/Operation.php
index 919136fc5..7cdd352b6 100644
--- a/vendor/qiniu/php-sdk/src/Qiniu/Processing/Operation.php
+++ b/vendor/qiniu/php-sdk/src/Qiniu/Processing/Operation.php
@@ -23,8 +23,8 @@ public function __construct($domain, $auth = null, $token_expire = 3600)
     /**
      * 对资源文件进行处理
      *
-     * @param $key   待处理的资源文件名
-     * @param $fops   string|array  fop操作,多次fop操作以array的形式传入。
+     * @param string $key 待处理的资源文件名
+     * @param string $fops string|array  fop操作,多次fop操作以array的形式传入。
      *                eg. imageView2/1/w/200/h/200, imageMogr2/thumbnail/!75px
      *
      * @return array 文件处理后的结果及错误。
diff --git a/vendor/qiniu/php-sdk/src/Qiniu/Processing/PersistentFop.php b/vendor/qiniu/php-sdk/src/Qiniu/Processing/PersistentFop.php
index 24e7b734a..ac95d251e 100644
--- a/vendor/qiniu/php-sdk/src/Qiniu/Processing/PersistentFop.php
+++ b/vendor/qiniu/php-sdk/src/Qiniu/Processing/PersistentFop.php
@@ -1,10 +1,10 @@
 baseURL = sprintf("%s/%s/apps", Config::RTCAPI_HOST, Config::RTCAPI_VERSION);
     }
 
-    /*
+    /**
      * 创建应用
-     * hub: 直播空间名
-     * title: app 的名称  注意,Title 不是唯一标识,重复 create 动作将生成多个 app
-     * maxUsers:人数限制
-     * NoAutoKickUser: bool 类型,可选,禁止自动踢人(抢流)。默认为 false ,
-       即同一个身份的 client (app/room/user) ,新的连麦请求可以成功,旧连接被关闭。
+     *
+     * @param string $hub 绑定的直播 hub
+     * @param string $title app 的名称  注意,Title 不是唯一标识,重复 create 动作将生成多个 app
+     * @param int $maxUsers 连麦房间支持的最大在线人数
+     * @param bool $noAutoKickUser 禁止自动踢人(抢流),默认为 false
+     * @return array
+     * @link  https://doc.qnsdk.com/rtn/docs/server_overview#2_1
      */
     public function createApp($hub, $title, $maxUsers = null, $noAutoKickUser = null)
     {
+        $params = array();
         $params['hub'] = $hub;
         $params['title'] = $title;
         if (!empty($maxUsers)) {
@@ -37,29 +41,25 @@ public function createApp($hub, $title, $maxUsers = null, $noAutoKickUser = null
             $params['noAutoKickUser'] = $noAutoKickUser;
         }
         $body = json_encode($params);
-        $ret = $this->post($this->baseURL, $body);
-        return $ret;
+        return $this->post($this->baseURL, $body);
     }
 
-    /*
-     * 更新应用
-     * appId: app 的唯一标识,创建的时候由系统生成。
-     * Title: app 的名称, 可选。
-     * Hub: 绑定的直播 hub,可选,用于合流后 rtmp 推流。
-     * MaxUsers: int 类型,可选,连麦房间支持的最大在线人数。
-     * NoAutoKickUser: bool 类型,可选,禁止自动踢人。
-     * MergePublishRtmp: 连麦合流转推 RTMP 的配置,可选择。其详细配置包括如下
-            Enable: 布尔类型,用于开启和关闭所有房间的合流功能。
-            AudioOnly: 布尔类型,可选,指定是否只合成音频。
-            Height, Width: int64,可选,指定合流输出的高和宽,默认为 640 x 480。
-            OutputFps: int64,可选,指定合流输出的帧率,默认为 25 fps 。
-            OutputKbps: int64,可选,指定合流输出的码率,默认为 1000 。
-            URL: 合流后转推旁路直播的地址,可选,支持魔法变量配置按照连麦房间号生成不同的推流地址。如果是转推到七牛直播云,不建议使用该配置。
-            StreamTitle: 转推七牛直播云的流名,可选,支持魔法变量配置按照连麦房间号生成不同的流名。例如,配置 Hub 为 qn-zhibo ,配置 StreamTitle 为 $(roomName) ,则房间 meeting-001 的合流将会被转推到 rtmp://pili-publish.qn-zhibo.***.com/qn-zhibo/meeting-001地址。详细配置细则,请咨询七牛技术支持。
+    /**
+     * 更新一个应用的配置信息
+     *
+     * @param string $appId app 的唯一标识,创建的时候由系统生成
+     * @param string $hub app 的名称,可选
+     * @param string $title 绑定的直播 hub,可选,用于合流后 rtmp 推流
+     * @param int $maxUsers 连麦房间支持的最大在线人数,可选
+     * @param bool $noAutoKickUser 禁止自动踢人,可选
+     * @param null $mergePublishRtmp 连麦合流转推 RTMP 的配置,可选择。其详细配置可以参考文档
+     * @return array
+     * @link  https://doc.qnsdk.com/rtn/docs/server_overview#2_1
      */
-    public function updateApp($appId, $hub, $title, $maxUsers = null, $mergePublishRtmp = null, $noAutoKickUser = null)
+    public function updateApp($appId, $hub, $title, $maxUsers = null, $noAutoKickUser = null, $mergePublishRtmp = null)
     {
         $url = $this->baseURL . '/' . $appId;
+        $params = array();
         $params['hub'] = $hub;
         $params['title'] = $title;
         if (!empty($maxUsers)) {
@@ -72,67 +72,91 @@ public function updateApp($appId, $hub, $title, $maxUsers = null, $mergePublishR
             $params['mergePublishRtmp'] = $mergePublishRtmp;
         }
         $body = json_encode($params);
-        $ret = $this->post($url, $body);
-        return $ret;
+        return $this->post($url, $body);
     }
 
-    /*
+    /**
      * 获取应用信息
-     * appId: app 的唯一标识,创建的时候由系统生成。
+     *
+     * @param string $appId
+     * @return array
+     * @link  https://doc.qnsdk.com/rtn/docs/server_overview#2_1
      */
     public function getApp($appId)
     {
         $url = $this->baseURL . '/' . $appId;
-        $ret  = $this->get($url);
-        return $ret;
+        return $this->get($url);
     }
 
-    /*
+    /**
      * 删除应用
-     * appId: app 的唯一标识,创建的时候由系统生成
+     *
+     * @param string $appId app 的唯一标识,创建的时候由系统生成
+     * @return array
+     * @link  https://doc.qnsdk.com/rtn/docs/server_overview#2_1
      */
     public function deleteApp($appId)
     {
         $url = $this->baseURL . '/' . $appId;
-        list(, $err)  = $this->delete($url);
-        return $err;
+        return $this->delete($url);
     }
 
-    /*
+    /**
      * 获取房间内用户列表
-     * appId: app 的唯一标识,创建的时候由系统生成。
-     * roomName: 操作所查询的连麦房间。
+     *
+     * @param string $appId app 的唯一标识,创建的时候由系统生成
+     * @param string $roomName 操作所查询的连麦房间
+     * @return array
+     * @link https://doc.qnsdk.com/rtn/docs/server_overview#2_2
      */
     public function listUser($appId, $roomName)
     {
         $url = sprintf("%s/%s/rooms/%s/users", $this->baseURL, $appId, $roomName);
-        $ret  = $this->get($url);
-        return $ret;
+        return $this->get($url);
     }
 
-   /*
-    * 踢出用户
-    * appId: app 的唯一标识,创建的时候由系统生成。
-    * roomName: 连麦房间
-    * userId: 请求加入房间的用户ID
-    */
+    /**
+     * 指定一个用户踢出房间
+     *
+     * @param string $appId app 的唯一标识,创建的时候由系统生成
+     * @param string $roomName 连麦房间
+     * @param string $userId 操作所剔除的用户
+     * @return mixed
+     * @link https://doc.qnsdk.com/rtn/docs/server_overview#2_2
+     */
     public function kickUser($appId, $roomName, $userId)
     {
         $url = sprintf("%s/%s/rooms/%s/users/%s", $this->baseURL, $appId, $roomName, $userId);
-        list(, $err)  = $this->delete($url);
-        return $err;
+        return $this->delete($url);
+    }
+
+    /**
+     * 停止一个房间的合流转推
+     *
+     * @param string $appId
+     * @param string $roomName
+     * @return array
+     * @link https://doc.qnsdk.com/rtn/docs/server_overview#2_2
+     */
+    public function stopMerge($appId, $roomName)
+    {
+        $url = sprintf("%s/%s/rooms/%s/merge", $this->baseURL, $appId, $roomName);
+        return $this->delete($url);
     }
 
-    /*
+    /**
      * 获取应用中活跃房间
-     * appId: app 的唯一标识,创建的时候由系统生成。
-     * prefix: 所查询房间名的前缀索引,可以为空。
-     * offset: int 类型,分页查询的位移标记。
-     * limit: int 类型,此次查询的最大长度。
-     * GET /v3/apps//rooms?prefix=&offset=&limit=
+     *
+     * @param string $appId 连麦房间所属的 app
+     * @param null $prefix 所查询房间名的前缀索引,可以为空。
+     * @param int $offset 分页查询的位移标记
+     * @param int $limit 此次查询的最大长度
+     * @return array
+     * @link https://doc.qnsdk.com/rtn/docs/server_overview#2_2
      */
     public function listActiveRooms($appId, $prefix = null, $offset = null, $limit = null)
     {
+        $query = array();
         if (isset($prefix)) {
             $query['prefix'] = $prefix;
         }
@@ -148,22 +172,23 @@ public function listActiveRooms($appId, $prefix = null, $offset = null, $limit =
         } else {
             $url = sprintf("%s/%s/rooms", $this->baseURL, $appId);
         }
-        $ret  = $this->get($url);
-        return $ret;
+        return $this->get($url);
     }
 
-    /*
+    /**
      * 生成加入房间的令牌
-     * appId: app 的唯一标识,创建的时候由系统生成。
-     * roomName: 房间名称,需满足规格 ^[a-zA-Z0-9_-]{3,64}$
-     * userId: 请求加入房间的用户 ID,需满足规格 ^[a-zA-Z0-9_-]{3,50}$
-     * expireAt: int64 类型,鉴权的有效时间,传入以秒为单位的64位Unix
-       绝对时间,token 将在该时间后失效。
-     * permission: 该用户的房间管理权限,"admin" 或 "user",默认为 "user" 。
-       当权限角色为 "admin" 时,拥有将其他用户移除出房间等特权.
+     *
+     * @param string $appId app 的唯一标识,创建的时候由系统生成
+     * @param string $roomName 房间名称,需满足规格 ^[a-zA-Z0-9_-]{3,64}$
+     * @param string $userId 请求加入房间的用户 ID,需满足规格 ^[a-zA-Z0-9_-]{3,50}$
+     * @param int $expireAt 鉴权的有效时间,传入以秒为单位的64位 Unix 绝对时间
+     * @param string $permission 该用户的房间管理权限,"admin" 或 "user",默认为 "user"
+     * @return string
+     * @link https://doc.qnsdk.com/rtn/docs/server_overview#1
      */
     public function appToken($appId, $roomName, $userId, $expireAt, $permission)
     {
+        $params = array();
         $params['appId'] = $appId;
         $params['userId'] = $userId;
         $params['roomName'] = $roomName;
diff --git a/vendor/qiniu/php-sdk/src/Qiniu/Sms/Sms.php b/vendor/qiniu/php-sdk/src/Qiniu/Sms/Sms.php
index f19a124fb..625ec3044 100644
--- a/vendor/qiniu/php-sdk/src/Qiniu/Sms/Sms.php
+++ b/vendor/qiniu/php-sdk/src/Qiniu/Sms/Sms.php
@@ -1,10 +1,11 @@
 baseURL = sprintf("%s/%s/", Config::SMS_HOST, Config::SMS_VERSION);
     }
 
-    /*
+    /**
      * 创建签名
-     * signature: string 类型,必填,【长度限制8个字符内】超过长度会报错
-     * source: string   类型,必填,申请签名时必须指定签名来源。取值范围为:
-        nterprises_and_institutions 企事业单位的全称或简称
-        website 工信部备案网站的全称或简称
-        app APP应用的全称或简称
-        public_number_or_small_program 公众号或小程序的全称或简称
-        store_name 电商平台店铺名的全称或简称
-        trade_name 商标名的全称或简称,
-     * pics: 本地的图片路径 string 类型,可选
-     *@return: 类型array {
-        "signature_id": 
-        }
+     *
+     * @param string $signature 签名
+     * @param string $source 签名来源,申请签名时必须指定签名来源
+     * @param string $pics 签名对应的资质证明图片进行 base64 编码格式转换后的字符串,可选
+     * @return array
+     *
+     * @link https://developer.qiniu.com/sms/api/5844/sms-api-create-signature
      */
     public function createSignature($signature, $source, $pics = null)
     {
+        $params = array();
         $params['signature'] = $signature;
         $params['source'] = $source;
         if (!empty($pics)) {
-            $params['pics'] = $this->imgToBase64($pics);
+            $params['pics'] = array($this->imgToBase64($pics));
         }
         $body = json_encode($params);
-        $url =$this->baseURL.'signature';
-        $ret = $this->post($url, $body);
-        return $ret;
+        $url = $this->baseURL . 'signature';
+        return $this->post($url, $body);
     }
 
-    /*
-    * 编辑签名
-    *  id 签名id : string 类型,必填,
-    * signature: string 类型,必填,
-    * source: string    类型,必填,申请签名时必须指定签名来源。取值范围为:
-        enterprises_and_institutions 企事业单位的全称或简称
-        website 工信部备案网站的全称或简称
-        app APP应用的全称或简称
-        public_number_or_small_program 公众号或小程序的全称或简称
-        store_name 电商平台店铺名的全称或简称
-        trade_name 商标名的全称或简称,
-    * pics: 本地的图片路径 string   类型,可选,
-    * @return: 类型array {
-        "signature": string
-        }
-    */
+    /**
+     * 编辑签名
+     *
+     * @param string $id 签名 ID
+     * @param string $signature 签名
+     * @param string $source 签名来源
+     * @param string $pics 签名对应的资质证明图片进行 base64 编码格式转换后的字符串,可选
+     * @return array
+     * @link https://developer.qiniu.com/sms/api/5890/sms-api-edit-signature
+     */
     public function updateSignature($id, $signature, $source, $pics = null)
     {
+        $params = array();
         $params['signature'] = $signature;
         $params['source'] = $source;
         if (!empty($pics)) {
-            $params['pics'] = $this->imgToBase64($pics);
+            $params['pics'] = array($this->imgToBase64($pics));
         }
         $body = json_encode($params);
-        $url =$this->baseURL.'signature/'.$id;
-        $ret = $this->PUT($url, $body);
-        return $ret;
+        $url = $this->baseURL . 'signature/' . $id;
+        return $this->PUT($url, $body);
     }
 
-    /*
- * 查询签名
- * audit_status: 审核状态 string 类型,可选,
-   取值范围为: "passed"(通过), "rejected"(未通过), "reviewing"(审核中)
- * page:页码 int  类型,
- * page_size: 分页大小 int 类型,可选, 默认为20
- *@return: 类型array {
-    "items": [{
-        "id": string,
-        "signature": string,
-        "source": string,
-        "audit_status": string,
-        "reject_reason": string,
-        "created_at": int64,
-        "updated_at": int64
-            }...],
-    "total": int,
-    "page": int,
-    "page_size": int,
-    }
- */
-    public function checkSignature($audit_status = null, $page = 1, $page_size = 20)
+    /**
+     * 列出签名
+     *
+     * @param string $audit_status 审核状态:"passed"(通过), "rejected"(未通过), "reviewing"(审核中)
+     * @param int $page 页码。默认为 1
+     * @param int $page_size 分页大小。默认为 20
+     * @return array
+     * @link https://developer.qiniu.com/sms/api/5889/sms-api-query-signature
+     */
+    public function querySignature($audit_status = null, $page = 1, $page_size = 20)
     {
 
         $url = sprintf(
             "%s?audit_status=%s&page=%s&page_size=%s",
-            $this->baseURL.'signature',
+            $this->baseURL . 'signature',
             $audit_status,
             $page,
             $page_size
         );
-        $ret  = $this->get($url);
-        return $ret;
+        return $this->get($url);
     }
 
-
-    /*
- * 删除签名
- * id 签名id string 类型,必填,
- * @retrun : 请求成功 HTTP 状态码为 200
- */
-    public function deleteSignature($id)
+    /**
+     * 查询单个签名
+     *
+     * @param string $signature_id
+     * @return array
+     * @link https://developer.qiniu.com/sms/api/5970/query-a-single-signature
+     */
+    public function checkSingleSignature($signature_id)
     {
-        $url = $this->baseURL . 'signature/' . $id;
-        list(, $err)  = $this->delete($url);
-        return $err;
-    }
-
 
+        $url = sprintf(
+            "%s/%s",
+            $this->baseURL . 'signature',
+            $signature_id
+        );
+        return $this->get($url);
+    }
 
+    /**
+     * 删除签名
+     *
+     * @param string $signature_id 签名 ID
+     * @return array
+     * @link https://developer.qiniu.com/sms/api/5891/sms-api-delete-signature
+     */
+    public function deleteSignature($signature_id)
+    {
+        $url = $this->baseURL . 'signature/' . $signature_id;
+        return $this->delete($url);
+    }
 
-    /*
-    * 创建模板
-    * name  : 模板名称 string 类型 ,必填
-    * template:  模板内容 string  类型,必填
-    * type: 模板类型 string 类型,必填,
-      取值范围为: notification (通知类短信), verification (验证码短信), marketing (营销类短信)
-    * description:  申请理由简述 string  类型,必填
-    * signature_id:  已经审核通过的签名 string  类型,必填
-    * @return: 类型 array {
-        "template_id": string
-                }
-    */
+    /**
+     * 创建模板
+     *
+     * @param string $name 模板名称
+     * @param string $template 模板内容 可设置自定义变量,发送短信时候使用,参考:${code}
+     * @param string $type notification:通知类,verification:验证码,marketing:营销类,voice:语音类
+     * @param string $description 申请理由简述
+     * @param string $signature_id 已经审核通过的签名
+     * @return array array
+     * @link https://developer.qiniu.com/sms/api/5893/sms-api-create-template
+     */
     public function createTemplate(
         $name,
         $template,
         $type,
         $description,
-        $signture_id
+        $signature_id
     ) {
+        $params = array();
         $params['name'] = $name;
         $params['template'] = $template;
         $params['type'] = $type;
         $params['description'] = $description;
-        $params['signature_id'] = $signture_id;
+        $params['signature_id'] = $signature_id;
 
         $body = json_encode($params);
-        $url =$this->baseURL.'template';
-        $ret = $this->post($url, $body);
-        return $ret;
+        $url = $this->baseURL . 'template';
+        return $this->post($url, $body);
     }
 
-    /*
-  * 查询模板
-  * audit_status: 审核状态 string 类型 ,可选,
-    取值范围为: passed (通过), rejected (未通过), reviewing (审核中)
-  * page:  页码 int  类型,可选,默认为 1
-  * page_size: 分页大小 int 类型,可选,默认为 20
-  * @return: 类型array{
-      "items": [{
-            "id": string,
-            "name": string,
-            "template": string,
-            "audit_status": string,
-            "reject_reason": string,
-            "type": string,
-            "signature_id": string, // 模版绑定的签名ID
-            "signature_text": string, // 模版绑定的签名内容
-            "created_at": int64,
-            "updated_at": int64
-        }...],
-        "total": int,
-        "page": int,
-        "page_size": int
-        }
-  */
+    /**
+     * 列出模板
+     *
+     * @param string $audit_status 审核状态:passed (通过), rejected (未通过), reviewing (审核中)
+     * @param int $page 页码。默认为 1
+     * @param int $page_size 分页大小。默认为 20
+     * @return array
+     * @link https://developer.qiniu.com/sms/api/5894/sms-api-query-template
+     */
     public function queryTemplate($audit_status = null, $page = 1, $page_size = 20)
     {
 
         $url = sprintf(
             "%s?audit_status=%s&page=%s&page_size=%s",
-            $this->baseURL.'template',
+            $this->baseURL . 'template',
             $audit_status,
             $page,
             $page_size
         );
-        $ret  = $this->get($url);
-        return $ret;
+        return $this->get($url);
     }
 
-    /*
-    * 编辑模板
-    * id :模板id
-    * name  : 模板名称 string 类型 ,必填
-    * template:  模板内容 string  类型,必填
-    * description:  申请理由简述 string  类型,必填
-    * signature_id:  已经审核通过的签名 string  类型,必填
-    * @retrun : 请求成功 HTTP 状态码为 200
-    */
+    /**
+     * 查询单个模版
+     *
+     * @param string $template_id 模版ID
+     * @return array
+     * @link https://developer.qiniu.com/sms/api/5969/query-a-single-template
+     */
+    public function querySingleTemplate($template_id)
+    {
+
+        $url = sprintf(
+            "%s/%s",
+            $this->baseURL . 'template',
+            $template_id
+        );
+        return $this->get($url);
+    }
+
+    /**
+     * 编辑模板
+     *
+     * @param string $id 模板 ID
+     * @param string $name 模板名称
+     * @param string $template 模板内容
+     * @param string $description 申请理由简述
+     * @param string $signature_id 已经审核通过的签名 ID
+     * @return array
+     * @link https://developer.qiniu.com/sms/api/5895/sms-api-edit-template
+     */
     public function updateTemplate(
         $id,
         $name,
@@ -211,51 +206,96 @@ public function updateTemplate(
         $description,
         $signature_id
     ) {
+        $params = array();
         $params['name'] = $name;
         $params['template'] = $template;
         $params['description'] = $description;
         $params['signature_id'] = $signature_id;
         $body = json_encode($params);
-        $url =$this->baseURL.'template/'.$id;
-        $ret = $this->PUT($url, $body);
-        return $ret;
+        $url = $this->baseURL . 'template/' . $id;
+        return $this->PUT($url, $body);
     }
 
-    /*
-    * 删除模板
-    * id :模板id string 类型,必填,
-    * @retrun : 请求成功 HTTP 状态码为 200
-    */
-    public function deleteTemplate($id)
+    /**
+     * 删除模板
+     *
+     * @param string $template_id 模板 ID
+     * @return array
+     * @link https://developer.qiniu.com/sms/api/5896/sms-api-delete-template
+     */
+    public function deleteTemplate($template_id)
     {
-        $url = $this->baseURL . 'template/' . $id;
-        list(, $err)  = $this->delete($url);
-        return $err;
+        $url = $this->baseURL . 'template/' . $template_id;
+        return $this->delete($url);
     }
 
-    /*
-    * 发送短信
-    * 编辑模板
-    * template_id :模板id string类型,必填
-    * mobiles   : 手机号数组 []string 类型 ,必填
-    * parameters:  模板内容 map[string]string     类型,可选
-    * @return: 类型json {
-        "job_id": string
-        }
-    */
+    /**
+     * 发送短信
+     *
+     * @param string $template_id 模板 ID
+     * @param array $mobiles 手机号
+     * @param array $parameters 自定义模板变量,变量设置在创建模板时,参数template指定
+     * @return array
+     * @link https://developer.qiniu.com/sms/api/5897/sms-api-send-message
+     */
     public function sendMessage($template_id, $mobiles, $parameters = null)
     {
+        $params = array();
         $params['template_id'] = $template_id;
         $params['mobiles'] = $mobiles;
         if (!empty($parameters)) {
             $params['parameters'] = $parameters;
         }
         $body = json_encode($params);
-        $url =$this->baseURL.'message';
-        $ret = $this->post($url, $body);
-        return $ret;
+        $url = $this->baseURL . 'message';
+        return $this->post($url, $body);
+    }
+
+    /**
+     * 查询发送记录
+     *
+     * @param string $job_id 发送任务返回的 id
+     * @param string $message_id 单条短信发送接口返回的 id
+     * @param string $mobile 接收短信的手机号码
+     * @param string $status sending: 发送中,success: 发送成功,failed: 发送失败,waiting: 等待发送
+     * @param string $template_id 模版 id
+     * @param string $type marketing:营销,notification:通知,verification:验证码,voice:语音
+     * @param string $start 开始时间,timestamp,例如: 1563280448
+     * @param int $end 结束时间,timestamp,例如: 1563280471
+     * @param int $page 页码,默认为 1
+     * @param int $page_size 每页返回的数据条数,默认20,最大200
+     * @return array
+     * @link https://developer.qiniu.com/sms/api/5852/query-send-sms
+     */
+    public function querySendSms(
+        $job_id = null,
+        $message_id = null,
+        $mobile = null,
+        $status = null,
+        $template_id = null,
+        $type = null,
+        $start = null,
+        $end = null,
+        $page = 1,
+        $page_size = 20
+    ) {
+        $query = array();
+        \Qiniu\setWithoutEmpty($query, 'job_id', $job_id);
+        \Qiniu\setWithoutEmpty($query, 'message_id', $message_id);
+        \Qiniu\setWithoutEmpty($query, 'mobile', $mobile);
+        \Qiniu\setWithoutEmpty($query, 'status', $status);
+        \Qiniu\setWithoutEmpty($query, 'template_id', $template_id);
+        \Qiniu\setWithoutEmpty($query, 'type', $type);
+        \Qiniu\setWithoutEmpty($query, 'start', $start);
+        \Qiniu\setWithoutEmpty($query, 'end', $end);
+        \Qiniu\setWithoutEmpty($query, 'page', $page);
+        \Qiniu\setWithoutEmpty($query, 'page_size', $page_size);
+
+        $url = $this->baseURL . 'messages?' . http_build_query($query);
+        return $this->get($url);
     }
 
+
     public function imgToBase64($img_file)
     {
         $img_base64 = '';
@@ -265,9 +305,10 @@ public function imgToBase64($img_file)
             $fp = fopen($app_img_file, "r"); // 图片是否可读权限
             if ($fp) {
                 $filesize = filesize($app_img_file);
-                if ($filesize > 5*1024*1024) {
+                if ($filesize > 5 * 1024 * 1024) {
                     die("pic size < 5M !");
                 }
+                $img_type = null;
                 $content = fread($fp, $filesize);
                 $file_content = chunk_split(base64_encode($content)); // base64编码
                 switch ($img_info[2]) {           //判读图片类型
@@ -290,11 +331,11 @@ public function imgToBase64($img_file)
         return $img_base64;
     }
 
-    private function get($url, $cType = null)
+    private function get($url, $contentType = 'application/x-www-form-urlencoded')
     {
-        $rtcToken = $this->auth->authorizationV2($url, "GET", null, $cType);
-        $rtcToken['Content-Type'] = $cType;
-        $ret = Client::get($url, $rtcToken);
+        $headers = $this->auth->authorizationV2($url, "GET", null, $contentType);
+        $headers['Content-Type'] = $contentType;
+        $ret = Client::get($url, $headers);
         if (!$ret->ok()) {
             return array(null, new Error($url, $ret));
         }
@@ -303,9 +344,9 @@ private function get($url, $cType = null)
 
     private function delete($url, $contentType = 'application/json')
     {
-        $rtcToken = $this->auth->authorizationV2($url, "DELETE", null, $contentType);
-        $rtcToken['Content-Type'] = $contentType;
-        $ret = Client::delete($url, $rtcToken);
+        $headers = $this->auth->authorizationV2($url, "DELETE", null, $contentType);
+        $headers['Content-Type'] = $contentType;
+        $ret = Client::delete($url, $headers);
         if (!$ret->ok()) {
             return array(null, new Error($url, $ret));
         }
@@ -314,20 +355,22 @@ private function delete($url, $contentType = 'application/json')
 
     private function post($url, $body, $contentType = 'application/json')
     {
-        $rtcToken = $this->auth->authorizationV2($url, "POST", $body, $contentType);
-        $rtcToken['Content-Type'] = $contentType;
-        $ret = Client::post($url, $body, $rtcToken);
+        $headers = $this->auth->authorizationV2($url, "POST", $body, $contentType);
+
+        $headers['Content-Type'] = $contentType;
+        $ret = Client::post($url, $body, $headers);
         if (!$ret->ok()) {
             return array(null, new Error($url, $ret));
         }
         $r = ($ret->body === null) ? array() : $ret->json();
         return array($r, null);
     }
+
     private function PUT($url, $body, $contentType = 'application/json')
     {
-        $rtcToken = $this->auth->authorizationV2($url, "PUT", $body, $contentType);
-        $rtcToken['Content-Type'] = $contentType;
-        $ret = Client::put($url, $body, $rtcToken);
+        $headers = $this->auth->authorizationV2($url, "PUT", $body, $contentType);
+        $headers['Content-Type'] = $contentType;
+        $ret = Client::put($url, $body, $headers);
         if (!$ret->ok()) {
             return array(null, new Error($url, $ret));
         }
diff --git a/vendor/qiniu/php-sdk/src/Qiniu/Storage/ArgusManager.php b/vendor/qiniu/php-sdk/src/Qiniu/Storage/ArgusManager.php
index 08893708c..0f2baee2c 100644
--- a/vendor/qiniu/php-sdk/src/Qiniu/Storage/ArgusManager.php
+++ b/vendor/qiniu/php-sdk/src/Qiniu/Storage/ArgusManager.php
@@ -1,4 +1,5 @@
 arPost($path, $body);
+    }
+
+
+    /**
+     * 图片审核
      *
-     * @param $body     body信息
-     * @param $vid      videoID
+     * @param string $body
      *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
-     * @link  https://developer.qiniu.com/dora/manual/4258/video-pulp
+     * @return array 成功返回NULL,失败返回对象Qiniu\Http\Error
+     * @link  https://developer.qiniu.com/censor/api/5588/image-censor
      */
-    public function pulpVideo($body, $vid)
+    public function censorImage($body)
     {
-        $path = '/v1/video/' . $vid;
-        
+        $path = '/v3/image/censor';
+
         return $this->arPost($path, $body);
     }
 
+    /**
+     * 查询视频审核结果
+     *
+     * @param string $jobid 任务ID
+     * @return array
+     * @link  https://developer.qiniu.com/censor/api/5620/video-censor
+     */
+    public function censorStatus($jobid)
+    {
+        $scheme = "http://";
+
+        if ($this->config->useHTTPS === true) {
+            $scheme = "https://";
+        }
+        $url = $scheme . Config::ARGUS_HOST . "/v3/jobs/video/$jobid";
+        $response = $this->get($url);
+        if (!$response->ok()) {
+            print("statusCode: " . $response->statusCode);
+            return array(null, new Error($url, $response));
+        }
+        return array($response->json(), null);
+    }
+
     private function getArHost()
     {
         $scheme = "http://";
-        if ($this->config->useHTTPS == true) {
+        if ($this->config->useHTTPS === true) {
             $scheme = "https://";
         }
         return $scheme . Config::ARGUS_HOST;
@@ -58,16 +97,27 @@ private function arPost($path, $body = null)
         return $this->post($url, $body);
     }
 
+    private function get($url)
+    {
+        $headers = $this->auth->authorizationV2($url, 'GET');
+
+        return Client::get($url, $headers);
+    }
+
     private function post($url, $body)
     {
         $headers = $this->auth->authorizationV2($url, 'POST', $body, 'application/json');
-        $headers['Content-Type']='application/json';
+        $headers['Content-Type'] = 'application/json';
         $ret = Client::post($url, $body, $headers);
         if (!$ret->ok()) {
-            print($ret->statusCode);
+            print("statusCode: " . $ret->statusCode);
             return array(null, new Error($url, $ret));
         }
         $r = ($ret->body === null) ? array() : $ret->json();
+        if (strstr($url, "video")) {
+            $jobid = $r['job'];
+            return array($jobid, null);
+        }
         return array($r, null);
     }
 }
diff --git a/vendor/qiniu/php-sdk/src/Qiniu/Storage/BucketManager.php b/vendor/qiniu/php-sdk/src/Qiniu/Storage/BucketManager.php
index 0a2413dd4..600cb6c79 100644
--- a/vendor/qiniu/php-sdk/src/Qiniu/Storage/BucketManager.php
+++ b/vendor/qiniu/php-sdk/src/Qiniu/Storage/BucketManager.php
@@ -1,11 +1,11 @@
 ucPost($path);
-        return $info;
+        return $this->ucPost($path);
     }
 
     /**
      * 创建空间
      *
-     * @param $name     创建的空间名
-     * @param $region    创建的区域,默认华东
+     * @param string $name 创建的空间名
+     * @param string $region 创建的区域,默认华东
      *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
+     * @return array
+     * @link https://developer.qiniu.com/kodo/api/1382/mkbucketv3
      */
     public function createBucket($name, $region = 'z0')
     {
-        $path = '/mkbucketv2/'.$name.'/region/' . $region;
+        $path = '/mkbucketv3/' . $name . '/region/' . $region;
         return $this->rsPost($path, null);
     }
 
     /**
      * 删除空间
      *
-     * @param $name     删除的空间名
+     * @param string $name 需要删除的目标空间名
      *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
+     * @return array
+     * @link https://developer.qiniu.com/kodo/api/1601/drop-bucket
      */
     public function deleteBucket($name)
     {
-        $path = '/drop/'.$name;
+        $path = '/drop/' . $name;
         return $this->rsPost($path, null);
     }
 
     /**
      * 获取指定空间绑定的所有的域名
      *
-     * @return string[] 包含所有空间域名
+     * @param string $bucket 空间名称
+     * @return array
      */
     public function domains($bucket)
     {
@@ -104,55 +102,40 @@ public function domains($bucket)
     /**
      * 获取指定空间的相关信息
      *
-     * @return string[] 包含空间信息
+     * @param string $bucket 空间名称
+     * @return array
      */
     public function bucketInfo($bucket)
     {
         $path = '/v2/bucketInfo?bucket=' . $bucket;
-        $info = $this->ucPost($path);
-        return $info;
+        return $this->ucPost($path);
     }
 
     /**
      * 获取指定zone的空间信息列表
-     * 在Region 未指定且Global 不为 true 时(包含未指定的情况,下同),返回用户的所有空间。
-     * 在指定了 region 参数且 global 不为 true 时,只列举非全局空间。
-     * shared 不指定shared参数或指定shared为rw或false时,返回包含具有读写权限空间,
-     * 指定shared为rd或true时,返回包含具有读权限空间。
-     * fs:如果为 true,会返回每个空间当前的文件数和存储量(实时数据)。
-     * @return string[] 包含空间信息
+     *
+     * @param string $region 区域
+     * @param string $shared 指定共享空间,rw:读写权限空间,rd:读权限空间
+     * @param string $fs 如果为 true,会返回每个空间当前的文件数和存储量(实时数据)
+     * @return array
      */
     public function bucketInfos($region = null, $shared = 'false', $fs = 'false')
     {
         $path = '/v2/bucketInfos?region=' . $region . '&shared=' . $shared . '&fs=' . $fs;
-        $info = $this->ucPost($path);
-        return $info;
+        return $this->ucPost($path);
     }
 
-    /**
-     * 获取空间绑定的域名列表
-     * @return string[] 包含空间绑定的所有域名
-     */
-
     /**
      * 列取空间的文件列表
      *
-     * @param $bucket     空间名
-     * @param $prefix     列举前缀
-     * @param $marker     列举标识符
-     * @param $limit      单次列举个数限制
-     * @param $delimiter  指定目录分隔符
+     * @param string $bucket 空间名
+     * @param string $prefix 列举前缀
+     * @param string $marker 列举标识符
+     * @param int $limit 单次列举个数限制
+     * @param string $delimiter 指定目录分隔符
      *
-     * @return array    包含文件信息的数组,类似:[
-*                                              {
-*                                                 "hash" => "",
-*                                                  "key" => "",
-*                                                  "fsize" => "",
-*                                                  "putTime" => ""
-*                                              },
-*                                              ...
-*                                            ]
-     * @link  http://developer.qiniu.com/docs/v6/api/reference/rs/list.html
+     * @return array
+     * @link  https://developer.qiniu.com/kodo/api/1284/list
      */
     public function listFiles(
         $bucket,
@@ -173,22 +156,14 @@ public function listFiles(
     /**
      * 列取空间的文件列表
      *
-     * @param $bucket     空间名
-     * @param $prefix     列举前缀
-     * @param $marker     列举标识符
-     * @param $limit      单次列举个数限制
-     * @param $delimiter  指定目录分隔符
-     * @param $skipconfirm  是否跳过已删除条目的确认机制
+     * @param string $bucket 空间名
+     * @param string $prefix 列举前缀
+     * @param string $marker 列举标识符
+     * @param int $limit 单次列举个数限制
+     * @param string $delimiter 指定目录分隔符
+     * @param bool $skipconfirm 是否跳过已删除条目的确认机制
      *
-     * @return array    包含文件信息的数组,类似:[
-*                                              {
-*                                                 "hash" => "",
-*                                                  "key" => "",
-*                                                  "fsize" => "",
-*                                                  "putTime" => ""
-*                                              },
-*                                              ...
-*                                            ]
+     * @return array
      * @link  http://developer.qiniu.com/docs/v6/api/reference/rs/list.html
      */
     public function listFilesv2(
@@ -213,40 +188,22 @@ public function listFilesv2(
             return array(null, new Error($url, $ret));
         }
         $r = explode("\n", $ret->body);
-        $pop = array_pop($r);
+        array_pop($r);
         return array($r, null);
     }
 
-    /**
-     * 设置Referer防盗链
-     *
-     * @param $bucket     空间名
-     * @param $mode     0: 表示关闭Referer(使用此选项将会忽略以下参数并将恢复默认值);
-     * 1: 表示设置Referer白名单; 2:表示设置Referer黑名单
-     * @param $norefer     0: 表示不允许空 Refer 访问; 1: 表示允许空 Refer 访问
-     * @param $pattern      规则字符串, 当前允许格式分为三种: 一种为空主机头域名,
-     * 比如 foo.com; 一种是泛域名,比如 *.bar.com; 一种是完全通配符,
-     * 即一个 *; 多个规则之间用;隔开, 比如: foo.com;*.bar.com;sub.foo.com;*.sub.bar.com
-     * @param $source_enabled  源站是否支持,默认为0只给CDN配置, 设置为1表示开启源站防盗链
-     *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
-     */
-    // public function referAntiLeech(){
-
-    // }
-
     /**
      * 增加bucket生命规则
      *
-     * @param $bucket     空间名
-     * @param $name     规则名称 bucket 内唯一,长度小于50,不能为空,只能为
+     * @param string $bucket 空间名
+     * @param string $name 规则名称 bucket 内唯一,长度小于50,不能为空,只能为
      * 字母、数字、下划线
-     * @param $prefix     同一个 bucket 里面前缀不能重复
-     * @param $delete_after_days      指定上传文件多少天后删除,指定为0表示不删除,
+     * @param string $prefix 同一个 bucket 里面前缀不能重复
+     * @param int $delete_after_days 指定上传文件多少天后删除,指定为0表示不删除,
      * 大于0表示多少天后删除,需大于 to_line_after_days
-     * @param $to_line_after_days  指定文件上传多少天后转低频存储。指定为0表示
+     * @param int $to_line_after_days 指定文件上传多少天后转低频存储。指定为0表示
      * 不转低频存储,小于0表示上传的文件立即变低频存储
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
+     * @return array
      */
     public function bucketLifecycleRule(
         $bucket,
@@ -256,6 +213,7 @@ public function bucketLifecycleRule(
         $to_line_after_days
     ) {
         $path = '/rules/add';
+        $params = array();
         if ($bucket) {
             $params['bucket'] = $bucket;
         }
@@ -279,15 +237,15 @@ public function bucketLifecycleRule(
     /**
      * 更新bucket生命规则
      *
-     * @param $bucket     空间名
-     * @param $name     规则名称 bucket 内唯一,长度小于50,不能为空,只能为字母、
+     * @param string $bucket 空间名
+     * @param string $name 规则名称 bucket 内唯一,长度小于50,不能为空,只能为字母、
      * 数字、下划线
-     * @param $prefix     同一个 bucket 里面前缀不能重复
-     * @param $delete_after_days      指定上传文件多少天后删除,指定为0表示不删除,
+     * @param string $prefix 同一个 bucket 里面前缀不能重复
+     * @param int $delete_after_days 指定上传文件多少天后删除,指定为0表示不删除,
      * 大于0表示多少天后删除,需大于 to_line_after_days
-     * @param $to_line_after_days  指定文件上传多少天后转低频存储。指定为0表示不
+     * @param int $to_line_after_days 指定文件上传多少天后转低频存储。指定为0表示不
      * 转低频存储,小于0表示上传的文件立即变低频存储
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
+     * @return array
      */
     public function updateBucketLifecycleRule(
         $bucket,
@@ -297,6 +255,7 @@ public function updateBucketLifecycleRule(
         $to_line_after_days
     ) {
         $path = '/rules/update';
+        $params = array();
         if ($bucket) {
             $params['bucket'] = $bucket;
         }
@@ -313,15 +272,14 @@ public function updateBucketLifecycleRule(
             $params['to_line_after_days'] = $to_line_after_days;
         }
         $data = http_build_query($params);
-        $info = $this->ucPost($path, $data);
-        return $info;
+        return $this->ucPost($path, $data);
     }
 
     /**
      * 获取bucket生命规则
      *
-     * @param $bucket     空间名
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
+     * @param string $bucket 空间名
+     * @return array
      */
     public function getBucketLifecycleRules($bucket)
     {
@@ -333,14 +291,15 @@ public function getBucketLifecycleRules($bucket)
     /**
      * 删除bucket生命规则
      *
-     * @param $bucket     空间名
-     * @param $name     规则名称 bucket 内唯一,长度小于50,不能为空,
+     * @param string $bucket 空间名
+     * @param string $name 规则名称 bucket 内唯一,长度小于50,不能为空,
      * 只能为字母、数字、下划线()
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
+     * @return array
      */
     public function deleteBucketLifecycleRule($bucket, $name)
     {
         $path = '/rules/delete';
+        $params = array();
         if ($bucket) {
             $params['bucket'] = $bucket;
         }
@@ -355,18 +314,18 @@ public function deleteBucketLifecycleRule($bucket, $name)
     /**
      * 增加bucket事件通知规则
      *
-     * @param $bucket     空间名
-     * @param $name     规则名称 bucket 内唯一,长度小于50,不能为空,
+     * @param string $bucket 空间名
+     * @param string $name 规则名称 bucket 内唯一,长度小于50,不能为空,
      * 只能为字母、数字、下划线()
-     * @param $prefix     同一个 bucket 里面前缀不能重复
-     * @param $suffix      可选,文件配置的后缀
-     * @param $event  事件类型,可以指定多个,包括 put,mkfile,delete,copy,move,append,
+     * @param string $prefix 同一个 bucket 里面前缀不能重复
+     * @param string $suffix 可选,文件配置的后缀
+     * @param array $event 事件类型,可以指定多个,包括 put,mkfile,delete,copy,move,append,
      * disable,enable,deleteMarkerCreate
-     * @param $callbackURL 通知URL,可以指定多个,失败依次重试
-     * @param $access_key 可选,设置的话会对通知请求用对应的ak、sk进行签名
-     * @param $host 可选,通知请求的host
+     * @param string $callbackURL 通知URL,可以指定多个,失败依次重试
+     * @param string $access_key 可选,设置的话会对通知请求用对应的ak、sk进行签名
+     * @param string $host 可选,通知请求的host
      *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
+     * @return array
      */
     public function putBucketEvent(
         $bucket,
@@ -379,29 +338,30 @@ public function putBucketEvent(
         $host = null
     ) {
         $path = '/events/add';
-        if ($bucket) {
+        $params = array();
+        if (!empty($bucket)) {
             $params['bucket'] = $bucket;
         }
-        if ($name) {
+        if (!empty($name)) {
             $params['name'] = $name;
         }
-        if ($prefix) {
+        if (!empty($prefix)) {
             $params['prefix'] = $prefix;
         }
-        if ($suffix) {
+        if (!empty($suffix)) {
             $params['suffix'] = $suffix;
         }
-        if ($callbackURL) {
+        if (!empty($callbackURL)) {
             $params['callbackURL'] = $callbackURL;
         }
-        if ($access_key) {
+        if (!empty($access_key)) {
             $params['access_key'] = $access_key;
         }
-        if ($host) {
+        if (!empty($host)) {
             $params['host'] = $host;
         }
         $data = http_build_query($params);
-        if ($event) {
+        if (!empty($event)) {
             $eventpath = "";
             foreach ($event as $key => $value) {
                 $eventpath .= "&event=$value";
@@ -415,18 +375,18 @@ public function putBucketEvent(
     /**
      * 更新bucket事件通知规则
      *
-     * @param $bucket     空间名
-     * @param $name     规则名称 bucket 内唯一,长度小于50,不能为空,
+     * @param string $bucket 空间名
+     * @param string $name 规则名称 bucket 内唯一,长度小于50,不能为空,
      * 只能为字母、数字、下划线()
-     * @param $prefix     同一个 bucket 里面前缀不能重复
-     * @param $suffix      可选,文件配置的后缀
-     * @param $event  事件类型,可以指定多个,包括 put,mkfile,delete,copy,move,append,disable,
+     * @param string $prefix 同一个 bucket 里面前缀不能重复
+     * @param string $suffix 可选,文件配置的后缀
+     * @param array $event 事件类型,可以指定多个,包括 put,mkfile,delete,copy,move,append,disable,
      * enable,deleteMarkerCreate
-     * @param $callbackURL 通知URL,可以指定多个,失败依次重试
-     * @param $access_key 可选,设置的话会对通知请求用对应的ak、sk进行签名
-     * @param $host 可选,通知请求的host
+     * @param string $callbackURL 通知URL,可以指定多个,失败依次重试
+     * @param string $access_key 可选,设置的话会对通知请求用对应的ak、sk进行签名
+     * @param string $host 可选,通知请求的host
      *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
+     * @return array
      */
     public function updateBucketEvent(
         $bucket,
@@ -439,59 +399,65 @@ public function updateBucketEvent(
         $host = null
     ) {
         $path = '/events/update';
-        if ($bucket) {
+        $params = array();
+        if (!empty($bucket)) {
             $params['bucket'] = $bucket;
         }
-        if ($name) {
+        if (!empty($name)) {
             $params['name'] = $name;
         }
-        if ($prefix) {
+        if (!empty($prefix)) {
             $params['prefix'] = $prefix;
         }
         if ($suffix) {
             $params['suffix'] = $suffix;
         }
-        if ($event) {
+        if (!empty($event)) {
             $params['event'] = $event;
         }
-        if ($callbackURL) {
+        if (!empty($callbackURL)) {
             $params['callbackURL'] = $callbackURL;
         }
-        if ($access_key) {
+        if (!empty($access_key)) {
             $params['access_key'] = $access_key;
         }
-        if ($host) {
+        if (!empty($host)) {
             $params['host'] = $host;
         }
         $data = http_build_query($params);
-        $info = $this->ucPost($path, $data);
-        return $info;
+        if (!empty($event)) {
+            $eventpath = "";
+            foreach ($event as $key => $value) {
+                $eventpath .= "&event=$value";
+            }
+            $data .= $eventpath;
+        }
+        return $this->ucPost($path, $data);
     }
 
     /**
      * 获取bucket事件通知规则
      *
-     * @param $bucket     空间名
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
+     * @param string $bucket 空间名
+     * @return array
      */
     public function getBucketEvents($bucket)
     {
         $path = '/events/get?bucket=' . $bucket;
-        $info = $this->ucGet($path);
-        return $info;
+        return $this->ucGet($path);
     }
 
     /**
      * 删除bucket事件通知规则
      *
-     * @param $bucket     空间名
-     * @param $name     规则名称 bucket 内唯一,长度小于50,不能为空,
-     * 只能为字母、数字、下划线
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
+     * @param string $bucket 空间名
+     * @param string $name 规则名称bucket内唯一,长度小于50,不能为空,只能为字母、数字、下划线
+     * @return array
      */
     public function deleteBucketEvent($bucket, $name)
     {
         $path = '/events/delete';
+        $params = array();
         if ($bucket) {
             $params['bucket'] = $bucket;
         }
@@ -499,180 +465,112 @@ public function deleteBucketEvent($bucket, $name)
             $params['name'] = $name;
         }
         $data = http_build_query($params);
-        $info = $this->ucPost($path, $data);
-        return $info;
+        return $this->ucPost($path, $data);
     }
 
-    /**
-     * 设置bucket的跨域信息,最多允许设置10条跨域规则。
-     * 对于同一个域名如果设置了多条规则,那么按顺序使用第一条匹配的规则去生成返回值。
-     * 对于简单跨域请求,只匹配 Origin;
-     * allowed_orgin: 允许的域名。必填;支持通配符*;*表示全部匹配;只有第一个*生效;
-     * 需要设置"Scheme";大小写敏感。例如
-     * 规则:http://*.abc.*.com 请求:"http://test.abc.test.com" 结果:不通过
-     * 规则:"http://abc.com" 请求:"https://abc.com"/"abc.com" 结果:不通过
-     * 规则:"abc.com" 请求:"http://abc.com" 结果:不通过
-     * allowed_method: 允许的方法。必填;不支持通配符;大小写不敏感;
-     * allowed_header: 允许的header。选填;支持通配符*,
-     * 但只能是单独的*,表示允许全部header,其他*不生效;
-     * 空则不允许任何header;大小写不敏感;
-     * exposed_header: 暴露的header。选填;不支持通配符;
-     * X-Log, X-Reqid是默认会暴露的两个header;
-     * 其他的header如果没有设置,则不会暴露;大小写不敏感;
-     * max_age: 结果可以缓存的时间。选填;空则不缓存;
-     * allowed_credentials:该配置不支持设置,默认为true。
-     * 备注:如果没有设置任何corsRules,那么默认允许所有的跨域请求
-     */
-    // public function putCorsRules(string $bucket, array $params)
-    // {
-    //     $path = '/corsRules/set/' . $bucket;
-    //     $data = json_encode($params);
-    //     $info = $this->ucPost($path, $data);
-    //     return $info;
-    // }
-
     /**
      * 获取bucket的跨域信息
-     * $bucket 空间名
+     *
+     * @param string $bucket 空间名
+     * @return array
      */
     public function getCorsRules($bucket)
     {
         $path = '/corsRules/get/' . $bucket;
-        $info = $this->ucGet($path);
-        return $info;
-    }
-
-    /**
-     * 设置回源规则
-     * 使用该API设置源站优先级高于/image设置的源站,即IO优先读取source接口设置的源站配置,
-     * 如果存在会忽略/image设置的源站
-     * Bucket 空间名
-     * Host(可选)回源Host
-     * RetryCodes(可选),镜像回源时源站返回Code可以重试,最多指定3个,当前只支持4xx错误码重试
-     * SourceQiniuAK,SourceQiniuSK(可选)如果存在将在回源时对URL进行签名,客户源站可以验证
-     * 以保证请求来自Qiniu服务器
-     * Expires(可选) 签名过期时间,如果不设置默认为1小时
-     * Addr 回源地址,不可重复。
-     * Weight 权重,范围限制1-100,不填默认为1,回源时会根据所有源的权重值进行源站选择,
-     * 主备源会分开计算.
-     * Backup 是否备用回源,回源优先尝试主源
-     */
-    // public function putBucktSourceConfig(array $params)
-    // {
-    //     $path = '/mirrorConfig/set';
-    //     $data = json_encode($params);
-    //     $info = $this->ucPostV2($path, $data);
-    //     return $info;
-    // }
-
-    /**
-     * 获取空间回源配置
-     */
-    public function getBucktSourceConfig(array $params)
-    {
-        $path = '/mirrorConfig/get';
-        $data = json_encode($params);
-        $info = $this->ucPostV2($path, $data);
-        return $info;
+        return $this->ucGet($path);
     }
 
     /**
      * 开关原图保护
-     * mode 为1表示开启原图保护,0表示关闭
+     *
+     * @param string $bucket 空间名称
+     * @param int $mode mode 为1表示开启原图保护,0表示关闭
+     * @return array
      */
     public function putBucketAccessStyleMode($bucket, $mode)
     {
         $path = '/accessMode/' . $bucket . '/mode/' . $mode;
-        $info = $this->ucPost($path, null);
-        return $info;
+        return $this->ucPost($path, null);
     }
 
     /**
      * 设置私有属性
-     * private为0表示公开,为1表示私有
+     *
+     * @param string $bucket 空间名称
+     * @param int $private private为0表示公开,为1表示私有
+     * @return array
      */
     public function putBucketAccessMode($bucket, $private)
     {
-        $path = '/bucket/' . $bucket . '/private/' . $private;
-        $info = $this->ucPost($path, null);
-        return $info;
+        $path = "/private?bucket=$bucket&private=$private";
+        return $this->ucPost($path, null);
     }
 
     /**
-     * 设置referer防盗链
-     * bucket=: bucket 名
-     * mode=:
-     * 0: 表示关闭Referer(使用此选项将会忽略以下参数并将恢复默认值);
-     * 1: 表示设置Referer白名单; 2: 表示设置Referer黑名单
-     * norefer=: 0: 表示不允许空 Refer 访问;
-     * 1: 表示允许空 Refer 访问
-     * pattern=: 规则字符串, 当前允许格式分为三种:
-     * 一种为空主机头域名, 比如 foo.com;
-     * 一种是泛域名, 比如 *.bar.com; 一种是完全通配符, 即一个 *;
-     * 多个规则之间用;隔开, 比如: foo.com;*.bar.com;sub.foo.com;*.sub.bar.com
-     * 空主机头域名可以是多级域名,比如 foo.bar.com。
-     * 多个域名之间不允许夹带空白字符。
-     * source_enabled=:1
+     * 设置 referer 防盗链
+     *
+     * @param string $bucket 空间名称
+     * @param int $mode 0:关闭Referer(使用此选项将会忽略以下参数并将恢复默认值);
+     *                  1:设置Referer白名单; 2:设置Referer黑名单
+     * @param string $norefer 0:不允许空 Refer 访问; 1:表示允许空Refer访问
+     * @param string $pattern 规则字符串
+     * @param int $enabled 源站是否支持,默认为0只给CDN配置, 设置为1表示开启源站防盗链
+     * @return array
+     * @link https://developer.qiniu.com/kodo/manual/6093/set-the-hotlinking-prevention
      */
     public function putReferAntiLeech($bucket, $mode, $norefer, $pattern, $enabled = 1)
     {
         $path = "/referAntiLeech?bucket=$bucket&mode=$mode&norefer=$norefer&pattern=$pattern&source_enabled=$enabled";
-        $info = $this->ucPost($path, null);
-        return $info;
+        return $this->ucPost($path, null);
     }
 
     /**
      * 设置Bucket的maxAge
-     * maxAge为0或者负数表示为默认值(31536000)
+     *
+     * @param string $bucket 空间名称
+     * @param int $maxAge maxAge为0或者负数表示为默认值(31536000)
+     * @return array
      */
     public function putBucketMaxAge($bucket, $maxAge)
     {
         $path = '/maxAge?bucket=' . $bucket . '&maxAge=' . $maxAge;
-        $info = $this->ucPost($path, null);
-        return $info;
+        return $this->ucPost($path, null);
     }
 
     /**
-     * 设置配额
-     * : 空间名称,不支持授权空间
-     * : 空间存储量配额,参数传入0或不传表示不更改当前配置,传入-1表示取消限额,
-     * 新创建的空间默认没有限额。
-     * : 空间文件数配额,参数含义同
+     * 设置空间配额
+     *
+     * @param string $bucket 空间名称,不支持授权空间
+     * @param string $size 空间存储量配额,参数传入0或不传表示不更改当前配置,传入-1表示取消限额,新创建的空间默认没有限额
+     * @param string $count 空间文件数配额,参数含义同
+     * @return array
      */
     public function putBucketQuota($bucket, $size, $count)
     {
         $path = '/setbucketquota/' . $bucket . '/size/' . $size . '/count/' . $count;
-        $info = $this->apiPost($path, null);
-        return $info;
+        return $this->apiPost($path, null);
     }
 
     /**
-     * 获取配额
-     * bucket 空间名称
+     * 获取空间配额
+     *
+     * @param string $bucket 空间名称
+     * @return array
      */
     public function getBucketQuota($bucket)
     {
         $path = '/getbucketquota/' . $bucket;
-        $info = $this->apiPost($path, null);
-        return $info;
+        return $this->apiPost($path, null);
     }
 
     /**
      * 获取资源的元信息,但不返回文件内容
      *
-     * @param $bucket     待获取信息资源所在的空间
-     * @param $key        待获取资源的文件名
-     *
-     * @return array    包含文件信息的数组,类似:
-*                                              [
-*                                                  "hash" => "",
-*                                                  "key" => "",
-*                                                  "fsize" => ,
-*                                                  "putTime" => ""
-*                                                  "fileType" => 
-*                                              ]
+     * @param string $bucket 待获取信息资源所在的空间
+     * @param string $key 待获取资源的文件名
      *
-     * @link  http://developer.qiniu.com/docs/v6/api/reference/rs/stat.html
+     * @return array
+     * @link  https://developer.qiniu.com/kodo/api/1308/stat
      */
     public function stat($bucket, $key)
     {
@@ -683,28 +581,26 @@ public function stat($bucket, $key)
     /**
      * 删除指定资源
      *
-     * @param $bucket     待删除资源所在的空间
-     * @param $key        待删除资源的文件名
+     * @param string $bucket 待删除资源所在的空间
+     * @param string $key 待删除资源的文件名
      *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
-     * @link  http://developer.qiniu.com/docs/v6/api/reference/rs/delete.html
+     * @return array
+     * @link  https://developer.qiniu.com/kodo/api/1257/delete
      */
     public function delete($bucket, $key)
     {
         $path = '/delete/' . \Qiniu\entry($bucket, $key);
-        list(, $error) = $this->rsPost($path);
-        return $error;
+        return $this->rsPost($path);
     }
 
-
     /**
      * 给资源进行重命名,本质为move操作。
      *
-     * @param $bucket     待操作资源所在空间
-     * @param $oldname    待操作资源文件名
-     * @param $newname    目标资源文件名
+     * @param string $bucket 待操作资源所在空间
+     * @param string $oldname 待操作资源文件名
+     * @param string $newname 目标资源文件名
      *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
+     * @return array
      */
     public function rename($bucket, $oldname, $newname)
     {
@@ -714,13 +610,13 @@ public function rename($bucket, $oldname, $newname)
     /**
      * 对资源进行复制。
      *
-     * @param $from_bucket     待操作资源所在空间
-     * @param $from_key        待操作资源文件名
-     * @param $to_bucket       目标资源空间名
-     * @param $to_key          目标资源文件名
+     * @param string $from_bucket 待操作资源所在空间
+     * @param string $from_key 待操作资源文件名
+     * @param string $to_bucket 目标资源空间名
+     * @param string $to_key 目标资源文件名
      *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
-     * @link  http://developer.qiniu.com/docs/v6/api/reference/rs/copy.html
+     * @return array
+     * @link  https://developer.qiniu.com/kodo/api/1254/copy
      */
     public function copy($from_bucket, $from_key, $to_bucket, $to_key, $force = false)
     {
@@ -730,20 +626,19 @@ public function copy($from_bucket, $from_key, $to_bucket, $to_key, $force = fals
         if ($force === true) {
             $path .= '/force/true';
         }
-        list(, $error) = $this->rsPost($path);
-        return $error;
+        return $this->rsPost($path);
     }
 
     /**
      * 将资源从一个空间到另一个空间
      *
-     * @param $from_bucket     待操作资源所在空间
-     * @param $from_key        待操作资源文件名
-     * @param $to_bucket       目标资源空间名
-     * @param $to_key          目标资源文件名
+     * @param string $from_bucket 待操作资源所在空间
+     * @param string $from_key 待操作资源文件名
+     * @param string $to_bucket 目标资源空间名
+     * @param string $to_key 目标资源文件名
      *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
-     * @link  http://developer.qiniu.com/docs/v6/api/reference/rs/move.html
+     * @return array
+     * @link  https://developer.qiniu.com/kodo/api/1288/move
      */
     public function move($from_bucket, $from_key, $to_bucket, $to_key, $force = false)
     {
@@ -753,87 +648,71 @@ public function move($from_bucket, $from_key, $to_bucket, $to_key, $force = fals
         if ($force) {
             $path .= '/force/true';
         }
-        list(, $error) = $this->rsPost($path);
-        return $error;
+        return $this->rsPost($path);
     }
 
     /**
      * 主动修改指定资源的文件元信息
      *
-     * @param $bucket     待操作资源所在空间
-     * @param $key        待操作资源文件名
-     * @param $mime       待操作文件目标mimeType
+     * @param string $bucket 待操作资源所在空间
+     * @param string $key 待操作资源文件名
+     * @param string $mime 待操作文件目标mimeType
      *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
-     * @link  http://developer.qiniu.com/docs/v6/api/reference/rs/chgm.html
+     * @return array
+     * @link  https://developer.qiniu.com/kodo/api/1252/chgm
      */
     public function changeMime($bucket, $key, $mime)
     {
         $resource = \Qiniu\entry($bucket, $key);
         $encode_mime = \Qiniu\base64_urlSafeEncode($mime);
         $path = '/chgm/' . $resource . '/mime/' . $encode_mime;
-        list(, $error) = $this->rsPost($path);
-        return $error;
+        return $this->rsPost($path);
     }
 
 
     /**
      * 修改指定资源的存储类型
      *
-     * @param $bucket     待操作资源所在空间
-     * @param $key        待操作资源文件名
-     * @param $fileType       待操作文件目标文件类型
+     * @param string $bucket 待操作资源所在空间
+     * @param string $key 待操作资源文件名
+     * @param int $fileType 0 表示标准存储;1 表示低频存储;2 表示归档存储
      *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
-     * @link  https://developer.qiniu.com/kodo/api/3710/modify-the-file-type
+     * @return array
+     * @link  https://developer.qiniu.com/kodo/api/3710/chtype
      */
     public function changeType($bucket, $key, $fileType)
     {
         $resource = \Qiniu\entry($bucket, $key);
         $path = '/chtype/' . $resource . '/type/' . $fileType;
-        list(, $error) = $this->rsPost($path);
-        return $error;
+        return $this->rsPost($path);
     }
 
     /**
      * 修改文件的存储状态,即禁用状态和启用状态间的的互相转换
      *
-     * @param $bucket     待操作资源所在空间
-     * @param $key        待操作资源文件名
-     * @param $status       待操作文件目标文件类型
+     * @param string $bucket 待操作资源所在空间
+     * @param string $key 待操作资源文件名
+     * @param int $status 0表示启用;1表示禁用
      *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
+     * @return array
      * @link  https://developer.qiniu.com/kodo/api/4173/modify-the-file-status
      */
     public function changeStatus($bucket, $key, $status)
     {
         $resource = \Qiniu\entry($bucket, $key);
         $path = '/chstatus/' . $resource . '/status/' . $status;
-        list(, $error) = $this->rsPost($path);
-        return $error;
+        return $this->rsPost($path);
     }
 
     /**
      * 从指定URL抓取资源,并将该资源存储到指定空间中
      *
-     * @param $url        指定的URL
-     * @param $bucket     目标资源空间
-     * @param $key        目标资源文件名
-     *
-     * @return array    包含已拉取的文件信息。
-     *                         成功时:  [
-     *                                          [
-     *                                              "hash" => "",
-     *                                              "key" => ""
-     *                                          ],
-     *                                          null
-     *                                  ]
+     * @param string $url 指定的URL
+     * @param string $bucket 目标资源空间
+     * @param string $key 目标资源文件名
      *
-     *                         失败时:  [
-     *                                          null,
-     *                                         Qiniu/Http/Error
-     *                                  ]
-     * @link  http://developer.qiniu.com/docs/v6/api/reference/rs/fetch.html
+     * @return array
+     * @link  https://developer.qiniu.com/kodo/api/1263/fetch
      */
     public function fetch($url, $bucket, $key = null)
     {
@@ -849,14 +728,97 @@ public function fetch($url, $bucket, $key = null)
         return $this->post($url, null);
     }
 
+    /**
+     * 从指定URL异步抓取资源,并将该资源存储到指定空间中
+     *
+     * @param string $url 需要抓取的url
+     * @param string $bucket 所在区域的bucket
+     * @param string $host 从指定url下载数据时使用的Host
+     * @param string $key 文件存储的key
+     * @param string $md5 文件md5
+     * @param string $etag 文件etag
+     * @param string $callbackurl 回调URL
+     * @param string $callbackbody 回调Body
+     * @param string $callbackbodytype 回调Body内容类型,默认为"application/x-www-form-urlencoded"
+     * @param string $callbackhost 回调时使用的Host
+     * @param int $file_type 存储文件类型 0:标准存储(默认),1:低频存储,2:归档存储
+     * @param bool $ignore_same_key 如果空间中已经存在同名文件则放弃本次抓取
+     * @return array
+     * @link  https://developer.qiniu.com/kodo/api/4097/asynch-fetch
+     */
+    public function asynchFetch(
+        $url,
+        $bucket,
+        $host = null,
+        $key = null,
+        $md5 = null,
+        $etag = null,
+        $callbackurl = null,
+        $callbackbody = null,
+        $callbackbodytype = 'application/x-www-form-urlencoded',
+        $callbackhost = null,
+        $file_type = 0,
+        $ignore_same_key = false
+    ) {
+        $path = '/sisyphus/fetch';
+
+        $params = array('url' => $url, 'bucket' => $bucket);
+        \Qiniu\setWithoutEmpty($params, 'host', $host);
+        \Qiniu\setWithoutEmpty($params, 'key', $key);
+        \Qiniu\setWithoutEmpty($params, 'md5', $md5);
+        \Qiniu\setWithoutEmpty($params, 'etag', $etag);
+        \Qiniu\setWithoutEmpty($params, 'callbackurl', $callbackurl);
+        \Qiniu\setWithoutEmpty($params, 'callbackbody', $callbackbody);
+        \Qiniu\setWithoutEmpty($params, 'callbackbodytype', $callbackbodytype);
+        \Qiniu\setWithoutEmpty($params, 'callbackhost', $callbackhost);
+        \Qiniu\setWithoutEmpty($params, 'file_type', $file_type);
+        \Qiniu\setWithoutEmpty($params, 'ignore_same_key', $ignore_same_key);
+        $data = json_encode($params);
+
+        $ak = $this->auth->getAccessKey();
+        $apiHost = $this->config->getApiHost($ak, $bucket);
+        $url = $apiHost . $path;
+
+        return $this->postV2($url, $data);
+    }
+
+
+    /**
+     * 查询异步第三方资源抓取任务状态
+     *
+     * @param string $zone
+     * @param string $id
+     * @return array
+     * @link  https://developer.qiniu.com/kodo/api/4097/asynch-fetch
+     */
+    public function asynchFetchStatus($zone, $id)
+    {
+        $scheme = "http://";
+
+        if ($this->config->useHTTPS === true) {
+            $scheme = "https://";
+        }
+
+        $url = $scheme . "api-" . $zone . ".qiniu.com/sisyphus/fetch?id=" . $id;
+
+        $response = $this->getV2($url);
+
+        if (!$response->ok()) {
+            print("statusCode: " . $response->statusCode);
+            return array(null, new Error($url, $response));
+        }
+        return array($response->json(), null);
+    }
+
+
     /**
      * 从镜像源站抓取资源到空间中,如果空间中已经存在,则覆盖该资源
      *
-     * @param $bucket     待获取资源所在的空间
-     * @param $key        代获取资源文件名
+     * @param string $bucket 待获取资源所在的空间
+     * @param string $key 代获取资源文件名
      *
-     * @return mixed      成功返回NULL,失败返回对象Qiniu\Http\Error
-     * @link  http://developer.qiniu.com/docs/v6/api/reference/rs/prefetch.html
+     * @return array
+     * @link  https://developer.qiniu.com/kodo/api/1293/prefetch
      */
     public function prefetch($bucket, $key)
     {
@@ -867,14 +829,13 @@ public function prefetch($bucket, $key)
         $ioHost = $this->config->getIovipHost($ak, $bucket);
 
         $url = $ioHost . $path;
-        list(, $error) = $this->post($url, null);
-        return $error;
+        return $this->post($url, null);
     }
 
     /**
      * 在单次请求中进行多个资源管理操作
      *
-     * @param $operations     资源管理操作数组
+     * @param array $operations 资源管理操作数组
      *
      * @return array 每个资源的处理情况,结果类似:
      *              [
@@ -896,25 +857,24 @@ public function batch($operations)
     /**
      * 设置文件的生命周期
      *
-     * @param $bucket 设置文件生命周期文件所在的空间
-     * @param $key    设置文件生命周期文件的文件名
-     * @param $days   设置该文件多少天后删除,当$days设置为0时表示取消该文件的生命周期
+     * @param string $bucket 设置文件生命周期文件所在的空间
+     * @param string $key 设置文件生命周期文件的文件名
+     * @param int $days 设置该文件多少天后删除,当$days设置为0时表示取消该文件的生命周期
      *
-     * @return Mixed
+     * @return array
      * @link https://developer.qiniu.com/kodo/api/update-file-lifecycle
      */
     public function deleteAfterDays($bucket, $key, $days)
     {
         $entry = \Qiniu\entry($bucket, $key);
         $path = "/deleteAfterDays/$entry/$days";
-        list(, $error) = $this->rsPost($path);
-        return $error;
+        return $this->rsPost($path);
     }
 
     private function getRsfHost()
     {
         $scheme = "http://";
-        if ($this->config->useHTTPS == true) {
+        if ($this->config->useHTTPS === true) {
             $scheme = "https://";
         }
         return $scheme . Config::RSF_HOST;
@@ -923,7 +883,7 @@ private function getRsfHost()
     private function getRsHost()
     {
         $scheme = "http://";
-        if ($this->config->useHTTPS == true) {
+        if ($this->config->useHTTPS === true) {
             $scheme = "https://";
         }
         return $scheme . Config::RS_HOST;
@@ -932,7 +892,7 @@ private function getRsHost()
     private function getApiHost()
     {
         $scheme = "http://";
-        if ($this->config->useHTTPS == true) {
+        if ($this->config->useHTTPS === true) {
             $scheme = "https://";
         }
         return $scheme . Config::API_HOST;
@@ -941,7 +901,7 @@ private function getApiHost()
     private function getUcHost()
     {
         $scheme = "http://";
-        if ($this->config->useHTTPS == true) {
+        if ($this->config->useHTTPS === true) {
             $scheme = "https://";
         }
         return $scheme . Config::UC_HOST;
@@ -993,6 +953,12 @@ private function get($url)
         return array($ret->json(), null);
     }
 
+    private function getV2($url)
+    {
+        $headers = $this->auth->authorizationV2($url, 'GET');
+        return Client::get($url, $headers);
+    }
+
     private function post($url, $body)
     {
         $headers = $this->auth->authorization($url, $body, 'application/x-www-form-urlencoded');
@@ -1004,12 +970,6 @@ private function post($url, $body)
         return array($r, null);
     }
 
-    private function ucPostV2($path, $body)
-    {
-        $url = $this->getUcHost() . $path;
-        return $this->postV2($url, $body);
-    }
-
     private function postV2($url, $body)
     {
         $headers = $this->auth->authorizationV2($url, 'POST', $body, 'application/json');
diff --git a/vendor/qiniu/php-sdk/src/Qiniu/Storage/FormUploader.php b/vendor/qiniu/php-sdk/src/Qiniu/Storage/FormUploader.php
index d87756a02..1267004e5 100644
--- a/vendor/qiniu/php-sdk/src/Qiniu/Storage/FormUploader.php
+++ b/vendor/qiniu/php-sdk/src/Qiniu/Storage/FormUploader.php
@@ -1,8 +1,9 @@
 key = $key;
         $this->key2 = $key2;
 
+        global $customCallbackURL;
+        $this->customCallbackURL = $customCallbackURL;
+
         global $testAuth;
-        $this->bucketManager = new BucketManager($testAuth);
+        $config = new Config();
+        $this->bucketManager = new BucketManager($testAuth, $config);
 
         global $dummyAuth;
         $this->dummyBucketManager = new BucketManager($dummyAuth);
@@ -38,6 +45,49 @@ public function testBuckets()
         $this->assertEquals(401, $error->code());
         $this->assertNull($list2);
         $this->assertNotNull($error->message());
+        $this->assertNotNull($error->getResponse());
+    }
+
+    public function testListbuckets()
+    {
+        list($ret, $error) = $this->bucketManager->listbuckets('z0');
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
+    }
+
+    public function testCreateBucket()
+    {
+        list($ret, $error) = $this->bucketManager->createBucket('phpsdk-ci-test');
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
+    }
+
+    public function testDeleteBucket()
+    {
+        list($ret, $error) = $this->bucketManager->deleteBucket('phpsdk-ci-test');
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
+    }
+
+    public function testDomains()
+    {
+        list($ret, $error) = $this->bucketManager->domains($this->bucketName);
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
+    }
+
+    public function testBucketInfo()
+    {
+        list($ret, $error) = $this->bucketManager->bucketInfo($this->bucketName);
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
+    }
+
+    public function testBucketInfos()
+    {
+        list($ret, $error) = $this->bucketManager->bucketInfos('z0');
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
     }
 
     public function testList()
@@ -45,6 +95,90 @@ public function testList()
         list($ret, $error) = $this->bucketManager->listFiles($this->bucketName, null, null, 10);
         $this->assertNotNull($ret['items'][0]);
         $this->assertNotNull($ret['marker']);
+        $this->assertNull($error);
+    }
+
+    public function testListFilesv2()
+    {
+        list($ret, $error) = $this->bucketManager->listFilesv2($this->bucketName, null, null, 10);
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
+    }
+
+    public function testBucketLifecycleRule()
+    {
+        list($ret, $error) = $this->bucketManager->bucketLifecycleRule($this->bucketName, 'demo', 'test', 80, 70);
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
+    }
+
+    public function testGetbucketLifecycleRule()
+    {
+        list($ret, $error) = $this->bucketManager->getBucketLifecycleRules($this->bucketName);
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
+    }
+
+    public function testUpdatebucketLifecycleRule()
+    {
+        list($ret, $error) = $this->bucketManager->updateBucketLifecycleRule(
+            $this->bucketName,
+            'demo',
+            'testupdate',
+            80,
+            70
+        );
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
+    }
+
+    public function testDeleteBucketLifecycleRule()
+    {
+        list($ret, $error) = $this->bucketManager->deleteBucketLifecycleRule($this->bucketName, 'demo');
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
+    }
+
+    public function testPutBucketEvent()
+    {
+        list($ret, $error) = $this->bucketManager->putBucketEvent(
+            $this->bucketName,
+            'bucketevent',
+            'test',
+            'img',
+            array('copy'),
+            $this->customCallbackURL
+        );
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
+    }
+
+    public function testUpdateBucketEvent()
+    {
+        list($ret, $error) = $this->bucketManager->updateBucketEvent(
+            $this->bucketName,
+            'bucketevent',
+            'test',
+            'video',
+            array('copy'),
+            $this->customCallbackURL
+        );
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
+    }
+
+    public function testGetBucketEvent()
+    {
+        list($ret, $error) = $this->bucketManager->getBucketEvents($this->bucketName);
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
+    }
+
+    public function testDeleteBucketEvent()
+    {
+        list($ret, $error) = $this->bucketManager->deleteBucketEvent($this->bucketName, 'bucketevent');
+        $this->assertNotNull($ret);
+        $this->assertNull($error);
     }
 
     public function testStat()
@@ -67,8 +201,9 @@ public function testStat()
 
     public function testDelete()
     {
-        $error = $this->bucketManager->delete($this->bucketName, 'del');
-        $this->assertEquals(612, $error->code());
+        list($ret, $error) = $this->bucketManager->delete($this->bucketName, 'del');
+        $this->assertNull($ret);
+        $this->assertNotNull($error);
     }
 
 
@@ -77,9 +212,9 @@ public function testRename()
         $key = 'renamefrom' . rand();
         $this->bucketManager->copy($this->bucketName, $this->key, $this->bucketName, $key);
         $key2 = 'renameto' . $key;
-        $error = $this->bucketManager->rename($this->bucketName, $key, $key2);
+        list($ret, $error) = $this->bucketManager->rename($this->bucketName, $key, $key2);
         $this->assertNull($error);
-        $error = $this->bucketManager->delete($this->bucketName, $key2);
+        list($ret, $error) = $this->bucketManager->delete($this->bucketName, $key2);
         $this->assertNull($error);
     }
 
@@ -89,7 +224,7 @@ public function testCopy()
         $key = 'copyto' . rand();
         $this->bucketManager->delete($this->bucketName, $key);
 
-        $error = $this->bucketManager->copy(
+        list($ret, $error) = $this->bucketManager->copy(
             $this->bucketName,
             $this->key,
             $this->bucketName,
@@ -98,7 +233,7 @@ public function testCopy()
         $this->assertNull($error);
 
         //test force copy
-        $error = $this->bucketManager->copy(
+        list($ret, $error) = $this->bucketManager->copy(
             $this->bucketName,
             $this->key2,
             $this->bucketName,
@@ -112,14 +247,14 @@ public function testCopy()
 
         $this->assertEquals($key2Stat['hash'], $key2CopiedStat['hash']);
 
-        $error = $this->bucketManager->delete($this->bucketName, $key);
+        list($ret, $error) = $this->bucketManager->delete($this->bucketName, $key);
         $this->assertNull($error);
     }
 
 
     public function testChangeMime()
     {
-        $error = $this->bucketManager->changeMime(
+        list($ret, $error) = $this->bucketManager->changeMime(
             $this->bucketName,
             'php-sdk.html',
             'text/html'
@@ -129,7 +264,7 @@ public function testChangeMime()
 
     public function testPrefetch()
     {
-        $error = $this->bucketManager->prefetch(
+        list($ret, $error) = $this->bucketManager->prefetch(
             $this->bucketName,
             'php-sdk.html'
         );
@@ -162,6 +297,35 @@ public function testFetch()
         $this->assertNull($error);
     }
 
+    public function testAsynchFetch()
+    {
+        list($ret, $error) = $this->bucketManager->asynchFetch(
+            'http://devtools.qiniu.com/qiniu.png',
+            $this->bucketName,
+            null,
+            'qiniu.png'
+        );
+        $this->assertArrayHasKey('id', $ret);
+        $this->assertNull($error);
+
+        list($ret, $error) = $this->bucketManager->asynchFetch(
+            'http://devtools.qiniu.com/qiniu.png',
+            $this->bucketName,
+            null,
+            ''
+        );
+        $this->assertArrayHasKey('id', $ret);
+        $this->assertNull($error);
+
+        list($ret, $error) = $this->bucketManager->asynchFetch(
+            'http://devtools.qiniu.com/qiniu.png',
+            $this->bucketName
+        );
+        $this->assertArrayHasKey('id', $ret);
+        $this->assertNull($error);
+    }
+
+
     public function testBatchCopy()
     {
         $key = 'copyto' . rand();
@@ -191,7 +355,7 @@ public function testBatchMove()
         );
         list($ret, $error) = $this->bucketManager->batch($ops);
         $this->assertEquals(200, $ret[0]['code']);
-        $error = $this->bucketManager->delete($this->bucketName, $key2);
+        list($ret, $error) = $this->bucketManager->delete($this->bucketName, $key2);
         $this->assertNull($error);
     }
 
@@ -203,7 +367,7 @@ public function testBatchRename()
         $ops = BucketManager::buildBatchRename($this->bucketName, array($key => $key2), true);
         list($ret, $error) = $this->bucketManager->batch($ops);
         $this->assertEquals(200, $ret[0]['code']);
-        $error = $this->bucketManager->delete($this->bucketName, $key2);
+        list($ret, $error) = $this->bucketManager->delete($this->bucketName, $key2);
         $this->assertNull($error);
     }
 
@@ -217,11 +381,71 @@ public function testBatchStat()
     public function testDeleteAfterDays()
     {
         $key = rand();
-        $err = $this->bucketManager->deleteAfterDays($this->bucketName, $key, 1);
-        $this->assertEquals(612, $err->code());
+        list($ret, $error) = $this->bucketManager->deleteAfterDays($this->bucketName, $key, 1);
+        $this->assertNotNull($error);
 
         $this->bucketManager->copy($this->bucketName, $this->key, $this->bucketName, $key);
-        $err = $this->bucketManager->deleteAfterDays($this->bucketName, $key, 1);
-        $this->assertEquals(null, $err);
+        list($ret, $error) = $this->bucketManager->deleteAfterDays($this->bucketName, $key, 1);
+        $this->assertEquals(null, $ret);
+    }
+
+    public function testGetCorsRules()
+    {
+        list($ret, $err) = $this->bucketManager->getCorsRules($this->bucketName);
+        $this->assertNull($err);
+    }
+
+    public function testPutBucketAccessStyleMode()
+    {
+        list($ret, $err) = $this->bucketManager->putBucketAccessStyleMode($this->bucketName, 0);
+        $this->assertNull($err);
+    }
+
+    public function testPutBucketAccessMode()
+    {
+        list($ret, $err) = $this->bucketManager->putBucketAccessMode($this->bucketName, 0);
+        $this->assertNull($err);
+    }
+
+    public function testPutReferAntiLeech()
+    {
+        list($ret, $err) = $this->bucketManager->putReferAntiLeech($this->bucketName, 0, "1", "*");
+        $this->assertNull($err);
+    }
+
+    public function testPutBucketMaxAge()
+    {
+        list($ret, $err) = $this->bucketManager->putBucketMaxAge($this->bucketName, 31536000);
+        $this->assertNull($err);
+    }
+
+    public function testPutBucketQuota()
+    {
+        list($ret, $err) = $this->bucketManager->putBucketQuota($this->bucketName, -1, -1);
+        $this->assertNull($err);
+    }
+
+    public function testGetBucketQuota()
+    {
+        list($ret, $err) = $this->bucketManager->getBucketQuota($this->bucketName);
+        $this->assertNull($err);
+    }
+
+    public function testChangeType()
+    {
+        list($ret, $err) = $this->bucketManager->changeType($this->bucketName, $this->key, 0);
+        $this->assertNull($err);
+
+        list($ret, $err) = $this->bucketManager->changeType($this->bucketName, $this->key, 1);
+        $this->assertNull($err);
+    }
+
+    public function testChangeStatus()
+    {
+        list($ret, $err) = $this->bucketManager->changeStatus($this->bucketName, $this->key, 1);
+        $this->assertNull($err);
+
+        list($ret, $err) = $this->bucketManager->changeStatus($this->bucketName, $this->key, 0);
+        $this->assertNull($err);
     }
 }
diff --git a/vendor/qiniu/php-sdk/tests/Qiniu/Tests/CdnManagerTest.php b/vendor/qiniu/php-sdk/tests/Qiniu/Tests/CdnManagerTest.php
index 892197da7..1a12704b6 100755
--- a/vendor/qiniu/php-sdk/tests/Qiniu/Tests/CdnManagerTest.php
+++ b/vendor/qiniu/php-sdk/tests/Qiniu/Tests/CdnManagerTest.php
@@ -15,26 +15,130 @@ class CdnManagerTest extends \PHPUnit_Framework_TestCase
 {
     protected $cdnManager;
     protected $encryptKey;
-    protected $imgUrl;
+    protected $testStartDate;
+    protected $testEndDate;
+    protected $testGranularity;
+    protected $testLogDate;
+    protected $refreshUrl;
+    protected $refreshDirs;
+    protected $customDomain;
+    protected $customDomain2;
 
     protected function setUp()
     {
-        global $timestampAntiLeechEncryptKey;
-        global $customDomain;
         global $testAuth;
-
         $this->cdnManager = new CdnManager($testAuth);
+
+        global $timestampAntiLeechEncryptKey;
         $this->encryptKey = $timestampAntiLeechEncryptKey;
-        $this->imgUrl = $customDomain . '/sdktest.png';
+
+        global $testStartDate;
+        $this->testStartDate = $testStartDate;
+
+        global $testEndDate;
+        $this->testEndDate = $testEndDate;
+
+        global $testGranularity;
+        $this->testGranularity = $testGranularity;
+
+        global $testLogDate;
+        $this->testLogDate = $testLogDate;
+
+        global $customDomain;
+        $this->refreshUrl = $customDomain . '/sdktest.png';
+        $this->refreshDirs = $customDomain;
+        $this->customDomain = $customDomain;
+
+        global $customDomain2;
+        $this->customDomain2 = $customDomain2;
     }
 
-    public function testCreateTimestampAntiLeechUrl()
+    public function testRefreshUrls()
+    {
+        list($ret, $err) = $this->cdnManager->refreshUrls(array($this->refreshUrl));
+        $this->assertNotNull($ret);
+        $this->assertNull($err);
+    }
+
+    public function testRefreshDirs()
     {
+        list($ret, $err) = $this->cdnManager->refreshDirs(array($this->refreshDirs));
+        $this->assertNotNull($ret);
+        $this->assertNull($err);
+    }
 
-        $signUrl = $this->cdnManager->createTimestampAntiLeechUrl($this->imgUrl, $this->encryptKey, 3600);
+    public function testRefreshUrlsAndDirs()
+    {
+        list($ret, $err) = $this->cdnManager->refreshUrlsAndDirs(array($this->refreshUrl), array($this->refreshDirs));
+        $this->assertNotNull($ret);
+        $this->assertNull($err);
+    }
+
+    public function testGetCdnRefreshList()
+    {
+        list($ret, $err) = $this->cdnManager->getCdnRefreshList(null, null, null, 'success');
+        $this->assertNotNull($ret);
+        $this->assertNull($err);
+    }
+
+    public function testPrefetchUrls()
+    {
+        list($ret, $err) = $this->cdnManager->prefetchUrls(array($this->refreshUrl));
+        $this->assertNotNull($ret);
+        $this->assertNull($err);
+    }
+
+    public function testGetCdnPrefetchList()
+    {
+        list($ret, $err) = $this->cdnManager->getCdnPrefetchList(null, null, 'success');
+        $this->assertNotNull($ret);
+        $this->assertNull($err);
+    }
+
+    public function testGetBandwidthData()
+    {
+        list($ret, $err) = $this->cdnManager->getBandwidthData(
+            array($this->customDomain2),
+            $this->testStartDate,
+            $this->testEndDate,
+            $this->testGranularity
+        );
+        $this->assertNotNull($ret);
+        $this->assertNull($err);
+    }
+
+    public function testGetFluxData()
+    {
+        list($ret, $err) = $this->cdnManager->getFluxData(
+            array($this->customDomain2),
+            $this->testStartDate,
+            $this->testEndDate,
+            $this->testGranularity
+        );
+        $this->assertNotNull($ret);
+        $this->assertNull($err);
+    }
+
+    public function testGetCdnLogList()
+    {
+        list($ret, $err) = $this->cdnManager->getCdnLogList(array('fake.qiniu.com'), $this->testLogDate);
+        $this->assertNull($ret);
+        $this->assertNotNull($err);
+    }
+
+    public function testCreateTimestampAntiLeechUrl()
+    {
+        $signUrl = $this->cdnManager->createTimestampAntiLeechUrl($this->refreshUrl, $this->encryptKey, 3600);
+        $response = Client::get($signUrl);
+        $this->assertEquals($response->statusCode, 200);
+        $this->assertNull($response->error);
 
+        $signUrl = $this->cdnManager->createTimestampAntiLeechUrl(
+            $this->refreshUrl . '?qiniu',
+            $this->encryptKey,
+            3600
+        );
         $response = Client::get($signUrl);
-        
         $this->assertEquals($response->statusCode, 200);
         $this->assertNull($response->error);
     }
diff --git a/vendor/qiniu/php-sdk/tests/Qiniu/Tests/HttpTest.php b/vendor/qiniu/php-sdk/tests/Qiniu/Tests/HttpTest.php
index e2ab5fc6d..558bc1f11 100755
--- a/vendor/qiniu/php-sdk/tests/Qiniu/Tests/HttpTest.php
+++ b/vendor/qiniu/php-sdk/tests/Qiniu/Tests/HttpTest.php
@@ -7,7 +7,7 @@ class HttpTest extends \PHPUnit_Framework_TestCase
 {
     public function testGet()
     {
-        $response = Client::get('baidu.com');
+        $response = Client::get('qiniu.com');
         $this->assertEquals($response->statusCode, 200);
         $this->assertNotNull($response->body);
         $this->assertNull($response->error);
@@ -15,7 +15,7 @@ public function testGet()
 
     public function testGetQiniu()
     {
-        $response = Client::get('up.qiniu.com');
+        $response = Client::get('upload.qiniu.com');
         $this->assertEquals(405, $response->statusCode);
         $this->assertNotNull($response->body);
         $this->assertNotNull($response->xReqId());
@@ -23,9 +23,27 @@ public function testGetQiniu()
         $this->assertNotNull($response->error);
     }
 
+    public function testDelete()
+    {
+        $response = Client::delete('uc.qbox.me/bucketTagging', array());
+        $this->assertEquals($response->statusCode, 401);
+        $this->assertNotNull($response->body);
+        $this->assertNotNull($response->error);
+    }
+
+    public function testDeleteQiniu()
+    {
+        $response = Client::delete('uc.qbox.me/bucketTagging', array());
+        $this->assertEquals(401, $response->statusCode);
+        $this->assertNotNull($response->body);
+        $this->assertNotNull($response->xReqId());
+        $this->assertNotNull($response->xLog());
+        $this->assertNotNull($response->error);
+    }
+
     public function testPost()
     {
-        $response = Client::post('baidu.com', null);
+        $response = Client::post('qiniu.com', null);
         $this->assertEquals($response->statusCode, 200);
         $this->assertNotNull($response->body);
         $this->assertNull($response->error);
@@ -33,11 +51,29 @@ public function testPost()
 
     public function testPostQiniu()
     {
-        $response = Client::post('up.qiniu.com', null);
+        $response = Client::post('upload.qiniu.com', null);
         $this->assertEquals($response->statusCode, 400);
         $this->assertNotNull($response->body);
         $this->assertNotNull($response->xReqId());
         $this->assertNotNull($response->xLog());
         $this->assertNotNull($response->error);
     }
+
+    public function testPut()
+    {
+        $response = Client::PUT('uc.qbox.me/bucketTagging', null);
+        $this->assertEquals($response->statusCode, 401);
+        $this->assertNotNull($response->body);
+        $this->assertNotNull($response->error);
+    }
+
+    public function testPutQiniu()
+    {
+        $response = Client::put('uc.qbox.me/bucketTagging', null);
+        $this->assertEquals(401, $response->statusCode);
+        $this->assertNotNull($response->body);
+        $this->assertNotNull($response->xReqId());
+        $this->assertNotNull($response->xLog());
+        $this->assertNotNull($response->error);
+    }
 }
diff --git a/vendor/qiniu/php-sdk/tests/Qiniu/Tests/ResumeUpTest.php b/vendor/qiniu/php-sdk/tests/Qiniu/Tests/ResumeUpTest.php
index 41e6ea8ab..a648d88d3 100755
--- a/vendor/qiniu/php-sdk/tests/Qiniu/Tests/ResumeUpTest.php
+++ b/vendor/qiniu/php-sdk/tests/Qiniu/Tests/ResumeUpTest.php
@@ -35,7 +35,7 @@ public function test4ML()
     public function test4ML2()
     {
         $key = 'resumePutFile4ML';
-        $zone = new Zone(array('up.fake.qiniu.com'), array('up.qiniup.com'));
+        $zone = new Zone(array('upload.fake.qiniu.com'), array('upload.qiniup.com'));
         $cfg = new Config($zone);
         $upManager = new UploadManager($cfg);
         $token = $this->auth->uploadToken($this->bucketName, $key);
diff --git a/vendor/qiniu/php-sdk/tests/Qiniu/Tests/ZoneTest.php b/vendor/qiniu/php-sdk/tests/Qiniu/Tests/ZoneTest.php
index d32875bd2..cc5cce507 100755
--- a/vendor/qiniu/php-sdk/tests/Qiniu/Tests/ZoneTest.php
+++ b/vendor/qiniu/php-sdk/tests/Qiniu/Tests/ZoneTest.php
@@ -13,6 +13,8 @@ class ZoneTest extends \PHPUnit_Framework_TestCase
     protected $bucketName;
     protected $bucketNameBC;
     protected $bucketNameNA;
+    protected $bucketNameFS;
+    protected $bucketNameAS;
 
 
     protected function setUp()
@@ -26,6 +28,12 @@ protected function setUp()
         global $bucketNameNA;
         $this->bucketNameNA = $bucketNameNA;
 
+        global $bucketNameFS;
+        $this->bucketNameFS = $bucketNameFS;
+
+        global $bucketNameAS;
+        $this->bucketNameAS = $bucketNameAS;
+
         global $accessKey;
         $this->ak = $accessKey;
 
@@ -35,14 +43,24 @@ protected function setUp()
 
     public function testUpHosts()
     {
+        list($ret, $err) = Zone::queryZone($this->ak, 'fakebucket');
+        $this->assertNull($ret);
+        $this->assertNotNull($err);
+
         $zone = Zone::queryZone($this->ak, $this->bucketName);
         $this->assertContains('upload.qiniup.com', $zone->cdnUpHosts);
 
         $zone = Zone::queryZone($this->ak, $this->bucketNameBC);
         $this->assertContains('upload-z1.qiniup.com', $zone->cdnUpHosts);
 
+        $zone = Zone::queryZone($this->ak, $this->bucketNameFS);
+        $this->assertContains('upload-z2.qiniup.com', $zone->cdnUpHosts);
+
         $zone = Zone::queryZone($this->ak, $this->bucketNameNA);
         $this->assertContains('upload-na0.qiniup.com', $zone->cdnUpHosts);
+
+        $zone = Zone::queryZone($this->ak, $this->bucketNameAS);
+        $this->assertContains('upload-as0.qiniup.com', $zone->cdnUpHosts);
     }
 
     public function testIoHosts()
@@ -53,7 +71,55 @@ public function testIoHosts()
         $zone = Zone::queryZone($this->ak, $this->bucketNameBC);
         $this->assertEquals($zone->iovipHost, 'iovip-z1.qbox.me');
 
+        $zone = Zone::queryZone($this->ak, $this->bucketNameFS);
+        $this->assertEquals($zone->iovipHost, 'iovip-z2.qbox.me');
+
         $zone = Zone::queryZone($this->ak, $this->bucketNameNA);
         $this->assertEquals($zone->iovipHost, 'iovip-na0.qbox.me');
+
+        $zone = Zone::queryZone($this->ak, $this->bucketNameAS);
+        $this->assertEquals($zone->iovipHost, 'iovip-as0.qbox.me');
+    }
+
+    public function testZonez0()
+    {
+        $zone = Zone::zonez0();
+        $this->assertContains('upload.qiniup.com', $zone->cdnUpHosts);
+    }
+
+    public function testZonez1()
+    {
+        $zone = Zone::zonez1();
+        $this->assertContains('upload-z1.qiniup.com', $zone->cdnUpHosts);
+    }
+
+    public function testZonez2()
+    {
+        $zone = Zone::zonez2();
+        $this->assertContains('upload-z2.qiniup.com', $zone->cdnUpHosts);
+    }
+
+    public function testZoneNa0()
+    {
+        $zone = Zone::zoneNa0();
+        $this->assertContains('upload-na0.qiniup.com', $zone->cdnUpHosts);
+    }
+
+    public function testZoneAs0()
+    {
+        $zone = Zone::zoneAs0();
+        $this->assertContains('upload-as0.qiniup.com', $zone->cdnUpHosts);
+    }
+
+    public function testQvmZonez0()
+    {
+        $zone = Zone::qvmZonez0();
+        $this->assertContains('free-qvm-z0-xs.qiniup.com', $zone->srcUpHosts);
+    }
+
+    public function testQvmZonez1()
+    {
+        $zone = Zone::qvmZonez1();
+        $this->assertContains('free-qvm-z1-zz.qiniup.com', $zone->srcUpHosts);
     }
 }
diff --git a/vendor/qiniu/php-sdk/tests/bootstrap.php b/vendor/qiniu/php-sdk/tests/bootstrap.php
index 5cbce3570..aa3776a0b 100755
--- a/vendor/qiniu/php-sdk/tests/bootstrap.php
+++ b/vendor/qiniu/php-sdk/tests/bootstrap.php
@@ -12,8 +12,15 @@
 $key = 'php-logo.png';
 $key2 = 'niu.jpg';
 
+$testStartDate = '2020-08-18';
+$testEndDate = '2020-08-19';
+$testGranularity = 'day';
+$testLogDate = '2020-08-18';
+
 $bucketNameBC = 'phpsdk-bc';
 $bucketNameNA = 'phpsdk-na';
+$bucketNameFS = 'phpsdk-fs';
+$bucketNameAS = 'phpsdk-as';
 
 $dummyAccessKey = 'abcdefghklmnopq';
 $dummySecretKey = '1234567890';
@@ -22,6 +29,8 @@
 //cdn
 $timestampAntiLeechEncryptKey = getenv('QINIU_TIMESTAMP_ENCRPTKEY');
 $customDomain = "http://sdk.peterpy.cn";
+$customDomain2 = "sdk.peterpy.cn";
+$customCallbackURL = "https://qiniu.timhbw.com/notify/callback";
 
 $tid = getenv('TRAVIS_JOB_NUMBER');
 if (!empty($tid)) {
diff --git a/vendor/symfony/polyfill-intl-idn/Idn.php b/vendor/symfony/polyfill-intl-idn/Idn.php
index f54ffd535..fee3026df 100644
--- a/vendor/symfony/polyfill-intl-idn/Idn.php
+++ b/vendor/symfony/polyfill-intl-idn/Idn.php
@@ -1,184 +1,736 @@
  and Trevor Rowbotham 
  *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * Originally forked from
- * https://github.com/true/php-punycode/blob/v2.1.1/src/Punycode.php
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
  */
 
 namespace Symfony\Polyfill\Intl\Idn;
 
+use Exception;
+use Normalizer;
+use Symfony\Polyfill\Intl\Idn\Resources\unidata\DisallowedRanges;
+use Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex;
+
 /**
- * Partial intl implementation in pure PHP.
- *
- * Implemented:
- * - idn_to_ascii - Convert domain name to IDNA ASCII form
- * - idn_to_utf8  - Convert domain name from IDNA ASCII to Unicode
- *
- * @author Renan Gonçalves 
- * @author Sebastian Kroczek 
- * @author Dmitry Lukashin 
- * @author Laurent Bassin 
+ * @see https://www.unicode.org/reports/tr46/
  *
  * @internal
  */
 final class Idn
 {
-    const INTL_IDNA_VARIANT_2003 = 0;
-    const INTL_IDNA_VARIANT_UTS46 = 1;
-
-    private static $encodeTable = array(
-        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
-        'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
-        'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-    );
-
-    private static $decodeTable = array(
-        'a' => 0, 'b' => 1, 'c' => 2, 'd' => 3, 'e' => 4, 'f' => 5,
-        'g' => 6, 'h' => 7, 'i' => 8, 'j' => 9, 'k' => 10, 'l' => 11,
-        'm' => 12, 'n' => 13, 'o' => 14, 'p' => 15, 'q' => 16, 'r' => 17,
-        's' => 18, 't' => 19, 'u' => 20, 'v' => 21, 'w' => 22, 'x' => 23,
-        'y' => 24, 'z' => 25, '0' => 26, '1' => 27, '2' => 28, '3' => 29,
-        '4' => 30, '5' => 31, '6' => 32, '7' => 33, '8' => 34, '9' => 35,
-    );
-
-    public static function idn_to_ascii($domain, $options, $variant, &$idna_info = array())
+    public const ERROR_EMPTY_LABEL = 1;
+    public const ERROR_LABEL_TOO_LONG = 2;
+    public const ERROR_DOMAIN_NAME_TOO_LONG = 4;
+    public const ERROR_LEADING_HYPHEN = 8;
+    public const ERROR_TRAILING_HYPHEN = 0x10;
+    public const ERROR_HYPHEN_3_4 = 0x20;
+    public const ERROR_LEADING_COMBINING_MARK = 0x40;
+    public const ERROR_DISALLOWED = 0x80;
+    public const ERROR_PUNYCODE = 0x100;
+    public const ERROR_LABEL_HAS_DOT = 0x200;
+    public const ERROR_INVALID_ACE_LABEL = 0x400;
+    public const ERROR_BIDI = 0x800;
+    public const ERROR_CONTEXTJ = 0x1000;
+    public const ERROR_CONTEXTO_PUNCTUATION = 0x2000;
+    public const ERROR_CONTEXTO_DIGITS = 0x4000;
+
+    public const INTL_IDNA_VARIANT_2003 = 0;
+    public const INTL_IDNA_VARIANT_UTS46 = 1;
+
+    public const IDNA_DEFAULT = 0;
+    public const IDNA_ALLOW_UNASSIGNED = 1;
+    public const IDNA_USE_STD3_RULES = 2;
+    public const IDNA_CHECK_BIDI = 4;
+    public const IDNA_CHECK_CONTEXTJ = 8;
+    public const IDNA_NONTRANSITIONAL_TO_ASCII = 16;
+    public const IDNA_NONTRANSITIONAL_TO_UNICODE = 32;
+
+    public const MAX_DOMAIN_SIZE = 253;
+    public const MAX_LABEL_SIZE = 63;
+
+    public const BASE = 36;
+    public const TMIN = 1;
+    public const TMAX = 26;
+    public const SKEW = 38;
+    public const DAMP = 700;
+    public const INITIAL_BIAS = 72;
+    public const INITIAL_N = 128;
+    public const DELIMITER = '-';
+    public const MAX_INT = 2147483647;
+
+    /**
+     * Contains the numeric value of a basic code point (for use in representing integers) in the
+     * range 0 to BASE-1, or -1 if b is does not represent a value.
+     *
+     * @var array
+     */
+    private static $basicToDigit = [
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+        26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
+
+        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+
+        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    ];
+
+    /**
+     * @var array
+     */
+    private static $virama;
+
+    /**
+     * @var array
+     */
+    private static $mapped;
+
+    /**
+     * @var array
+     */
+    private static $ignored;
+
+    /**
+     * @var array
+     */
+    private static $deviation;
+
+    /**
+     * @var array
+     */
+    private static $disallowed;
+
+    /**
+     * @var array
+     */
+    private static $disallowed_STD3_mapped;
+
+    /**
+     * @var array
+     */
+    private static $disallowed_STD3_valid;
+
+    /**
+     * @var bool
+     */
+    private static $mappingTableLoaded = false;
+
+    /**
+     * @see https://www.unicode.org/reports/tr46/#ToASCII
+     *
+     * @param string $domainName
+     * @param int    $options
+     * @param int    $variant
+     * @param array  $idna_info
+     *
+     * @return string|false
+     */
+    public static function idn_to_ascii($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = [])
     {
         if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
-            @trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED);
+            @trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED);
         }
 
-        if (self::INTL_IDNA_VARIANT_UTS46 === $variant) {
-            $domain = mb_strtolower($domain, 'utf-8');
+        $options = [
+            'CheckHyphens' => true,
+            'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & self::IDNA_CHECK_BIDI),
+            'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & self::IDNA_CHECK_CONTEXTJ),
+            'UseSTD3ASCIIRules' => 0 !== ($options & self::IDNA_USE_STD3_RULES),
+            'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & self::IDNA_NONTRANSITIONAL_TO_ASCII),
+            'VerifyDnsLength' => true,
+        ];
+        $info = new Info();
+        $labels = self::process((string) $domainName, $options, $info);
+
+        foreach ($labels as $i => $label) {
+            // Only convert labels to punycode that contain non-ASCII code points
+            if (1 === preg_match('/[^\x00-\x7F]/', $label)) {
+                try {
+                    $label = 'xn--'.self::punycodeEncode($label);
+                } catch (Exception $e) {
+                    $info->errors |= self::ERROR_PUNYCODE;
+                }
+
+                $labels[$i] = $label;
+            }
         }
 
-        $parts = explode('.', $domain);
+        if ($options['VerifyDnsLength']) {
+            self::validateDomainAndLabelLength($labels, $info);
+        }
 
-        foreach ($parts as $i => &$part) {
-            if ('' === $part && \count($parts) > 1 + $i) {
-                return false;
+        $idna_info = [
+            'result' => implode('.', $labels),
+            'isTransitionalDifferent' => $info->transitionalDifferent,
+            'errors' => $info->errors,
+        ];
+
+        return 0 === $info->errors ? $idna_info['result'] : false;
+    }
+
+    /**
+     * @see https://www.unicode.org/reports/tr46/#ToUnicode
+     *
+     * @param string $domainName
+     * @param int    $options
+     * @param int    $variant
+     * @param array  $idna_info
+     *
+     * @return string|false
+     */
+    public static function idn_to_utf8($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = [])
+    {
+        if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
+            @trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED);
+        }
+
+        $info = new Info();
+        $labels = self::process((string) $domainName, [
+            'CheckHyphens' => true,
+            'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & self::IDNA_CHECK_BIDI),
+            'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & self::IDNA_CHECK_CONTEXTJ),
+            'UseSTD3ASCIIRules' => 0 !== ($options & self::IDNA_USE_STD3_RULES),
+            'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & self::IDNA_NONTRANSITIONAL_TO_UNICODE),
+        ], $info);
+        $idna_info = [
+            'result' => implode('.', $labels),
+            'isTransitionalDifferent' => $info->transitionalDifferent,
+            'errors' => $info->errors,
+        ];
+
+        return 0 === $info->errors ? $idna_info['result'] : false;
+    }
+
+    /**
+     * @param string $label
+     *
+     * @return bool
+     */
+    private static function isValidContextJ(array $codePoints, $label)
+    {
+        if (!isset(self::$virama)) {
+            self::$virama = require __DIR__.\DIRECTORY_SEPARATOR.'Resources'.\DIRECTORY_SEPARATOR.'unidata'.\DIRECTORY_SEPARATOR.'virama.php';
+        }
+
+        $offset = 0;
+
+        foreach ($codePoints as $i => $codePoint) {
+            if (0x200C !== $codePoint && 0x200D !== $codePoint) {
+                continue;
             }
-            if (false === $part = self::encodePart($part)) {
+
+            if (!isset($codePoints[$i - 1])) {
                 return false;
             }
+
+            // If Canonical_Combining_Class(Before(cp)) .eq. Virama Then True;
+            if (isset(self::$virama[$codePoints[$i - 1]])) {
+                continue;
+            }
+
+            // If RegExpMatch((Joining_Type:{L,D})(Joining_Type:T)*\u200C(Joining_Type:T)*(Joining_Type:{R,D})) Then
+            // True;
+            // Generated RegExp = ([Joining_Type:{L,D}][Joining_Type:T]*\u200C[Joining_Type:T]*)[Joining_Type:{R,D}]
+            if (0x200C === $codePoint && 1 === preg_match(Regex::ZWNJ, $label, $matches, \PREG_OFFSET_CAPTURE, $offset)) {
+                $offset += \strlen($matches[1][0]);
+
+                continue;
+            }
+
+            return false;
         }
 
-        $output = implode('.', $parts);
+        return true;
+    }
+
+    /**
+     * @see https://www.unicode.org/reports/tr46/#ProcessingStepMap
+     *
+     * @param string              $input
+     * @param array $options
+     *
+     * @return string
+     */
+    private static function mapCodePoints($input, array $options, Info $info)
+    {
+        $str = '';
+        $useSTD3ASCIIRules = $options['UseSTD3ASCIIRules'];
+        $transitional = $options['Transitional_Processing'];
+
+        foreach (self::utf8Decode($input) as $codePoint) {
+            $data = self::lookupCodePointStatus($codePoint, $useSTD3ASCIIRules);
+
+            switch ($data['status']) {
+                case 'disallowed':
+                    $info->errors |= self::ERROR_DISALLOWED;
+
+                    // no break.
+
+                case 'valid':
+                    $str .= mb_chr($codePoint, 'utf-8');
+
+                    break;
+
+                case 'ignored':
+                    // Do nothing.
+                    break;
+
+                case 'mapped':
+                    $str .= $data['mapping'];
+
+                    break;
+
+                case 'deviation':
+                    $info->transitionalDifferent = true;
+                    $str .= ($transitional ? $data['mapping'] : mb_chr($codePoint, 'utf-8'));
 
-        $idna_info = array(
-            'result' => \strlen($output) > 255 ? false : $output,
-            'isTransitionalDifferent' => false,
-            'errors' => 0,
-        );
+                    break;
+            }
+        }
 
-        return $idna_info['result'];
+        return $str;
     }
 
-    public static function idn_to_utf8($domain, $options, $variant, &$idna_info = array())
+    /**
+     * @see https://www.unicode.org/reports/tr46/#Processing
+     *
+     * @param string              $domain
+     * @param array $options
+     *
+     * @return array
+     */
+    private static function process($domain, array $options, Info $info)
     {
-        if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
-            @trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED);
+        // If VerifyDnsLength is not set, we are doing ToUnicode otherwise we are doing ToASCII and
+        // we need to respect the VerifyDnsLength option.
+        $checkForEmptyLabels = !isset($options['VerifyDnsLength']) || $options['VerifyDnsLength'];
+
+        if ($checkForEmptyLabels && '' === $domain) {
+            $info->errors |= self::ERROR_EMPTY_LABEL;
+
+            return [$domain];
         }
 
-        $parts = explode('.', $domain);
+        // Step 1. Map each code point in the domain name string
+        $domain = self::mapCodePoints($domain, $options, $info);
 
-        foreach ($parts as &$part) {
-            $length = \strlen($part);
-            if ($length < 1 || 63 < $length) {
-                continue;
+        // Step 2. Normalize the domain name string to Unicode Normalization Form C.
+        if (!Normalizer::isNormalized($domain, Normalizer::FORM_C)) {
+            $domain = Normalizer::normalize($domain, Normalizer::FORM_C);
+        }
+
+        // Step 3. Break the string into labels at U+002E (.) FULL STOP.
+        $labels = explode('.', $domain);
+        $lastLabelIndex = \count($labels) - 1;
+
+        // Step 4. Convert and validate each label in the domain name string.
+        foreach ($labels as $i => $label) {
+            $validationOptions = $options;
+
+            if ('xn--' === substr($label, 0, 4)) {
+                try {
+                    $label = self::punycodeDecode(substr($label, 4));
+                } catch (Exception $e) {
+                    $info->errors |= self::ERROR_PUNYCODE;
+
+                    continue;
+                }
+
+                $validationOptions['Transitional_Processing'] = false;
+                $labels[$i] = $label;
             }
-            if (0 !== strpos($part, 'xn--')) {
-                continue;
+
+            self::validateLabel($label, $info, $validationOptions, $i > 0 && $i === $lastLabelIndex);
+        }
+
+        if ($info->bidiDomain && !$info->validBidiDomain) {
+            $info->errors |= self::ERROR_BIDI;
+        }
+
+        // Any input domain name string that does not record an error has been successfully
+        // processed according to this specification. Conversely, if an input domain_name string
+        // causes an error, then the processing of the input domain_name string fails. Determining
+        // what to do with error input is up to the caller, and not in the scope of this document.
+        return $labels;
+    }
+
+    /**
+     * @see https://tools.ietf.org/html/rfc5893#section-2
+     *
+     * @param string $label
+     */
+    private static function validateBidiLabel($label, Info $info)
+    {
+        if (1 === preg_match(Regex::RTL_LABEL, $label)) {
+            $info->bidiDomain = true;
+
+            // Step 1. The first character must be a character with Bidi property L, R, or AL.
+            // If it has the R or AL property, it is an RTL label
+            if (1 !== preg_match(Regex::BIDI_STEP_1_RTL, $label)) {
+                $info->validBidiDomain = false;
+
+                return;
+            }
+
+            // Step 2. In an RTL label, only characters with the Bidi properties R, AL, AN, EN, ES,
+            // CS, ET, ON, BN, or NSM are allowed.
+            if (1 === preg_match(Regex::BIDI_STEP_2, $label)) {
+                $info->validBidiDomain = false;
+
+                return;
+            }
+
+            // Step 3. In an RTL label, the end of the label must be a character with Bidi property
+            // R, AL, EN, or AN, followed by zero or more characters with Bidi property NSM.
+            if (1 !== preg_match(Regex::BIDI_STEP_3, $label)) {
+                $info->validBidiDomain = false;
+
+                return;
+            }
+
+            // Step 4. In an RTL label, if an EN is present, no AN may be present, and vice versa.
+            if (1 === preg_match(Regex::BIDI_STEP_4_AN, $label) && 1 === preg_match(Regex::BIDI_STEP_4_EN, $label)) {
+                $info->validBidiDomain = false;
+
+                return;
             }
 
-            $part = substr($part, 4);
-            $part = self::decodePart($part);
+            return;
         }
 
-        $output = implode('.', $parts);
+        // We are a LTR label
+        // Step 1. The first character must be a character with Bidi property L, R, or AL.
+        // If it has the L property, it is an LTR label.
+        if (1 !== preg_match(Regex::BIDI_STEP_1_LTR, $label)) {
+            $info->validBidiDomain = false;
 
-        $idna_info = array(
-            'result' => \strlen($output) > 255 ? false : $output,
-            'isTransitionalDifferent' => false,
-            'errors' => 0,
-        );
+            return;
+        }
+
+        // Step 5. In an LTR label, only characters with the Bidi properties L, EN,
+        // ES, CS, ET, ON, BN, or NSM are allowed.
+        if (1 === preg_match(Regex::BIDI_STEP_5, $label)) {
+            $info->validBidiDomain = false;
+
+            return;
+        }
 
-        return $idna_info['result'];
+        // Step 6.In an LTR label, the end of the label must be a character with Bidi property L or
+        // EN, followed by zero or more characters with Bidi property NSM.
+        if (1 !== preg_match(Regex::BIDI_STEP_6, $label)) {
+            $info->validBidiDomain = false;
+
+            return;
+        }
     }
 
-    private static function encodePart($input)
+    /**
+     * @param array $labels
+     */
+    private static function validateDomainAndLabelLength(array $labels, Info $info)
     {
-        if (\substr($input, 0, 1) === '-' || \substr($input, -1) === '-') {
-            return false;
+        $maxDomainSize = self::MAX_DOMAIN_SIZE;
+        $length = \count($labels);
+
+        // Number of "." delimiters.
+        $domainLength = $length - 1;
+
+        // If the last label is empty and it is not the first label, then it is the root label.
+        // Increase the max size by 1, making it 254, to account for the root label's "."
+        // delimiter. This also means we don't need to check the last label's length for being too
+        // long.
+        if ($length > 1 && '' === $labels[$length - 1]) {
+            ++$maxDomainSize;
+            --$length;
         }
 
-        $codePoints = self::listCodePoints($input);
+        for ($i = 0; $i < $length; ++$i) {
+            $bytes = \strlen($labels[$i]);
+            $domainLength += $bytes;
 
-        $n = 128;
-        $bias = 72;
-        $delta = 0;
-        $h = $b = \count($codePoints['basic']);
+            if ($bytes > self::MAX_LABEL_SIZE) {
+                $info->errors |= self::ERROR_LABEL_TOO_LONG;
+            }
+        }
 
-        $output = '';
-        foreach ($codePoints['basic'] as $code) {
-            $output .= mb_chr($code, 'utf-8');
+        if ($domainLength > $maxDomainSize) {
+            $info->errors |= self::ERROR_DOMAIN_NAME_TOO_LONG;
         }
-        if ($input === $output) {
-            return $output;
+    }
+
+    /**
+     * @see https://www.unicode.org/reports/tr46/#Validity_Criteria
+     *
+     * @param string              $label
+     * @param array $options
+     * @param bool                $canBeEmpty
+     */
+    private static function validateLabel($label, Info $info, array $options, $canBeEmpty)
+    {
+        if ('' === $label) {
+            if (!$canBeEmpty && (!isset($options['VerifyDnsLength']) || $options['VerifyDnsLength'])) {
+                $info->errors |= self::ERROR_EMPTY_LABEL;
+            }
+
+            return;
         }
-        if ($b > 0) {
-            $output .= '-';
+
+        // Step 1. The label must be in Unicode Normalization Form C.
+        if (!Normalizer::isNormalized($label, Normalizer::FORM_C)) {
+            $info->errors |= self::ERROR_INVALID_ACE_LABEL;
+        }
+
+        $codePoints = self::utf8Decode($label);
+
+        if ($options['CheckHyphens']) {
+            // Step 2. If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character
+            // in both the thrid and fourth positions.
+            if (isset($codePoints[2], $codePoints[3]) && 0x002D === $codePoints[2] && 0x002D === $codePoints[3]) {
+                $info->errors |= self::ERROR_HYPHEN_3_4;
+            }
+
+            // Step 3. If CheckHyphens, the label must neither begin nor end with a U+002D
+            // HYPHEN-MINUS character.
+            if ('-' === substr($label, 0, 1)) {
+                $info->errors |= self::ERROR_LEADING_HYPHEN;
+            }
+
+            if ('-' === substr($label, -1, 1)) {
+                $info->errors |= self::ERROR_TRAILING_HYPHEN;
+            }
+        }
+
+        // Step 4. The label must not contain a U+002E (.) FULL STOP.
+        if (false !== strpos($label, '.')) {
+            $info->errors |= self::ERROR_LABEL_HAS_DOT;
+        }
+
+        // Step 5. The label must not begin with a combining mark, that is: General_Category=Mark.
+        if (1 === preg_match(Regex::COMBINING_MARK, $label)) {
+            $info->errors |= self::ERROR_LEADING_COMBINING_MARK;
+        }
+
+        // Step 6. Each code point in the label must only have certain status values according to
+        // Section 5, IDNA Mapping Table:
+        $transitional = $options['Transitional_Processing'];
+        $useSTD3ASCIIRules = $options['UseSTD3ASCIIRules'];
+
+        foreach ($codePoints as $codePoint) {
+            $data = self::lookupCodePointStatus($codePoint, $useSTD3ASCIIRules);
+            $status = $data['status'];
+
+            if ('valid' === $status || (!$transitional && 'deviation' === $status)) {
+                continue;
+            }
+
+            $info->errors |= self::ERROR_DISALLOWED;
+
+            break;
+        }
+
+        // Step 7. If CheckJoiners, the label must satisify the ContextJ rules from Appendix A, in
+        // The Unicode Code Points and Internationalized Domain Names for Applications (IDNA)
+        // [IDNA2008].
+        if ($options['CheckJoiners'] && !self::isValidContextJ($codePoints, $label)) {
+            $info->errors |= self::ERROR_CONTEXTJ;
         }
 
-        $codePoints['nonBasic'] = array_unique($codePoints['nonBasic']);
-        sort($codePoints['nonBasic']);
+        // Step 8. If CheckBidi, and if the domain name is a  Bidi domain name, then the label must
+        // satisfy all six of the numbered conditions in [IDNA2008] RFC 5893, Section 2.
+        if ($options['CheckBidi'] && (!$info->bidiDomain || $info->validBidiDomain)) {
+            self::validateBidiLabel($label, $info);
+        }
+    }
 
+    /**
+     * @see https://tools.ietf.org/html/rfc3492#section-6.2
+     *
+     * @param string $input
+     *
+     * @return string
+     */
+    private static function punycodeDecode($input)
+    {
+        $n = self::INITIAL_N;
+        $out = 0;
         $i = 0;
-        $length = mb_strlen($input, 'utf-8');
-        while ($h < $length) {
-            $m = $codePoints['nonBasic'][$i++];
+        $bias = self::INITIAL_BIAS;
+        $lastDelimIndex = strrpos($input, self::DELIMITER);
+        $b = false === $lastDelimIndex ? 0 : $lastDelimIndex;
+        $inputLength = \strlen($input);
+        $output = [];
+        $bytes = array_map('ord', str_split($input));
+
+        for ($j = 0; $j < $b; ++$j) {
+            if ($bytes[$j] > 0x7F) {
+                throw new Exception('Invalid input');
+            }
+
+            $output[$out++] = $input[$j];
+        }
+
+        if ($b > 0) {
+            ++$b;
+        }
+
+        for ($in = $b; $in < $inputLength; ++$out) {
+            $oldi = $i;
+            $w = 1;
+
+            for ($k = self::BASE; /* no condition */; $k += self::BASE) {
+                if ($in >= $inputLength) {
+                    throw new Exception('Invalid input');
+                }
+
+                $digit = self::$basicToDigit[$bytes[$in++] & 0xFF];
+
+                if ($digit < 0) {
+                    throw new Exception('Invalid input');
+                }
+
+                if ($digit > intdiv(self::MAX_INT - $i, $w)) {
+                    throw new Exception('Integer overflow');
+                }
+
+                $i += $digit * $w;
+
+                if ($k <= $bias) {
+                    $t = self::TMIN;
+                } elseif ($k >= $bias + self::TMAX) {
+                    $t = self::TMAX;
+                } else {
+                    $t = $k - $bias;
+                }
+
+                if ($digit < $t) {
+                    break;
+                }
+
+                $baseMinusT = self::BASE - $t;
+
+                if ($w > intdiv(self::MAX_INT, $baseMinusT)) {
+                    throw new Exception('Integer overflow');
+                }
+
+                $w *= $baseMinusT;
+            }
+
+            $outPlusOne = $out + 1;
+            $bias = self::adaptBias($i - $oldi, $outPlusOne, 0 === $oldi);
+
+            if (intdiv($i, $outPlusOne) > self::MAX_INT - $n) {
+                throw new Exception('Integer overflow');
+            }
+
+            $n += intdiv($i, $outPlusOne);
+            $i %= $outPlusOne;
+            array_splice($output, $i++, 0, [mb_chr($n, 'utf-8')]);
+        }
+
+        return implode('', $output);
+    }
+
+    /**
+     * @see https://tools.ietf.org/html/rfc3492#section-6.3
+     *
+     * @param string $input
+     *
+     * @return string
+     */
+    private static function punycodeEncode($input)
+    {
+        $n = self::INITIAL_N;
+        $delta = 0;
+        $out = 0;
+        $bias = self::INITIAL_BIAS;
+        $inputLength = 0;
+        $output = '';
+        $iter = self::utf8Decode($input);
+
+        foreach ($iter as $codePoint) {
+            ++$inputLength;
+
+            if ($codePoint < 0x80) {
+                $output .= \chr($codePoint);
+                ++$out;
+            }
+        }
+
+        $h = $out;
+        $b = $out;
+
+        if ($b > 0) {
+            $output .= self::DELIMITER;
+            ++$out;
+        }
+
+        while ($h < $inputLength) {
+            $m = self::MAX_INT;
+
+            foreach ($iter as $codePoint) {
+                if ($codePoint >= $n && $codePoint < $m) {
+                    $m = $codePoint;
+                }
+            }
+
+            if ($m - $n > intdiv(self::MAX_INT - $delta, $h + 1)) {
+                throw new Exception('Integer overflow');
+            }
+
             $delta += ($m - $n) * ($h + 1);
             $n = $m;
 
-            foreach ($codePoints['all'] as $c) {
-                if ($c < $n || $c < 128) {
-                    ++$delta;
+            foreach ($iter as $codePoint) {
+                if ($codePoint < $n && 0 === ++$delta) {
+                    throw new Exception('Integer overflow');
                 }
-                if ($c === $n) {
+
+                if ($codePoint === $n) {
                     $q = $delta;
-                    for ($k = 36;; $k += 36) {
-                        $t = self::calculateThreshold($k, $bias);
+
+                    for ($k = self::BASE; /* no condition */; $k += self::BASE) {
+                        if ($k <= $bias) {
+                            $t = self::TMIN;
+                        } elseif ($k >= $bias + self::TMAX) {
+                            $t = self::TMAX;
+                        } else {
+                            $t = $k - $bias;
+                        }
+
                         if ($q < $t) {
                             break;
                         }
 
-                        $code = $t + (($q - $t) % (36 - $t));
-                        $output .= self::$encodeTable[$code];
-
-                        $q = ($q - $t) / (36 - $t);
+                        $qMinusT = $q - $t;
+                        $baseMinusT = self::BASE - $t;
+                        $output .= self::encodeDigit($t + ($qMinusT) % ($baseMinusT), false);
+                        ++$out;
+                        $q = intdiv($qMinusT, $baseMinusT);
                     }
 
-                    $output .= self::$encodeTable[$q];
-                    $bias = self::adapt($delta, $h + 1, ($h === $b));
+                    $output .= self::encodeDigit($q, false);
+                    ++$out;
+                    $bias = self::adaptBias($delta, $h + 1, $h === $b);
                     $delta = 0;
                     ++$h;
                 }
@@ -188,100 +740,186 @@ private static function encodePart($input)
             ++$n;
         }
 
-        $output = 'xn--'.$output;
-
-        return \strlen($output) < 1 || 63 < \strlen($output) ? false : strtolower($output);
+        return $output;
     }
 
-    private static function listCodePoints($input)
+    /**
+     * @see https://tools.ietf.org/html/rfc3492#section-6.1
+     *
+     * @param int  $delta
+     * @param int  $numPoints
+     * @param bool $firstTime
+     *
+     * @return int
+     */
+    private static function adaptBias($delta, $numPoints, $firstTime)
     {
-        $codePoints = array(
-            'all' => array(),
-            'basic' => array(),
-            'nonBasic' => array(),
-        );
+        // xxx >> 1 is a faster way of doing intdiv(xxx, 2)
+        $delta = $firstTime ? intdiv($delta, self::DAMP) : $delta >> 1;
+        $delta += intdiv($delta, $numPoints);
+        $k = 0;
 
-        $length = mb_strlen($input, 'utf-8');
-        for ($i = 0; $i < $length; ++$i) {
-            $char = mb_substr($input, $i, 1, 'utf-8');
-            $code = mb_ord($char, 'utf-8');
-            if ($code < 128) {
-                $codePoints['all'][] = $codePoints['basic'][] = $code;
-            } else {
-                $codePoints['all'][] = $codePoints['nonBasic'][] = $code;
-            }
+        while ($delta > ((self::BASE - self::TMIN) * self::TMAX) >> 1) {
+            $delta = intdiv($delta, self::BASE - self::TMIN);
+            $k += self::BASE;
         }
 
-        return $codePoints;
+        return $k + intdiv((self::BASE - self::TMIN + 1) * $delta, $delta + self::SKEW);
     }
 
-    private static function calculateThreshold($k, $bias)
+    /**
+     * @param int  $d
+     * @param bool $flag
+     *
+     * @return string
+     */
+    private static function encodeDigit($d, $flag)
     {
-        if ($k <= $bias + 1) {
-            return 1;
-        }
-        if ($k >= $bias + 26) {
-            return 26;
-        }
-
-        return $k - $bias;
+        return \chr($d + 22 + 75 * ($d < 26 ? 1 : 0) - (($flag ? 1 : 0) << 5));
     }
 
-    private static function adapt($delta, $numPoints, $firstTime)
+    /**
+     * Takes a UTF-8 encoded string and converts it into a series of integer code points. Any
+     * invalid byte sequences will be replaced by a U+FFFD replacement code point.
+     *
+     * @see https://encoding.spec.whatwg.org/#utf-8-decoder
+     *
+     * @param string $input
+     *
+     * @return array
+     */
+    private static function utf8Decode($input)
     {
-        $delta = (int) ($firstTime ? $delta / 700 : $delta / 2);
-        $delta += (int) ($delta / $numPoints);
+        $bytesSeen = 0;
+        $bytesNeeded = 0;
+        $lowerBoundary = 0x80;
+        $upperBoundary = 0xBF;
+        $codePoint = 0;
+        $codePoints = [];
+        $length = \strlen($input);
 
-        $k = 0;
-        while ($delta > 35 * 13) {
-            $delta = (int) ($delta / 35);
-            $k = $k + 36;
+        for ($i = 0; $i < $length; ++$i) {
+            $byte = \ord($input[$i]);
+
+            if (0 === $bytesNeeded) {
+                if ($byte >= 0x00 && $byte <= 0x7F) {
+                    $codePoints[] = $byte;
+
+                    continue;
+                }
+
+                if ($byte >= 0xC2 && $byte <= 0xDF) {
+                    $bytesNeeded = 1;
+                    $codePoint = $byte & 0x1F;
+                } elseif ($byte >= 0xE0 && $byte <= 0xEF) {
+                    if (0xE0 === $byte) {
+                        $lowerBoundary = 0xA0;
+                    } elseif (0xED === $byte) {
+                        $upperBoundary = 0x9F;
+                    }
+
+                    $bytesNeeded = 2;
+                    $codePoint = $byte & 0xF;
+                } elseif ($byte >= 0xF0 && $byte <= 0xF4) {
+                    if (0xF0 === $byte) {
+                        $lowerBoundary = 0x90;
+                    } elseif (0xF4 === $byte) {
+                        $upperBoundary = 0x8F;
+                    }
+
+                    $bytesNeeded = 3;
+                    $codePoint = $byte & 0x7;
+                } else {
+                    $codePoints[] = 0xFFFD;
+                }
+
+                continue;
+            }
+
+            if ($byte < $lowerBoundary || $byte > $upperBoundary) {
+                $codePoint = 0;
+                $bytesNeeded = 0;
+                $bytesSeen = 0;
+                $lowerBoundary = 0x80;
+                $upperBoundary = 0xBF;
+                --$i;
+                $codePoints[] = 0xFFFD;
+
+                continue;
+            }
+
+            $lowerBoundary = 0x80;
+            $upperBoundary = 0xBF;
+            $codePoint = ($codePoint << 6) | ($byte & 0x3F);
+
+            if (++$bytesSeen !== $bytesNeeded) {
+                continue;
+            }
+
+            $codePoints[] = $codePoint;
+            $codePoint = 0;
+            $bytesNeeded = 0;
+            $bytesSeen = 0;
         }
 
-        return $k + (int) (36 * $delta / ($delta + 38));
+        // String unexpectedly ended, so append a U+FFFD code point.
+        if (0 !== $bytesNeeded) {
+            $codePoints[] = 0xFFFD;
+        }
+
+        return $codePoints;
     }
 
-    private static function decodePart($input)
+    /**
+     * @param int  $codePoint
+     * @param bool $useSTD3ASCIIRules
+     *
+     * @return array{status: string, mapping?: string}
+     */
+    private static function lookupCodePointStatus($codePoint, $useSTD3ASCIIRules)
     {
-        $n = 128;
-        $i = 0;
-        $bias = 72;
-        $output = '';
+        if (!self::$mappingTableLoaded) {
+            self::$mappingTableLoaded = true;
+            self::$mapped = require __DIR__.'/Resources/unidata/mapped.php';
+            self::$ignored = require __DIR__.'/Resources/unidata/ignored.php';
+            self::$deviation = require __DIR__.'/Resources/unidata/deviation.php';
+            self::$disallowed = require __DIR__.'/Resources/unidata/disallowed.php';
+            self::$disallowed_STD3_mapped = require __DIR__.'/Resources/unidata/disallowed_STD3_mapped.php';
+            self::$disallowed_STD3_valid = require __DIR__.'/Resources/unidata/disallowed_STD3_valid.php';
+        }
 
-        $pos = strrpos($input, '-');
-        if (false !== $pos) {
-            $output = substr($input, 0, $pos++);
-        } else {
-            $pos = 0;
+        if (isset(self::$mapped[$codePoint])) {
+            return ['status' => 'mapped', 'mapping' => self::$mapped[$codePoint]];
         }
 
-        $outputLength = \strlen($output);
-        $inputLength = \strlen($input);
+        if (isset(self::$ignored[$codePoint])) {
+            return ['status' => 'ignored'];
+        }
 
-        while ($pos < $inputLength) {
-            $oldi = $i;
-            $w = 1;
+        if (isset(self::$deviation[$codePoint])) {
+            return ['status' => 'deviation', 'mapping' => self::$deviation[$codePoint]];
+        }
 
-            for ($k = 36;; $k += 36) {
-                $digit = self::$decodeTable[$input[$pos++]];
-                $i += $digit * $w;
-                $t = self::calculateThreshold($k, $bias);
+        if (isset(self::$disallowed[$codePoint]) || DisallowedRanges::inRange($codePoint)) {
+            return ['status' => 'disallowed'];
+        }
 
-                if ($digit < $t) {
-                    break;
-                }
+        $isDisallowedMapped = isset(self::$disallowed_STD3_mapped[$codePoint]);
 
-                $w *= 36 - $t;
+        if ($isDisallowedMapped || isset(self::$disallowed_STD3_valid[$codePoint])) {
+            $status = 'disallowed';
+
+            if (!$useSTD3ASCIIRules) {
+                $status = $isDisallowedMapped ? 'mapped' : 'valid';
             }
 
-            $bias = self::adapt($i - $oldi, ++$outputLength, 0 === $oldi);
-            $n = $n + (int) ($i / $outputLength);
-            $i = $i % $outputLength;
-            $output = mb_substr($output, 0, $i, 'utf-8').mb_chr($n, 'utf-8').mb_substr($output, $i, $outputLength - 1, 'utf-8');
+            if ($isDisallowedMapped) {
+                return ['status' => $status, 'mapping' => self::$disallowed_STD3_mapped[$codePoint]];
+            }
 
-            ++$i;
+            return ['status' => $status];
         }
 
-        return $output;
+        return ['status' => 'valid'];
     }
 }
diff --git a/vendor/symfony/polyfill-intl-idn/Info.php b/vendor/symfony/polyfill-intl-idn/Info.php
new file mode 100644
index 000000000..25c3582b2
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-idn/Info.php
@@ -0,0 +1,23 @@
+ and Trevor Rowbotham 
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Polyfill\Intl\Idn;
+
+/**
+ * @internal
+ */
+class Info
+{
+    public $bidiDomain = false;
+    public $errors = 0;
+    public $validBidiDomain = true;
+    public $transitionalDifferent = false;
+}
diff --git a/vendor/symfony/polyfill-intl-idn/LICENSE b/vendor/symfony/polyfill-intl-idn/LICENSE
index 3f853aaf3..03c5e2577 100644
--- a/vendor/symfony/polyfill-intl-idn/LICENSE
+++ b/vendor/symfony/polyfill-intl-idn/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2018-2019 Fabien Potencier
+Copyright (c) 2018-2019 Fabien Potencier and Trevor Rowbotham 
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php b/vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php
new file mode 100644
index 000000000..5bb70e48a
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php
@@ -0,0 +1,375 @@
+= 128 && $codePoint <= 159) {
+            return true;
+        }
+
+        if ($codePoint >= 2155 && $codePoint <= 2207) {
+            return true;
+        }
+
+        if ($codePoint >= 3676 && $codePoint <= 3712) {
+            return true;
+        }
+
+        if ($codePoint >= 3808 && $codePoint <= 3839) {
+            return true;
+        }
+
+        if ($codePoint >= 4059 && $codePoint <= 4095) {
+            return true;
+        }
+
+        if ($codePoint >= 4256 && $codePoint <= 4293) {
+            return true;
+        }
+
+        if ($codePoint >= 6849 && $codePoint <= 6911) {
+            return true;
+        }
+
+        if ($codePoint >= 11859 && $codePoint <= 11903) {
+            return true;
+        }
+
+        if ($codePoint >= 42955 && $codePoint <= 42996) {
+            return true;
+        }
+
+        if ($codePoint >= 55296 && $codePoint <= 57343) {
+            return true;
+        }
+
+        if ($codePoint >= 57344 && $codePoint <= 63743) {
+            return true;
+        }
+
+        if ($codePoint >= 64218 && $codePoint <= 64255) {
+            return true;
+        }
+
+        if ($codePoint >= 64976 && $codePoint <= 65007) {
+            return true;
+        }
+
+        if ($codePoint >= 65630 && $codePoint <= 65663) {
+            return true;
+        }
+
+        if ($codePoint >= 65953 && $codePoint <= 65999) {
+            return true;
+        }
+
+        if ($codePoint >= 66046 && $codePoint <= 66175) {
+            return true;
+        }
+
+        if ($codePoint >= 66518 && $codePoint <= 66559) {
+            return true;
+        }
+
+        if ($codePoint >= 66928 && $codePoint <= 67071) {
+            return true;
+        }
+
+        if ($codePoint >= 67432 && $codePoint <= 67583) {
+            return true;
+        }
+
+        if ($codePoint >= 67760 && $codePoint <= 67807) {
+            return true;
+        }
+
+        if ($codePoint >= 67904 && $codePoint <= 67967) {
+            return true;
+        }
+
+        if ($codePoint >= 68256 && $codePoint <= 68287) {
+            return true;
+        }
+
+        if ($codePoint >= 68528 && $codePoint <= 68607) {
+            return true;
+        }
+
+        if ($codePoint >= 68681 && $codePoint <= 68735) {
+            return true;
+        }
+
+        if ($codePoint >= 68922 && $codePoint <= 69215) {
+            return true;
+        }
+
+        if ($codePoint >= 69298 && $codePoint <= 69375) {
+            return true;
+        }
+
+        if ($codePoint >= 69466 && $codePoint <= 69551) {
+            return true;
+        }
+
+        if ($codePoint >= 70207 && $codePoint <= 70271) {
+            return true;
+        }
+
+        if ($codePoint >= 70517 && $codePoint <= 70655) {
+            return true;
+        }
+
+        if ($codePoint >= 70874 && $codePoint <= 71039) {
+            return true;
+        }
+
+        if ($codePoint >= 71134 && $codePoint <= 71167) {
+            return true;
+        }
+
+        if ($codePoint >= 71370 && $codePoint <= 71423) {
+            return true;
+        }
+
+        if ($codePoint >= 71488 && $codePoint <= 71679) {
+            return true;
+        }
+
+        if ($codePoint >= 71740 && $codePoint <= 71839) {
+            return true;
+        }
+
+        if ($codePoint >= 72026 && $codePoint <= 72095) {
+            return true;
+        }
+
+        if ($codePoint >= 72441 && $codePoint <= 72703) {
+            return true;
+        }
+
+        if ($codePoint >= 72887 && $codePoint <= 72959) {
+            return true;
+        }
+
+        if ($codePoint >= 73130 && $codePoint <= 73439) {
+            return true;
+        }
+
+        if ($codePoint >= 73465 && $codePoint <= 73647) {
+            return true;
+        }
+
+        if ($codePoint >= 74650 && $codePoint <= 74751) {
+            return true;
+        }
+
+        if ($codePoint >= 75076 && $codePoint <= 77823) {
+            return true;
+        }
+
+        if ($codePoint >= 78905 && $codePoint <= 82943) {
+            return true;
+        }
+
+        if ($codePoint >= 83527 && $codePoint <= 92159) {
+            return true;
+        }
+
+        if ($codePoint >= 92784 && $codePoint <= 92879) {
+            return true;
+        }
+
+        if ($codePoint >= 93072 && $codePoint <= 93759) {
+            return true;
+        }
+
+        if ($codePoint >= 93851 && $codePoint <= 93951) {
+            return true;
+        }
+
+        if ($codePoint >= 94112 && $codePoint <= 94175) {
+            return true;
+        }
+
+        if ($codePoint >= 101590 && $codePoint <= 101631) {
+            return true;
+        }
+
+        if ($codePoint >= 101641 && $codePoint <= 110591) {
+            return true;
+        }
+
+        if ($codePoint >= 110879 && $codePoint <= 110927) {
+            return true;
+        }
+
+        if ($codePoint >= 111356 && $codePoint <= 113663) {
+            return true;
+        }
+
+        if ($codePoint >= 113828 && $codePoint <= 118783) {
+            return true;
+        }
+
+        if ($codePoint >= 119366 && $codePoint <= 119519) {
+            return true;
+        }
+
+        if ($codePoint >= 119673 && $codePoint <= 119807) {
+            return true;
+        }
+
+        if ($codePoint >= 121520 && $codePoint <= 122879) {
+            return true;
+        }
+
+        if ($codePoint >= 122923 && $codePoint <= 123135) {
+            return true;
+        }
+
+        if ($codePoint >= 123216 && $codePoint <= 123583) {
+            return true;
+        }
+
+        if ($codePoint >= 123648 && $codePoint <= 124927) {
+            return true;
+        }
+
+        if ($codePoint >= 125143 && $codePoint <= 125183) {
+            return true;
+        }
+
+        if ($codePoint >= 125280 && $codePoint <= 126064) {
+            return true;
+        }
+
+        if ($codePoint >= 126133 && $codePoint <= 126208) {
+            return true;
+        }
+
+        if ($codePoint >= 126270 && $codePoint <= 126463) {
+            return true;
+        }
+
+        if ($codePoint >= 126652 && $codePoint <= 126703) {
+            return true;
+        }
+
+        if ($codePoint >= 126706 && $codePoint <= 126975) {
+            return true;
+        }
+
+        if ($codePoint >= 127406 && $codePoint <= 127461) {
+            return true;
+        }
+
+        if ($codePoint >= 127590 && $codePoint <= 127743) {
+            return true;
+        }
+
+        if ($codePoint >= 129202 && $codePoint <= 129279) {
+            return true;
+        }
+
+        if ($codePoint >= 129751 && $codePoint <= 129791) {
+            return true;
+        }
+
+        if ($codePoint >= 129995 && $codePoint <= 130031) {
+            return true;
+        }
+
+        if ($codePoint >= 130042 && $codePoint <= 131069) {
+            return true;
+        }
+
+        if ($codePoint >= 173790 && $codePoint <= 173823) {
+            return true;
+        }
+
+        if ($codePoint >= 191457 && $codePoint <= 194559) {
+            return true;
+        }
+
+        if ($codePoint >= 195102 && $codePoint <= 196605) {
+            return true;
+        }
+
+        if ($codePoint >= 201547 && $codePoint <= 262141) {
+            return true;
+        }
+
+        if ($codePoint >= 262144 && $codePoint <= 327677) {
+            return true;
+        }
+
+        if ($codePoint >= 327680 && $codePoint <= 393213) {
+            return true;
+        }
+
+        if ($codePoint >= 393216 && $codePoint <= 458749) {
+            return true;
+        }
+
+        if ($codePoint >= 458752 && $codePoint <= 524285) {
+            return true;
+        }
+
+        if ($codePoint >= 524288 && $codePoint <= 589821) {
+            return true;
+        }
+
+        if ($codePoint >= 589824 && $codePoint <= 655357) {
+            return true;
+        }
+
+        if ($codePoint >= 655360 && $codePoint <= 720893) {
+            return true;
+        }
+
+        if ($codePoint >= 720896 && $codePoint <= 786429) {
+            return true;
+        }
+
+        if ($codePoint >= 786432 && $codePoint <= 851965) {
+            return true;
+        }
+
+        if ($codePoint >= 851968 && $codePoint <= 917501) {
+            return true;
+        }
+
+        if ($codePoint >= 917536 && $codePoint <= 917631) {
+            return true;
+        }
+
+        if ($codePoint >= 917632 && $codePoint <= 917759) {
+            return true;
+        }
+
+        if ($codePoint >= 918000 && $codePoint <= 983037) {
+            return true;
+        }
+
+        if ($codePoint >= 983040 && $codePoint <= 1048573) {
+            return true;
+        }
+
+        if ($codePoint >= 1048576 && $codePoint <= 1114109) {
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php b/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php
new file mode 100644
index 000000000..c4b9778e5
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php
@@ -0,0 +1,24 @@
+ 'ss',
+  962 => 'σ',
+  8204 => '',
+  8205 => '',
+);
diff --git a/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php b/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php
new file mode 100644
index 000000000..25a5f564d
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php
@@ -0,0 +1,2638 @@
+ true,
+  889 => true,
+  896 => true,
+  897 => true,
+  898 => true,
+  899 => true,
+  907 => true,
+  909 => true,
+  930 => true,
+  1216 => true,
+  1328 => true,
+  1367 => true,
+  1368 => true,
+  1419 => true,
+  1420 => true,
+  1424 => true,
+  1480 => true,
+  1481 => true,
+  1482 => true,
+  1483 => true,
+  1484 => true,
+  1485 => true,
+  1486 => true,
+  1487 => true,
+  1515 => true,
+  1516 => true,
+  1517 => true,
+  1518 => true,
+  1525 => true,
+  1526 => true,
+  1527 => true,
+  1528 => true,
+  1529 => true,
+  1530 => true,
+  1531 => true,
+  1532 => true,
+  1533 => true,
+  1534 => true,
+  1535 => true,
+  1536 => true,
+  1537 => true,
+  1538 => true,
+  1539 => true,
+  1540 => true,
+  1541 => true,
+  1564 => true,
+  1565 => true,
+  1757 => true,
+  1806 => true,
+  1807 => true,
+  1867 => true,
+  1868 => true,
+  1970 => true,
+  1971 => true,
+  1972 => true,
+  1973 => true,
+  1974 => true,
+  1975 => true,
+  1976 => true,
+  1977 => true,
+  1978 => true,
+  1979 => true,
+  1980 => true,
+  1981 => true,
+  1982 => true,
+  1983 => true,
+  2043 => true,
+  2044 => true,
+  2094 => true,
+  2095 => true,
+  2111 => true,
+  2140 => true,
+  2141 => true,
+  2143 => true,
+  2229 => true,
+  2248 => true,
+  2249 => true,
+  2250 => true,
+  2251 => true,
+  2252 => true,
+  2253 => true,
+  2254 => true,
+  2255 => true,
+  2256 => true,
+  2257 => true,
+  2258 => true,
+  2274 => true,
+  2436 => true,
+  2445 => true,
+  2446 => true,
+  2449 => true,
+  2450 => true,
+  2473 => true,
+  2481 => true,
+  2483 => true,
+  2484 => true,
+  2485 => true,
+  2490 => true,
+  2491 => true,
+  2501 => true,
+  2502 => true,
+  2505 => true,
+  2506 => true,
+  2511 => true,
+  2512 => true,
+  2513 => true,
+  2514 => true,
+  2515 => true,
+  2516 => true,
+  2517 => true,
+  2518 => true,
+  2520 => true,
+  2521 => true,
+  2522 => true,
+  2523 => true,
+  2526 => true,
+  2532 => true,
+  2533 => true,
+  2559 => true,
+  2560 => true,
+  2564 => true,
+  2571 => true,
+  2572 => true,
+  2573 => true,
+  2574 => true,
+  2577 => true,
+  2578 => true,
+  2601 => true,
+  2609 => true,
+  2612 => true,
+  2615 => true,
+  2618 => true,
+  2619 => true,
+  2621 => true,
+  2627 => true,
+  2628 => true,
+  2629 => true,
+  2630 => true,
+  2633 => true,
+  2634 => true,
+  2638 => true,
+  2639 => true,
+  2640 => true,
+  2642 => true,
+  2643 => true,
+  2644 => true,
+  2645 => true,
+  2646 => true,
+  2647 => true,
+  2648 => true,
+  2653 => true,
+  2655 => true,
+  2656 => true,
+  2657 => true,
+  2658 => true,
+  2659 => true,
+  2660 => true,
+  2661 => true,
+  2679 => true,
+  2680 => true,
+  2681 => true,
+  2682 => true,
+  2683 => true,
+  2684 => true,
+  2685 => true,
+  2686 => true,
+  2687 => true,
+  2688 => true,
+  2692 => true,
+  2702 => true,
+  2706 => true,
+  2729 => true,
+  2737 => true,
+  2740 => true,
+  2746 => true,
+  2747 => true,
+  2758 => true,
+  2762 => true,
+  2766 => true,
+  2767 => true,
+  2769 => true,
+  2770 => true,
+  2771 => true,
+  2772 => true,
+  2773 => true,
+  2774 => true,
+  2775 => true,
+  2776 => true,
+  2777 => true,
+  2778 => true,
+  2779 => true,
+  2780 => true,
+  2781 => true,
+  2782 => true,
+  2783 => true,
+  2788 => true,
+  2789 => true,
+  2802 => true,
+  2803 => true,
+  2804 => true,
+  2805 => true,
+  2806 => true,
+  2807 => true,
+  2808 => true,
+  2816 => true,
+  2820 => true,
+  2829 => true,
+  2830 => true,
+  2833 => true,
+  2834 => true,
+  2857 => true,
+  2865 => true,
+  2868 => true,
+  2874 => true,
+  2875 => true,
+  2885 => true,
+  2886 => true,
+  2889 => true,
+  2890 => true,
+  2894 => true,
+  2895 => true,
+  2896 => true,
+  2897 => true,
+  2898 => true,
+  2899 => true,
+  2900 => true,
+  2904 => true,
+  2905 => true,
+  2906 => true,
+  2907 => true,
+  2910 => true,
+  2916 => true,
+  2917 => true,
+  2936 => true,
+  2937 => true,
+  2938 => true,
+  2939 => true,
+  2940 => true,
+  2941 => true,
+  2942 => true,
+  2943 => true,
+  2944 => true,
+  2945 => true,
+  2948 => true,
+  2955 => true,
+  2956 => true,
+  2957 => true,
+  2961 => true,
+  2966 => true,
+  2967 => true,
+  2968 => true,
+  2971 => true,
+  2973 => true,
+  2976 => true,
+  2977 => true,
+  2978 => true,
+  2981 => true,
+  2982 => true,
+  2983 => true,
+  2987 => true,
+  2988 => true,
+  2989 => true,
+  3002 => true,
+  3003 => true,
+  3004 => true,
+  3005 => true,
+  3011 => true,
+  3012 => true,
+  3013 => true,
+  3017 => true,
+  3022 => true,
+  3023 => true,
+  3025 => true,
+  3026 => true,
+  3027 => true,
+  3028 => true,
+  3029 => true,
+  3030 => true,
+  3032 => true,
+  3033 => true,
+  3034 => true,
+  3035 => true,
+  3036 => true,
+  3037 => true,
+  3038 => true,
+  3039 => true,
+  3040 => true,
+  3041 => true,
+  3042 => true,
+  3043 => true,
+  3044 => true,
+  3045 => true,
+  3067 => true,
+  3068 => true,
+  3069 => true,
+  3070 => true,
+  3071 => true,
+  3085 => true,
+  3089 => true,
+  3113 => true,
+  3130 => true,
+  3131 => true,
+  3132 => true,
+  3141 => true,
+  3145 => true,
+  3150 => true,
+  3151 => true,
+  3152 => true,
+  3153 => true,
+  3154 => true,
+  3155 => true,
+  3156 => true,
+  3159 => true,
+  3163 => true,
+  3164 => true,
+  3165 => true,
+  3166 => true,
+  3167 => true,
+  3172 => true,
+  3173 => true,
+  3184 => true,
+  3185 => true,
+  3186 => true,
+  3187 => true,
+  3188 => true,
+  3189 => true,
+  3190 => true,
+  3213 => true,
+  3217 => true,
+  3241 => true,
+  3252 => true,
+  3258 => true,
+  3259 => true,
+  3269 => true,
+  3273 => true,
+  3278 => true,
+  3279 => true,
+  3280 => true,
+  3281 => true,
+  3282 => true,
+  3283 => true,
+  3284 => true,
+  3287 => true,
+  3288 => true,
+  3289 => true,
+  3290 => true,
+  3291 => true,
+  3292 => true,
+  3293 => true,
+  3295 => true,
+  3300 => true,
+  3301 => true,
+  3312 => true,
+  3315 => true,
+  3316 => true,
+  3317 => true,
+  3318 => true,
+  3319 => true,
+  3320 => true,
+  3321 => true,
+  3322 => true,
+  3323 => true,
+  3324 => true,
+  3325 => true,
+  3326 => true,
+  3327 => true,
+  3341 => true,
+  3345 => true,
+  3397 => true,
+  3401 => true,
+  3408 => true,
+  3409 => true,
+  3410 => true,
+  3411 => true,
+  3428 => true,
+  3429 => true,
+  3456 => true,
+  3460 => true,
+  3479 => true,
+  3480 => true,
+  3481 => true,
+  3506 => true,
+  3516 => true,
+  3518 => true,
+  3519 => true,
+  3527 => true,
+  3528 => true,
+  3529 => true,
+  3531 => true,
+  3532 => true,
+  3533 => true,
+  3534 => true,
+  3541 => true,
+  3543 => true,
+  3552 => true,
+  3553 => true,
+  3554 => true,
+  3555 => true,
+  3556 => true,
+  3557 => true,
+  3568 => true,
+  3569 => true,
+  3573 => true,
+  3574 => true,
+  3575 => true,
+  3576 => true,
+  3577 => true,
+  3578 => true,
+  3579 => true,
+  3580 => true,
+  3581 => true,
+  3582 => true,
+  3583 => true,
+  3584 => true,
+  3643 => true,
+  3644 => true,
+  3645 => true,
+  3646 => true,
+  3715 => true,
+  3717 => true,
+  3723 => true,
+  3748 => true,
+  3750 => true,
+  3774 => true,
+  3775 => true,
+  3781 => true,
+  3783 => true,
+  3790 => true,
+  3791 => true,
+  3802 => true,
+  3803 => true,
+  3912 => true,
+  3949 => true,
+  3950 => true,
+  3951 => true,
+  3952 => true,
+  3992 => true,
+  4029 => true,
+  4045 => true,
+  4294 => true,
+  4296 => true,
+  4297 => true,
+  4298 => true,
+  4299 => true,
+  4300 => true,
+  4302 => true,
+  4303 => true,
+  4447 => true,
+  4448 => true,
+  4681 => true,
+  4686 => true,
+  4687 => true,
+  4695 => true,
+  4697 => true,
+  4702 => true,
+  4703 => true,
+  4745 => true,
+  4750 => true,
+  4751 => true,
+  4785 => true,
+  4790 => true,
+  4791 => true,
+  4799 => true,
+  4801 => true,
+  4806 => true,
+  4807 => true,
+  4823 => true,
+  4881 => true,
+  4886 => true,
+  4887 => true,
+  4955 => true,
+  4956 => true,
+  4989 => true,
+  4990 => true,
+  4991 => true,
+  5018 => true,
+  5019 => true,
+  5020 => true,
+  5021 => true,
+  5022 => true,
+  5023 => true,
+  5110 => true,
+  5111 => true,
+  5118 => true,
+  5119 => true,
+  5760 => true,
+  5789 => true,
+  5790 => true,
+  5791 => true,
+  5881 => true,
+  5882 => true,
+  5883 => true,
+  5884 => true,
+  5885 => true,
+  5886 => true,
+  5887 => true,
+  5901 => true,
+  5909 => true,
+  5910 => true,
+  5911 => true,
+  5912 => true,
+  5913 => true,
+  5914 => true,
+  5915 => true,
+  5916 => true,
+  5917 => true,
+  5918 => true,
+  5919 => true,
+  5943 => true,
+  5944 => true,
+  5945 => true,
+  5946 => true,
+  5947 => true,
+  5948 => true,
+  5949 => true,
+  5950 => true,
+  5951 => true,
+  5972 => true,
+  5973 => true,
+  5974 => true,
+  5975 => true,
+  5976 => true,
+  5977 => true,
+  5978 => true,
+  5979 => true,
+  5980 => true,
+  5981 => true,
+  5982 => true,
+  5983 => true,
+  5997 => true,
+  6001 => true,
+  6004 => true,
+  6005 => true,
+  6006 => true,
+  6007 => true,
+  6008 => true,
+  6009 => true,
+  6010 => true,
+  6011 => true,
+  6012 => true,
+  6013 => true,
+  6014 => true,
+  6015 => true,
+  6068 => true,
+  6069 => true,
+  6110 => true,
+  6111 => true,
+  6122 => true,
+  6123 => true,
+  6124 => true,
+  6125 => true,
+  6126 => true,
+  6127 => true,
+  6138 => true,
+  6139 => true,
+  6140 => true,
+  6141 => true,
+  6142 => true,
+  6143 => true,
+  6150 => true,
+  6158 => true,
+  6159 => true,
+  6170 => true,
+  6171 => true,
+  6172 => true,
+  6173 => true,
+  6174 => true,
+  6175 => true,
+  6265 => true,
+  6266 => true,
+  6267 => true,
+  6268 => true,
+  6269 => true,
+  6270 => true,
+  6271 => true,
+  6315 => true,
+  6316 => true,
+  6317 => true,
+  6318 => true,
+  6319 => true,
+  6390 => true,
+  6391 => true,
+  6392 => true,
+  6393 => true,
+  6394 => true,
+  6395 => true,
+  6396 => true,
+  6397 => true,
+  6398 => true,
+  6399 => true,
+  6431 => true,
+  6444 => true,
+  6445 => true,
+  6446 => true,
+  6447 => true,
+  6460 => true,
+  6461 => true,
+  6462 => true,
+  6463 => true,
+  6465 => true,
+  6466 => true,
+  6467 => true,
+  6510 => true,
+  6511 => true,
+  6517 => true,
+  6518 => true,
+  6519 => true,
+  6520 => true,
+  6521 => true,
+  6522 => true,
+  6523 => true,
+  6524 => true,
+  6525 => true,
+  6526 => true,
+  6527 => true,
+  6572 => true,
+  6573 => true,
+  6574 => true,
+  6575 => true,
+  6602 => true,
+  6603 => true,
+  6604 => true,
+  6605 => true,
+  6606 => true,
+  6607 => true,
+  6619 => true,
+  6620 => true,
+  6621 => true,
+  6684 => true,
+  6685 => true,
+  6751 => true,
+  6781 => true,
+  6782 => true,
+  6794 => true,
+  6795 => true,
+  6796 => true,
+  6797 => true,
+  6798 => true,
+  6799 => true,
+  6810 => true,
+  6811 => true,
+  6812 => true,
+  6813 => true,
+  6814 => true,
+  6815 => true,
+  6830 => true,
+  6831 => true,
+  6988 => true,
+  6989 => true,
+  6990 => true,
+  6991 => true,
+  7037 => true,
+  7038 => true,
+  7039 => true,
+  7156 => true,
+  7157 => true,
+  7158 => true,
+  7159 => true,
+  7160 => true,
+  7161 => true,
+  7162 => true,
+  7163 => true,
+  7224 => true,
+  7225 => true,
+  7226 => true,
+  7242 => true,
+  7243 => true,
+  7244 => true,
+  7305 => true,
+  7306 => true,
+  7307 => true,
+  7308 => true,
+  7309 => true,
+  7310 => true,
+  7311 => true,
+  7355 => true,
+  7356 => true,
+  7368 => true,
+  7369 => true,
+  7370 => true,
+  7371 => true,
+  7372 => true,
+  7373 => true,
+  7374 => true,
+  7375 => true,
+  7419 => true,
+  7420 => true,
+  7421 => true,
+  7422 => true,
+  7423 => true,
+  7674 => true,
+  7958 => true,
+  7959 => true,
+  7966 => true,
+  7967 => true,
+  8006 => true,
+  8007 => true,
+  8014 => true,
+  8015 => true,
+  8024 => true,
+  8026 => true,
+  8028 => true,
+  8030 => true,
+  8062 => true,
+  8063 => true,
+  8117 => true,
+  8133 => true,
+  8148 => true,
+  8149 => true,
+  8156 => true,
+  8176 => true,
+  8177 => true,
+  8181 => true,
+  8191 => true,
+  8206 => true,
+  8207 => true,
+  8228 => true,
+  8229 => true,
+  8230 => true,
+  8232 => true,
+  8233 => true,
+  8234 => true,
+  8235 => true,
+  8236 => true,
+  8237 => true,
+  8238 => true,
+  8289 => true,
+  8290 => true,
+  8291 => true,
+  8293 => true,
+  8294 => true,
+  8295 => true,
+  8296 => true,
+  8297 => true,
+  8298 => true,
+  8299 => true,
+  8300 => true,
+  8301 => true,
+  8302 => true,
+  8303 => true,
+  8306 => true,
+  8307 => true,
+  8335 => true,
+  8349 => true,
+  8350 => true,
+  8351 => true,
+  8384 => true,
+  8385 => true,
+  8386 => true,
+  8387 => true,
+  8388 => true,
+  8389 => true,
+  8390 => true,
+  8391 => true,
+  8392 => true,
+  8393 => true,
+  8394 => true,
+  8395 => true,
+  8396 => true,
+  8397 => true,
+  8398 => true,
+  8399 => true,
+  8433 => true,
+  8434 => true,
+  8435 => true,
+  8436 => true,
+  8437 => true,
+  8438 => true,
+  8439 => true,
+  8440 => true,
+  8441 => true,
+  8442 => true,
+  8443 => true,
+  8444 => true,
+  8445 => true,
+  8446 => true,
+  8447 => true,
+  8498 => true,
+  8579 => true,
+  8588 => true,
+  8589 => true,
+  8590 => true,
+  8591 => true,
+  9255 => true,
+  9256 => true,
+  9257 => true,
+  9258 => true,
+  9259 => true,
+  9260 => true,
+  9261 => true,
+  9262 => true,
+  9263 => true,
+  9264 => true,
+  9265 => true,
+  9266 => true,
+  9267 => true,
+  9268 => true,
+  9269 => true,
+  9270 => true,
+  9271 => true,
+  9272 => true,
+  9273 => true,
+  9274 => true,
+  9275 => true,
+  9276 => true,
+  9277 => true,
+  9278 => true,
+  9279 => true,
+  9291 => true,
+  9292 => true,
+  9293 => true,
+  9294 => true,
+  9295 => true,
+  9296 => true,
+  9297 => true,
+  9298 => true,
+  9299 => true,
+  9300 => true,
+  9301 => true,
+  9302 => true,
+  9303 => true,
+  9304 => true,
+  9305 => true,
+  9306 => true,
+  9307 => true,
+  9308 => true,
+  9309 => true,
+  9310 => true,
+  9311 => true,
+  9352 => true,
+  9353 => true,
+  9354 => true,
+  9355 => true,
+  9356 => true,
+  9357 => true,
+  9358 => true,
+  9359 => true,
+  9360 => true,
+  9361 => true,
+  9362 => true,
+  9363 => true,
+  9364 => true,
+  9365 => true,
+  9366 => true,
+  9367 => true,
+  9368 => true,
+  9369 => true,
+  9370 => true,
+  9371 => true,
+  11124 => true,
+  11125 => true,
+  11158 => true,
+  11311 => true,
+  11359 => true,
+  11508 => true,
+  11509 => true,
+  11510 => true,
+  11511 => true,
+  11512 => true,
+  11558 => true,
+  11560 => true,
+  11561 => true,
+  11562 => true,
+  11563 => true,
+  11564 => true,
+  11566 => true,
+  11567 => true,
+  11624 => true,
+  11625 => true,
+  11626 => true,
+  11627 => true,
+  11628 => true,
+  11629 => true,
+  11630 => true,
+  11633 => true,
+  11634 => true,
+  11635 => true,
+  11636 => true,
+  11637 => true,
+  11638 => true,
+  11639 => true,
+  11640 => true,
+  11641 => true,
+  11642 => true,
+  11643 => true,
+  11644 => true,
+  11645 => true,
+  11646 => true,
+  11671 => true,
+  11672 => true,
+  11673 => true,
+  11674 => true,
+  11675 => true,
+  11676 => true,
+  11677 => true,
+  11678 => true,
+  11679 => true,
+  11687 => true,
+  11695 => true,
+  11703 => true,
+  11711 => true,
+  11719 => true,
+  11727 => true,
+  11735 => true,
+  11743 => true,
+  11930 => true,
+  12020 => true,
+  12021 => true,
+  12022 => true,
+  12023 => true,
+  12024 => true,
+  12025 => true,
+  12026 => true,
+  12027 => true,
+  12028 => true,
+  12029 => true,
+  12030 => true,
+  12031 => true,
+  12246 => true,
+  12247 => true,
+  12248 => true,
+  12249 => true,
+  12250 => true,
+  12251 => true,
+  12252 => true,
+  12253 => true,
+  12254 => true,
+  12255 => true,
+  12256 => true,
+  12257 => true,
+  12258 => true,
+  12259 => true,
+  12260 => true,
+  12261 => true,
+  12262 => true,
+  12263 => true,
+  12264 => true,
+  12265 => true,
+  12266 => true,
+  12267 => true,
+  12268 => true,
+  12269 => true,
+  12270 => true,
+  12271 => true,
+  12272 => true,
+  12273 => true,
+  12274 => true,
+  12275 => true,
+  12276 => true,
+  12277 => true,
+  12278 => true,
+  12279 => true,
+  12280 => true,
+  12281 => true,
+  12282 => true,
+  12283 => true,
+  12284 => true,
+  12285 => true,
+  12286 => true,
+  12287 => true,
+  12352 => true,
+  12439 => true,
+  12440 => true,
+  12544 => true,
+  12545 => true,
+  12546 => true,
+  12547 => true,
+  12548 => true,
+  12592 => true,
+  12644 => true,
+  12687 => true,
+  12772 => true,
+  12773 => true,
+  12774 => true,
+  12775 => true,
+  12776 => true,
+  12777 => true,
+  12778 => true,
+  12779 => true,
+  12780 => true,
+  12781 => true,
+  12782 => true,
+  12783 => true,
+  12831 => true,
+  13250 => true,
+  13255 => true,
+  13272 => true,
+  40957 => true,
+  40958 => true,
+  40959 => true,
+  42125 => true,
+  42126 => true,
+  42127 => true,
+  42183 => true,
+  42184 => true,
+  42185 => true,
+  42186 => true,
+  42187 => true,
+  42188 => true,
+  42189 => true,
+  42190 => true,
+  42191 => true,
+  42540 => true,
+  42541 => true,
+  42542 => true,
+  42543 => true,
+  42544 => true,
+  42545 => true,
+  42546 => true,
+  42547 => true,
+  42548 => true,
+  42549 => true,
+  42550 => true,
+  42551 => true,
+  42552 => true,
+  42553 => true,
+  42554 => true,
+  42555 => true,
+  42556 => true,
+  42557 => true,
+  42558 => true,
+  42559 => true,
+  42744 => true,
+  42745 => true,
+  42746 => true,
+  42747 => true,
+  42748 => true,
+  42749 => true,
+  42750 => true,
+  42751 => true,
+  42944 => true,
+  42945 => true,
+  43053 => true,
+  43054 => true,
+  43055 => true,
+  43066 => true,
+  43067 => true,
+  43068 => true,
+  43069 => true,
+  43070 => true,
+  43071 => true,
+  43128 => true,
+  43129 => true,
+  43130 => true,
+  43131 => true,
+  43132 => true,
+  43133 => true,
+  43134 => true,
+  43135 => true,
+  43206 => true,
+  43207 => true,
+  43208 => true,
+  43209 => true,
+  43210 => true,
+  43211 => true,
+  43212 => true,
+  43213 => true,
+  43226 => true,
+  43227 => true,
+  43228 => true,
+  43229 => true,
+  43230 => true,
+  43231 => true,
+  43348 => true,
+  43349 => true,
+  43350 => true,
+  43351 => true,
+  43352 => true,
+  43353 => true,
+  43354 => true,
+  43355 => true,
+  43356 => true,
+  43357 => true,
+  43358 => true,
+  43389 => true,
+  43390 => true,
+  43391 => true,
+  43470 => true,
+  43482 => true,
+  43483 => true,
+  43484 => true,
+  43485 => true,
+  43519 => true,
+  43575 => true,
+  43576 => true,
+  43577 => true,
+  43578 => true,
+  43579 => true,
+  43580 => true,
+  43581 => true,
+  43582 => true,
+  43583 => true,
+  43598 => true,
+  43599 => true,
+  43610 => true,
+  43611 => true,
+  43715 => true,
+  43716 => true,
+  43717 => true,
+  43718 => true,
+  43719 => true,
+  43720 => true,
+  43721 => true,
+  43722 => true,
+  43723 => true,
+  43724 => true,
+  43725 => true,
+  43726 => true,
+  43727 => true,
+  43728 => true,
+  43729 => true,
+  43730 => true,
+  43731 => true,
+  43732 => true,
+  43733 => true,
+  43734 => true,
+  43735 => true,
+  43736 => true,
+  43737 => true,
+  43738 => true,
+  43767 => true,
+  43768 => true,
+  43769 => true,
+  43770 => true,
+  43771 => true,
+  43772 => true,
+  43773 => true,
+  43774 => true,
+  43775 => true,
+  43776 => true,
+  43783 => true,
+  43784 => true,
+  43791 => true,
+  43792 => true,
+  43799 => true,
+  43800 => true,
+  43801 => true,
+  43802 => true,
+  43803 => true,
+  43804 => true,
+  43805 => true,
+  43806 => true,
+  43807 => true,
+  43815 => true,
+  43823 => true,
+  43884 => true,
+  43885 => true,
+  43886 => true,
+  43887 => true,
+  44014 => true,
+  44015 => true,
+  44026 => true,
+  44027 => true,
+  44028 => true,
+  44029 => true,
+  44030 => true,
+  44031 => true,
+  55204 => true,
+  55205 => true,
+  55206 => true,
+  55207 => true,
+  55208 => true,
+  55209 => true,
+  55210 => true,
+  55211 => true,
+  55212 => true,
+  55213 => true,
+  55214 => true,
+  55215 => true,
+  55239 => true,
+  55240 => true,
+  55241 => true,
+  55242 => true,
+  55292 => true,
+  55293 => true,
+  55294 => true,
+  55295 => true,
+  64110 => true,
+  64111 => true,
+  64263 => true,
+  64264 => true,
+  64265 => true,
+  64266 => true,
+  64267 => true,
+  64268 => true,
+  64269 => true,
+  64270 => true,
+  64271 => true,
+  64272 => true,
+  64273 => true,
+  64274 => true,
+  64280 => true,
+  64281 => true,
+  64282 => true,
+  64283 => true,
+  64284 => true,
+  64311 => true,
+  64317 => true,
+  64319 => true,
+  64322 => true,
+  64325 => true,
+  64450 => true,
+  64451 => true,
+  64452 => true,
+  64453 => true,
+  64454 => true,
+  64455 => true,
+  64456 => true,
+  64457 => true,
+  64458 => true,
+  64459 => true,
+  64460 => true,
+  64461 => true,
+  64462 => true,
+  64463 => true,
+  64464 => true,
+  64465 => true,
+  64466 => true,
+  64832 => true,
+  64833 => true,
+  64834 => true,
+  64835 => true,
+  64836 => true,
+  64837 => true,
+  64838 => true,
+  64839 => true,
+  64840 => true,
+  64841 => true,
+  64842 => true,
+  64843 => true,
+  64844 => true,
+  64845 => true,
+  64846 => true,
+  64847 => true,
+  64912 => true,
+  64913 => true,
+  64968 => true,
+  64969 => true,
+  64970 => true,
+  64971 => true,
+  64972 => true,
+  64973 => true,
+  64974 => true,
+  64975 => true,
+  65022 => true,
+  65023 => true,
+  65042 => true,
+  65049 => true,
+  65050 => true,
+  65051 => true,
+  65052 => true,
+  65053 => true,
+  65054 => true,
+  65055 => true,
+  65072 => true,
+  65106 => true,
+  65107 => true,
+  65127 => true,
+  65132 => true,
+  65133 => true,
+  65134 => true,
+  65135 => true,
+  65141 => true,
+  65277 => true,
+  65278 => true,
+  65280 => true,
+  65440 => true,
+  65471 => true,
+  65472 => true,
+  65473 => true,
+  65480 => true,
+  65481 => true,
+  65488 => true,
+  65489 => true,
+  65496 => true,
+  65497 => true,
+  65501 => true,
+  65502 => true,
+  65503 => true,
+  65511 => true,
+  65519 => true,
+  65520 => true,
+  65521 => true,
+  65522 => true,
+  65523 => true,
+  65524 => true,
+  65525 => true,
+  65526 => true,
+  65527 => true,
+  65528 => true,
+  65529 => true,
+  65530 => true,
+  65531 => true,
+  65532 => true,
+  65533 => true,
+  65534 => true,
+  65535 => true,
+  65548 => true,
+  65575 => true,
+  65595 => true,
+  65598 => true,
+  65614 => true,
+  65615 => true,
+  65787 => true,
+  65788 => true,
+  65789 => true,
+  65790 => true,
+  65791 => true,
+  65795 => true,
+  65796 => true,
+  65797 => true,
+  65798 => true,
+  65844 => true,
+  65845 => true,
+  65846 => true,
+  65935 => true,
+  65949 => true,
+  65950 => true,
+  65951 => true,
+  66205 => true,
+  66206 => true,
+  66207 => true,
+  66257 => true,
+  66258 => true,
+  66259 => true,
+  66260 => true,
+  66261 => true,
+  66262 => true,
+  66263 => true,
+  66264 => true,
+  66265 => true,
+  66266 => true,
+  66267 => true,
+  66268 => true,
+  66269 => true,
+  66270 => true,
+  66271 => true,
+  66300 => true,
+  66301 => true,
+  66302 => true,
+  66303 => true,
+  66340 => true,
+  66341 => true,
+  66342 => true,
+  66343 => true,
+  66344 => true,
+  66345 => true,
+  66346 => true,
+  66347 => true,
+  66348 => true,
+  66379 => true,
+  66380 => true,
+  66381 => true,
+  66382 => true,
+  66383 => true,
+  66427 => true,
+  66428 => true,
+  66429 => true,
+  66430 => true,
+  66431 => true,
+  66462 => true,
+  66500 => true,
+  66501 => true,
+  66502 => true,
+  66503 => true,
+  66718 => true,
+  66719 => true,
+  66730 => true,
+  66731 => true,
+  66732 => true,
+  66733 => true,
+  66734 => true,
+  66735 => true,
+  66772 => true,
+  66773 => true,
+  66774 => true,
+  66775 => true,
+  66812 => true,
+  66813 => true,
+  66814 => true,
+  66815 => true,
+  66856 => true,
+  66857 => true,
+  66858 => true,
+  66859 => true,
+  66860 => true,
+  66861 => true,
+  66862 => true,
+  66863 => true,
+  66916 => true,
+  66917 => true,
+  66918 => true,
+  66919 => true,
+  66920 => true,
+  66921 => true,
+  66922 => true,
+  66923 => true,
+  66924 => true,
+  66925 => true,
+  66926 => true,
+  67383 => true,
+  67384 => true,
+  67385 => true,
+  67386 => true,
+  67387 => true,
+  67388 => true,
+  67389 => true,
+  67390 => true,
+  67391 => true,
+  67414 => true,
+  67415 => true,
+  67416 => true,
+  67417 => true,
+  67418 => true,
+  67419 => true,
+  67420 => true,
+  67421 => true,
+  67422 => true,
+  67423 => true,
+  67590 => true,
+  67591 => true,
+  67593 => true,
+  67638 => true,
+  67641 => true,
+  67642 => true,
+  67643 => true,
+  67645 => true,
+  67646 => true,
+  67670 => true,
+  67743 => true,
+  67744 => true,
+  67745 => true,
+  67746 => true,
+  67747 => true,
+  67748 => true,
+  67749 => true,
+  67750 => true,
+  67827 => true,
+  67830 => true,
+  67831 => true,
+  67832 => true,
+  67833 => true,
+  67834 => true,
+  67868 => true,
+  67869 => true,
+  67870 => true,
+  67898 => true,
+  67899 => true,
+  67900 => true,
+  67901 => true,
+  67902 => true,
+  68024 => true,
+  68025 => true,
+  68026 => true,
+  68027 => true,
+  68048 => true,
+  68049 => true,
+  68100 => true,
+  68103 => true,
+  68104 => true,
+  68105 => true,
+  68106 => true,
+  68107 => true,
+  68116 => true,
+  68120 => true,
+  68150 => true,
+  68151 => true,
+  68155 => true,
+  68156 => true,
+  68157 => true,
+  68158 => true,
+  68169 => true,
+  68170 => true,
+  68171 => true,
+  68172 => true,
+  68173 => true,
+  68174 => true,
+  68175 => true,
+  68185 => true,
+  68186 => true,
+  68187 => true,
+  68188 => true,
+  68189 => true,
+  68190 => true,
+  68191 => true,
+  68327 => true,
+  68328 => true,
+  68329 => true,
+  68330 => true,
+  68343 => true,
+  68344 => true,
+  68345 => true,
+  68346 => true,
+  68347 => true,
+  68348 => true,
+  68349 => true,
+  68350 => true,
+  68351 => true,
+  68406 => true,
+  68407 => true,
+  68408 => true,
+  68438 => true,
+  68439 => true,
+  68467 => true,
+  68468 => true,
+  68469 => true,
+  68470 => true,
+  68471 => true,
+  68498 => true,
+  68499 => true,
+  68500 => true,
+  68501 => true,
+  68502 => true,
+  68503 => true,
+  68504 => true,
+  68509 => true,
+  68510 => true,
+  68511 => true,
+  68512 => true,
+  68513 => true,
+  68514 => true,
+  68515 => true,
+  68516 => true,
+  68517 => true,
+  68518 => true,
+  68519 => true,
+  68520 => true,
+  68787 => true,
+  68788 => true,
+  68789 => true,
+  68790 => true,
+  68791 => true,
+  68792 => true,
+  68793 => true,
+  68794 => true,
+  68795 => true,
+  68796 => true,
+  68797 => true,
+  68798 => true,
+  68799 => true,
+  68851 => true,
+  68852 => true,
+  68853 => true,
+  68854 => true,
+  68855 => true,
+  68856 => true,
+  68857 => true,
+  68904 => true,
+  68905 => true,
+  68906 => true,
+  68907 => true,
+  68908 => true,
+  68909 => true,
+  68910 => true,
+  68911 => true,
+  69247 => true,
+  69290 => true,
+  69294 => true,
+  69295 => true,
+  69416 => true,
+  69417 => true,
+  69418 => true,
+  69419 => true,
+  69420 => true,
+  69421 => true,
+  69422 => true,
+  69423 => true,
+  69580 => true,
+  69581 => true,
+  69582 => true,
+  69583 => true,
+  69584 => true,
+  69585 => true,
+  69586 => true,
+  69587 => true,
+  69588 => true,
+  69589 => true,
+  69590 => true,
+  69591 => true,
+  69592 => true,
+  69593 => true,
+  69594 => true,
+  69595 => true,
+  69596 => true,
+  69597 => true,
+  69598 => true,
+  69599 => true,
+  69623 => true,
+  69624 => true,
+  69625 => true,
+  69626 => true,
+  69627 => true,
+  69628 => true,
+  69629 => true,
+  69630 => true,
+  69631 => true,
+  69710 => true,
+  69711 => true,
+  69712 => true,
+  69713 => true,
+  69744 => true,
+  69745 => true,
+  69746 => true,
+  69747 => true,
+  69748 => true,
+  69749 => true,
+  69750 => true,
+  69751 => true,
+  69752 => true,
+  69753 => true,
+  69754 => true,
+  69755 => true,
+  69756 => true,
+  69757 => true,
+  69758 => true,
+  69821 => true,
+  69826 => true,
+  69827 => true,
+  69828 => true,
+  69829 => true,
+  69830 => true,
+  69831 => true,
+  69832 => true,
+  69833 => true,
+  69834 => true,
+  69835 => true,
+  69836 => true,
+  69837 => true,
+  69838 => true,
+  69839 => true,
+  69865 => true,
+  69866 => true,
+  69867 => true,
+  69868 => true,
+  69869 => true,
+  69870 => true,
+  69871 => true,
+  69882 => true,
+  69883 => true,
+  69884 => true,
+  69885 => true,
+  69886 => true,
+  69887 => true,
+  69941 => true,
+  69960 => true,
+  69961 => true,
+  69962 => true,
+  69963 => true,
+  69964 => true,
+  69965 => true,
+  69966 => true,
+  69967 => true,
+  70007 => true,
+  70008 => true,
+  70009 => true,
+  70010 => true,
+  70011 => true,
+  70012 => true,
+  70013 => true,
+  70014 => true,
+  70015 => true,
+  70112 => true,
+  70133 => true,
+  70134 => true,
+  70135 => true,
+  70136 => true,
+  70137 => true,
+  70138 => true,
+  70139 => true,
+  70140 => true,
+  70141 => true,
+  70142 => true,
+  70143 => true,
+  70162 => true,
+  70279 => true,
+  70281 => true,
+  70286 => true,
+  70302 => true,
+  70314 => true,
+  70315 => true,
+  70316 => true,
+  70317 => true,
+  70318 => true,
+  70319 => true,
+  70379 => true,
+  70380 => true,
+  70381 => true,
+  70382 => true,
+  70383 => true,
+  70394 => true,
+  70395 => true,
+  70396 => true,
+  70397 => true,
+  70398 => true,
+  70399 => true,
+  70404 => true,
+  70413 => true,
+  70414 => true,
+  70417 => true,
+  70418 => true,
+  70441 => true,
+  70449 => true,
+  70452 => true,
+  70458 => true,
+  70469 => true,
+  70470 => true,
+  70473 => true,
+  70474 => true,
+  70478 => true,
+  70479 => true,
+  70481 => true,
+  70482 => true,
+  70483 => true,
+  70484 => true,
+  70485 => true,
+  70486 => true,
+  70488 => true,
+  70489 => true,
+  70490 => true,
+  70491 => true,
+  70492 => true,
+  70500 => true,
+  70501 => true,
+  70509 => true,
+  70510 => true,
+  70511 => true,
+  70748 => true,
+  70754 => true,
+  70755 => true,
+  70756 => true,
+  70757 => true,
+  70758 => true,
+  70759 => true,
+  70760 => true,
+  70761 => true,
+  70762 => true,
+  70763 => true,
+  70764 => true,
+  70765 => true,
+  70766 => true,
+  70767 => true,
+  70768 => true,
+  70769 => true,
+  70770 => true,
+  70771 => true,
+  70772 => true,
+  70773 => true,
+  70774 => true,
+  70775 => true,
+  70776 => true,
+  70777 => true,
+  70778 => true,
+  70779 => true,
+  70780 => true,
+  70781 => true,
+  70782 => true,
+  70783 => true,
+  70856 => true,
+  70857 => true,
+  70858 => true,
+  70859 => true,
+  70860 => true,
+  70861 => true,
+  70862 => true,
+  70863 => true,
+  71094 => true,
+  71095 => true,
+  71237 => true,
+  71238 => true,
+  71239 => true,
+  71240 => true,
+  71241 => true,
+  71242 => true,
+  71243 => true,
+  71244 => true,
+  71245 => true,
+  71246 => true,
+  71247 => true,
+  71258 => true,
+  71259 => true,
+  71260 => true,
+  71261 => true,
+  71262 => true,
+  71263 => true,
+  71277 => true,
+  71278 => true,
+  71279 => true,
+  71280 => true,
+  71281 => true,
+  71282 => true,
+  71283 => true,
+  71284 => true,
+  71285 => true,
+  71286 => true,
+  71287 => true,
+  71288 => true,
+  71289 => true,
+  71290 => true,
+  71291 => true,
+  71292 => true,
+  71293 => true,
+  71294 => true,
+  71295 => true,
+  71353 => true,
+  71354 => true,
+  71355 => true,
+  71356 => true,
+  71357 => true,
+  71358 => true,
+  71359 => true,
+  71451 => true,
+  71452 => true,
+  71468 => true,
+  71469 => true,
+  71470 => true,
+  71471 => true,
+  71923 => true,
+  71924 => true,
+  71925 => true,
+  71926 => true,
+  71927 => true,
+  71928 => true,
+  71929 => true,
+  71930 => true,
+  71931 => true,
+  71932 => true,
+  71933 => true,
+  71934 => true,
+  71943 => true,
+  71944 => true,
+  71946 => true,
+  71947 => true,
+  71956 => true,
+  71959 => true,
+  71990 => true,
+  71993 => true,
+  71994 => true,
+  72007 => true,
+  72008 => true,
+  72009 => true,
+  72010 => true,
+  72011 => true,
+  72012 => true,
+  72013 => true,
+  72014 => true,
+  72015 => true,
+  72104 => true,
+  72105 => true,
+  72152 => true,
+  72153 => true,
+  72165 => true,
+  72166 => true,
+  72167 => true,
+  72168 => true,
+  72169 => true,
+  72170 => true,
+  72171 => true,
+  72172 => true,
+  72173 => true,
+  72174 => true,
+  72175 => true,
+  72176 => true,
+  72177 => true,
+  72178 => true,
+  72179 => true,
+  72180 => true,
+  72181 => true,
+  72182 => true,
+  72183 => true,
+  72184 => true,
+  72185 => true,
+  72186 => true,
+  72187 => true,
+  72188 => true,
+  72189 => true,
+  72190 => true,
+  72191 => true,
+  72264 => true,
+  72265 => true,
+  72266 => true,
+  72267 => true,
+  72268 => true,
+  72269 => true,
+  72270 => true,
+  72271 => true,
+  72355 => true,
+  72356 => true,
+  72357 => true,
+  72358 => true,
+  72359 => true,
+  72360 => true,
+  72361 => true,
+  72362 => true,
+  72363 => true,
+  72364 => true,
+  72365 => true,
+  72366 => true,
+  72367 => true,
+  72368 => true,
+  72369 => true,
+  72370 => true,
+  72371 => true,
+  72372 => true,
+  72373 => true,
+  72374 => true,
+  72375 => true,
+  72376 => true,
+  72377 => true,
+  72378 => true,
+  72379 => true,
+  72380 => true,
+  72381 => true,
+  72382 => true,
+  72383 => true,
+  72713 => true,
+  72759 => true,
+  72774 => true,
+  72775 => true,
+  72776 => true,
+  72777 => true,
+  72778 => true,
+  72779 => true,
+  72780 => true,
+  72781 => true,
+  72782 => true,
+  72783 => true,
+  72813 => true,
+  72814 => true,
+  72815 => true,
+  72848 => true,
+  72849 => true,
+  72872 => true,
+  72967 => true,
+  72970 => true,
+  73015 => true,
+  73016 => true,
+  73017 => true,
+  73019 => true,
+  73022 => true,
+  73032 => true,
+  73033 => true,
+  73034 => true,
+  73035 => true,
+  73036 => true,
+  73037 => true,
+  73038 => true,
+  73039 => true,
+  73050 => true,
+  73051 => true,
+  73052 => true,
+  73053 => true,
+  73054 => true,
+  73055 => true,
+  73062 => true,
+  73065 => true,
+  73103 => true,
+  73106 => true,
+  73113 => true,
+  73114 => true,
+  73115 => true,
+  73116 => true,
+  73117 => true,
+  73118 => true,
+  73119 => true,
+  73649 => true,
+  73650 => true,
+  73651 => true,
+  73652 => true,
+  73653 => true,
+  73654 => true,
+  73655 => true,
+  73656 => true,
+  73657 => true,
+  73658 => true,
+  73659 => true,
+  73660 => true,
+  73661 => true,
+  73662 => true,
+  73663 => true,
+  73714 => true,
+  73715 => true,
+  73716 => true,
+  73717 => true,
+  73718 => true,
+  73719 => true,
+  73720 => true,
+  73721 => true,
+  73722 => true,
+  73723 => true,
+  73724 => true,
+  73725 => true,
+  73726 => true,
+  74863 => true,
+  74869 => true,
+  74870 => true,
+  74871 => true,
+  74872 => true,
+  74873 => true,
+  74874 => true,
+  74875 => true,
+  74876 => true,
+  74877 => true,
+  74878 => true,
+  74879 => true,
+  78895 => true,
+  78896 => true,
+  78897 => true,
+  78898 => true,
+  78899 => true,
+  78900 => true,
+  78901 => true,
+  78902 => true,
+  78903 => true,
+  78904 => true,
+  92729 => true,
+  92730 => true,
+  92731 => true,
+  92732 => true,
+  92733 => true,
+  92734 => true,
+  92735 => true,
+  92767 => true,
+  92778 => true,
+  92779 => true,
+  92780 => true,
+  92781 => true,
+  92910 => true,
+  92911 => true,
+  92918 => true,
+  92919 => true,
+  92920 => true,
+  92921 => true,
+  92922 => true,
+  92923 => true,
+  92924 => true,
+  92925 => true,
+  92926 => true,
+  92927 => true,
+  92998 => true,
+  92999 => true,
+  93000 => true,
+  93001 => true,
+  93002 => true,
+  93003 => true,
+  93004 => true,
+  93005 => true,
+  93006 => true,
+  93007 => true,
+  93018 => true,
+  93026 => true,
+  93048 => true,
+  93049 => true,
+  93050 => true,
+  93051 => true,
+  93052 => true,
+  94027 => true,
+  94028 => true,
+  94029 => true,
+  94030 => true,
+  94088 => true,
+  94089 => true,
+  94090 => true,
+  94091 => true,
+  94092 => true,
+  94093 => true,
+  94094 => true,
+  94181 => true,
+  94182 => true,
+  94183 => true,
+  94184 => true,
+  94185 => true,
+  94186 => true,
+  94187 => true,
+  94188 => true,
+  94189 => true,
+  94190 => true,
+  94191 => true,
+  94194 => true,
+  94195 => true,
+  94196 => true,
+  94197 => true,
+  94198 => true,
+  94199 => true,
+  94200 => true,
+  94201 => true,
+  94202 => true,
+  94203 => true,
+  94204 => true,
+  94205 => true,
+  94206 => true,
+  94207 => true,
+  100344 => true,
+  100345 => true,
+  100346 => true,
+  100347 => true,
+  100348 => true,
+  100349 => true,
+  100350 => true,
+  100351 => true,
+  110931 => true,
+  110932 => true,
+  110933 => true,
+  110934 => true,
+  110935 => true,
+  110936 => true,
+  110937 => true,
+  110938 => true,
+  110939 => true,
+  110940 => true,
+  110941 => true,
+  110942 => true,
+  110943 => true,
+  110944 => true,
+  110945 => true,
+  110946 => true,
+  110947 => true,
+  110952 => true,
+  110953 => true,
+  110954 => true,
+  110955 => true,
+  110956 => true,
+  110957 => true,
+  110958 => true,
+  110959 => true,
+  113771 => true,
+  113772 => true,
+  113773 => true,
+  113774 => true,
+  113775 => true,
+  113789 => true,
+  113790 => true,
+  113791 => true,
+  113801 => true,
+  113802 => true,
+  113803 => true,
+  113804 => true,
+  113805 => true,
+  113806 => true,
+  113807 => true,
+  113818 => true,
+  113819 => true,
+  119030 => true,
+  119031 => true,
+  119032 => true,
+  119033 => true,
+  119034 => true,
+  119035 => true,
+  119036 => true,
+  119037 => true,
+  119038 => true,
+  119039 => true,
+  119079 => true,
+  119080 => true,
+  119155 => true,
+  119156 => true,
+  119157 => true,
+  119158 => true,
+  119159 => true,
+  119160 => true,
+  119161 => true,
+  119162 => true,
+  119273 => true,
+  119274 => true,
+  119275 => true,
+  119276 => true,
+  119277 => true,
+  119278 => true,
+  119279 => true,
+  119280 => true,
+  119281 => true,
+  119282 => true,
+  119283 => true,
+  119284 => true,
+  119285 => true,
+  119286 => true,
+  119287 => true,
+  119288 => true,
+  119289 => true,
+  119290 => true,
+  119291 => true,
+  119292 => true,
+  119293 => true,
+  119294 => true,
+  119295 => true,
+  119540 => true,
+  119541 => true,
+  119542 => true,
+  119543 => true,
+  119544 => true,
+  119545 => true,
+  119546 => true,
+  119547 => true,
+  119548 => true,
+  119549 => true,
+  119550 => true,
+  119551 => true,
+  119639 => true,
+  119640 => true,
+  119641 => true,
+  119642 => true,
+  119643 => true,
+  119644 => true,
+  119645 => true,
+  119646 => true,
+  119647 => true,
+  119893 => true,
+  119965 => true,
+  119968 => true,
+  119969 => true,
+  119971 => true,
+  119972 => true,
+  119975 => true,
+  119976 => true,
+  119981 => true,
+  119994 => true,
+  119996 => true,
+  120004 => true,
+  120070 => true,
+  120075 => true,
+  120076 => true,
+  120085 => true,
+  120093 => true,
+  120122 => true,
+  120127 => true,
+  120133 => true,
+  120135 => true,
+  120136 => true,
+  120137 => true,
+  120145 => true,
+  120486 => true,
+  120487 => true,
+  120780 => true,
+  120781 => true,
+  121484 => true,
+  121485 => true,
+  121486 => true,
+  121487 => true,
+  121488 => true,
+  121489 => true,
+  121490 => true,
+  121491 => true,
+  121492 => true,
+  121493 => true,
+  121494 => true,
+  121495 => true,
+  121496 => true,
+  121497 => true,
+  121498 => true,
+  121504 => true,
+  122887 => true,
+  122905 => true,
+  122906 => true,
+  122914 => true,
+  122917 => true,
+  123181 => true,
+  123182 => true,
+  123183 => true,
+  123198 => true,
+  123199 => true,
+  123210 => true,
+  123211 => true,
+  123212 => true,
+  123213 => true,
+  123642 => true,
+  123643 => true,
+  123644 => true,
+  123645 => true,
+  123646 => true,
+  125125 => true,
+  125126 => true,
+  125260 => true,
+  125261 => true,
+  125262 => true,
+  125263 => true,
+  125274 => true,
+  125275 => true,
+  125276 => true,
+  125277 => true,
+  126468 => true,
+  126496 => true,
+  126499 => true,
+  126501 => true,
+  126502 => true,
+  126504 => true,
+  126515 => true,
+  126520 => true,
+  126522 => true,
+  126524 => true,
+  126525 => true,
+  126526 => true,
+  126527 => true,
+  126528 => true,
+  126529 => true,
+  126531 => true,
+  126532 => true,
+  126533 => true,
+  126534 => true,
+  126536 => true,
+  126538 => true,
+  126540 => true,
+  126544 => true,
+  126547 => true,
+  126549 => true,
+  126550 => true,
+  126552 => true,
+  126554 => true,
+  126556 => true,
+  126558 => true,
+  126560 => true,
+  126563 => true,
+  126565 => true,
+  126566 => true,
+  126571 => true,
+  126579 => true,
+  126584 => true,
+  126589 => true,
+  126591 => true,
+  126602 => true,
+  126620 => true,
+  126621 => true,
+  126622 => true,
+  126623 => true,
+  126624 => true,
+  126628 => true,
+  126634 => true,
+  127020 => true,
+  127021 => true,
+  127022 => true,
+  127023 => true,
+  127124 => true,
+  127125 => true,
+  127126 => true,
+  127127 => true,
+  127128 => true,
+  127129 => true,
+  127130 => true,
+  127131 => true,
+  127132 => true,
+  127133 => true,
+  127134 => true,
+  127135 => true,
+  127151 => true,
+  127152 => true,
+  127168 => true,
+  127184 => true,
+  127222 => true,
+  127223 => true,
+  127224 => true,
+  127225 => true,
+  127226 => true,
+  127227 => true,
+  127228 => true,
+  127229 => true,
+  127230 => true,
+  127231 => true,
+  127232 => true,
+  127491 => true,
+  127492 => true,
+  127493 => true,
+  127494 => true,
+  127495 => true,
+  127496 => true,
+  127497 => true,
+  127498 => true,
+  127499 => true,
+  127500 => true,
+  127501 => true,
+  127502 => true,
+  127503 => true,
+  127548 => true,
+  127549 => true,
+  127550 => true,
+  127551 => true,
+  127561 => true,
+  127562 => true,
+  127563 => true,
+  127564 => true,
+  127565 => true,
+  127566 => true,
+  127567 => true,
+  127570 => true,
+  127571 => true,
+  127572 => true,
+  127573 => true,
+  127574 => true,
+  127575 => true,
+  127576 => true,
+  127577 => true,
+  127578 => true,
+  127579 => true,
+  127580 => true,
+  127581 => true,
+  127582 => true,
+  127583 => true,
+  128728 => true,
+  128729 => true,
+  128730 => true,
+  128731 => true,
+  128732 => true,
+  128733 => true,
+  128734 => true,
+  128735 => true,
+  128749 => true,
+  128750 => true,
+  128751 => true,
+  128765 => true,
+  128766 => true,
+  128767 => true,
+  128884 => true,
+  128885 => true,
+  128886 => true,
+  128887 => true,
+  128888 => true,
+  128889 => true,
+  128890 => true,
+  128891 => true,
+  128892 => true,
+  128893 => true,
+  128894 => true,
+  128895 => true,
+  128985 => true,
+  128986 => true,
+  128987 => true,
+  128988 => true,
+  128989 => true,
+  128990 => true,
+  128991 => true,
+  129004 => true,
+  129005 => true,
+  129006 => true,
+  129007 => true,
+  129008 => true,
+  129009 => true,
+  129010 => true,
+  129011 => true,
+  129012 => true,
+  129013 => true,
+  129014 => true,
+  129015 => true,
+  129016 => true,
+  129017 => true,
+  129018 => true,
+  129019 => true,
+  129020 => true,
+  129021 => true,
+  129022 => true,
+  129023 => true,
+  129036 => true,
+  129037 => true,
+  129038 => true,
+  129039 => true,
+  129096 => true,
+  129097 => true,
+  129098 => true,
+  129099 => true,
+  129100 => true,
+  129101 => true,
+  129102 => true,
+  129103 => true,
+  129114 => true,
+  129115 => true,
+  129116 => true,
+  129117 => true,
+  129118 => true,
+  129119 => true,
+  129160 => true,
+  129161 => true,
+  129162 => true,
+  129163 => true,
+  129164 => true,
+  129165 => true,
+  129166 => true,
+  129167 => true,
+  129198 => true,
+  129199 => true,
+  129401 => true,
+  129484 => true,
+  129620 => true,
+  129621 => true,
+  129622 => true,
+  129623 => true,
+  129624 => true,
+  129625 => true,
+  129626 => true,
+  129627 => true,
+  129628 => true,
+  129629 => true,
+  129630 => true,
+  129631 => true,
+  129646 => true,
+  129647 => true,
+  129653 => true,
+  129654 => true,
+  129655 => true,
+  129659 => true,
+  129660 => true,
+  129661 => true,
+  129662 => true,
+  129663 => true,
+  129671 => true,
+  129672 => true,
+  129673 => true,
+  129674 => true,
+  129675 => true,
+  129676 => true,
+  129677 => true,
+  129678 => true,
+  129679 => true,
+  129705 => true,
+  129706 => true,
+  129707 => true,
+  129708 => true,
+  129709 => true,
+  129710 => true,
+  129711 => true,
+  129719 => true,
+  129720 => true,
+  129721 => true,
+  129722 => true,
+  129723 => true,
+  129724 => true,
+  129725 => true,
+  129726 => true,
+  129727 => true,
+  129731 => true,
+  129732 => true,
+  129733 => true,
+  129734 => true,
+  129735 => true,
+  129736 => true,
+  129737 => true,
+  129738 => true,
+  129739 => true,
+  129740 => true,
+  129741 => true,
+  129742 => true,
+  129743 => true,
+  129939 => true,
+  131070 => true,
+  131071 => true,
+  177973 => true,
+  177974 => true,
+  177975 => true,
+  177976 => true,
+  177977 => true,
+  177978 => true,
+  177979 => true,
+  177980 => true,
+  177981 => true,
+  177982 => true,
+  177983 => true,
+  178206 => true,
+  178207 => true,
+  183970 => true,
+  183971 => true,
+  183972 => true,
+  183973 => true,
+  183974 => true,
+  183975 => true,
+  183976 => true,
+  183977 => true,
+  183978 => true,
+  183979 => true,
+  183980 => true,
+  183981 => true,
+  183982 => true,
+  183983 => true,
+  194664 => true,
+  194676 => true,
+  194847 => true,
+  194911 => true,
+  195007 => true,
+  196606 => true,
+  196607 => true,
+  262142 => true,
+  262143 => true,
+  327678 => true,
+  327679 => true,
+  393214 => true,
+  393215 => true,
+  458750 => true,
+  458751 => true,
+  524286 => true,
+  524287 => true,
+  589822 => true,
+  589823 => true,
+  655358 => true,
+  655359 => true,
+  720894 => true,
+  720895 => true,
+  786430 => true,
+  786431 => true,
+  851966 => true,
+  851967 => true,
+  917502 => true,
+  917503 => true,
+  917504 => true,
+  917505 => true,
+  917506 => true,
+  917507 => true,
+  917508 => true,
+  917509 => true,
+  917510 => true,
+  917511 => true,
+  917512 => true,
+  917513 => true,
+  917514 => true,
+  917515 => true,
+  917516 => true,
+  917517 => true,
+  917518 => true,
+  917519 => true,
+  917520 => true,
+  917521 => true,
+  917522 => true,
+  917523 => true,
+  917524 => true,
+  917525 => true,
+  917526 => true,
+  917527 => true,
+  917528 => true,
+  917529 => true,
+  917530 => true,
+  917531 => true,
+  917532 => true,
+  917533 => true,
+  917534 => true,
+  917535 => true,
+  983038 => true,
+  983039 => true,
+  1048574 => true,
+  1048575 => true,
+  1114110 => true,
+  1114111 => true,
+);
diff --git a/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php b/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php
new file mode 100644
index 000000000..54f21cc0c
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php
@@ -0,0 +1,308 @@
+ ' ',
+  168 => ' ̈',
+  175 => ' ̄',
+  180 => ' ́',
+  184 => ' ̧',
+  728 => ' ̆',
+  729 => ' ̇',
+  730 => ' ̊',
+  731 => ' ̨',
+  732 => ' ̃',
+  733 => ' ̋',
+  890 => ' ι',
+  894 => ';',
+  900 => ' ́',
+  901 => ' ̈́',
+  8125 => ' ̓',
+  8127 => ' ̓',
+  8128 => ' ͂',
+  8129 => ' ̈͂',
+  8141 => ' ̓̀',
+  8142 => ' ̓́',
+  8143 => ' ̓͂',
+  8157 => ' ̔̀',
+  8158 => ' ̔́',
+  8159 => ' ̔͂',
+  8173 => ' ̈̀',
+  8174 => ' ̈́',
+  8175 => '`',
+  8189 => ' ́',
+  8190 => ' ̔',
+  8192 => ' ',
+  8193 => ' ',
+  8194 => ' ',
+  8195 => ' ',
+  8196 => ' ',
+  8197 => ' ',
+  8198 => ' ',
+  8199 => ' ',
+  8200 => ' ',
+  8201 => ' ',
+  8202 => ' ',
+  8215 => ' ̳',
+  8239 => ' ',
+  8252 => '!!',
+  8254 => ' ̅',
+  8263 => '??',
+  8264 => '?!',
+  8265 => '!?',
+  8287 => ' ',
+  8314 => '+',
+  8316 => '=',
+  8317 => '(',
+  8318 => ')',
+  8330 => '+',
+  8332 => '=',
+  8333 => '(',
+  8334 => ')',
+  8448 => 'a/c',
+  8449 => 'a/s',
+  8453 => 'c/o',
+  8454 => 'c/u',
+  9332 => '(1)',
+  9333 => '(2)',
+  9334 => '(3)',
+  9335 => '(4)',
+  9336 => '(5)',
+  9337 => '(6)',
+  9338 => '(7)',
+  9339 => '(8)',
+  9340 => '(9)',
+  9341 => '(10)',
+  9342 => '(11)',
+  9343 => '(12)',
+  9344 => '(13)',
+  9345 => '(14)',
+  9346 => '(15)',
+  9347 => '(16)',
+  9348 => '(17)',
+  9349 => '(18)',
+  9350 => '(19)',
+  9351 => '(20)',
+  9372 => '(a)',
+  9373 => '(b)',
+  9374 => '(c)',
+  9375 => '(d)',
+  9376 => '(e)',
+  9377 => '(f)',
+  9378 => '(g)',
+  9379 => '(h)',
+  9380 => '(i)',
+  9381 => '(j)',
+  9382 => '(k)',
+  9383 => '(l)',
+  9384 => '(m)',
+  9385 => '(n)',
+  9386 => '(o)',
+  9387 => '(p)',
+  9388 => '(q)',
+  9389 => '(r)',
+  9390 => '(s)',
+  9391 => '(t)',
+  9392 => '(u)',
+  9393 => '(v)',
+  9394 => '(w)',
+  9395 => '(x)',
+  9396 => '(y)',
+  9397 => '(z)',
+  10868 => '::=',
+  10869 => '==',
+  10870 => '===',
+  12288 => ' ',
+  12443 => ' ゙',
+  12444 => ' ゚',
+  12800 => '(ᄀ)',
+  12801 => '(ᄂ)',
+  12802 => '(ᄃ)',
+  12803 => '(ᄅ)',
+  12804 => '(ᄆ)',
+  12805 => '(ᄇ)',
+  12806 => '(ᄉ)',
+  12807 => '(ᄋ)',
+  12808 => '(ᄌ)',
+  12809 => '(ᄎ)',
+  12810 => '(ᄏ)',
+  12811 => '(ᄐ)',
+  12812 => '(ᄑ)',
+  12813 => '(ᄒ)',
+  12814 => '(가)',
+  12815 => '(나)',
+  12816 => '(다)',
+  12817 => '(라)',
+  12818 => '(마)',
+  12819 => '(바)',
+  12820 => '(사)',
+  12821 => '(아)',
+  12822 => '(자)',
+  12823 => '(차)',
+  12824 => '(카)',
+  12825 => '(타)',
+  12826 => '(파)',
+  12827 => '(하)',
+  12828 => '(주)',
+  12829 => '(오전)',
+  12830 => '(오후)',
+  12832 => '(一)',
+  12833 => '(二)',
+  12834 => '(三)',
+  12835 => '(四)',
+  12836 => '(五)',
+  12837 => '(六)',
+  12838 => '(七)',
+  12839 => '(八)',
+  12840 => '(九)',
+  12841 => '(十)',
+  12842 => '(月)',
+  12843 => '(火)',
+  12844 => '(水)',
+  12845 => '(木)',
+  12846 => '(金)',
+  12847 => '(土)',
+  12848 => '(日)',
+  12849 => '(株)',
+  12850 => '(有)',
+  12851 => '(社)',
+  12852 => '(名)',
+  12853 => '(特)',
+  12854 => '(財)',
+  12855 => '(祝)',
+  12856 => '(労)',
+  12857 => '(代)',
+  12858 => '(呼)',
+  12859 => '(学)',
+  12860 => '(監)',
+  12861 => '(企)',
+  12862 => '(資)',
+  12863 => '(協)',
+  12864 => '(祭)',
+  12865 => '(休)',
+  12866 => '(自)',
+  12867 => '(至)',
+  64297 => '+',
+  64606 => ' ٌّ',
+  64607 => ' ٍّ',
+  64608 => ' َّ',
+  64609 => ' ُّ',
+  64610 => ' ِّ',
+  64611 => ' ّٰ',
+  65018 => 'صلى الله عليه وسلم',
+  65019 => 'جل جلاله',
+  65040 => ',',
+  65043 => ':',
+  65044 => ';',
+  65045 => '!',
+  65046 => '?',
+  65075 => '_',
+  65076 => '_',
+  65077 => '(',
+  65078 => ')',
+  65079 => '{',
+  65080 => '}',
+  65095 => '[',
+  65096 => ']',
+  65097 => ' ̅',
+  65098 => ' ̅',
+  65099 => ' ̅',
+  65100 => ' ̅',
+  65101 => '_',
+  65102 => '_',
+  65103 => '_',
+  65104 => ',',
+  65108 => ';',
+  65109 => ':',
+  65110 => '?',
+  65111 => '!',
+  65113 => '(',
+  65114 => ')',
+  65115 => '{',
+  65116 => '}',
+  65119 => '#',
+  65120 => '&',
+  65121 => '*',
+  65122 => '+',
+  65124 => '<',
+  65125 => '>',
+  65126 => '=',
+  65128 => '\\',
+  65129 => '$',
+  65130 => '%',
+  65131 => '@',
+  65136 => ' ً',
+  65138 => ' ٌ',
+  65140 => ' ٍ',
+  65142 => ' َ',
+  65144 => ' ُ',
+  65146 => ' ِ',
+  65148 => ' ّ',
+  65150 => ' ْ',
+  65281 => '!',
+  65282 => '"',
+  65283 => '#',
+  65284 => '$',
+  65285 => '%',
+  65286 => '&',
+  65287 => '\'',
+  65288 => '(',
+  65289 => ')',
+  65290 => '*',
+  65291 => '+',
+  65292 => ',',
+  65295 => '/',
+  65306 => ':',
+  65307 => ';',
+  65308 => '<',
+  65309 => '=',
+  65310 => '>',
+  65311 => '?',
+  65312 => '@',
+  65339 => '[',
+  65340 => '\\',
+  65341 => ']',
+  65342 => '^',
+  65343 => '_',
+  65344 => '`',
+  65371 => '{',
+  65372 => '|',
+  65373 => '}',
+  65374 => '~',
+  65507 => ' ̄',
+  127233 => '0,',
+  127234 => '1,',
+  127235 => '2,',
+  127236 => '3,',
+  127237 => '4,',
+  127238 => '5,',
+  127239 => '6,',
+  127240 => '7,',
+  127241 => '8,',
+  127242 => '9,',
+  127248 => '(a)',
+  127249 => '(b)',
+  127250 => '(c)',
+  127251 => '(d)',
+  127252 => '(e)',
+  127253 => '(f)',
+  127254 => '(g)',
+  127255 => '(h)',
+  127256 => '(i)',
+  127257 => '(j)',
+  127258 => '(k)',
+  127259 => '(l)',
+  127260 => '(m)',
+  127261 => '(n)',
+  127262 => '(o)',
+  127263 => '(p)',
+  127264 => '(q)',
+  127265 => '(r)',
+  127266 => '(s)',
+  127267 => '(t)',
+  127268 => '(u)',
+  127269 => '(v)',
+  127270 => '(w)',
+  127271 => '(x)',
+  127272 => '(y)',
+  127273 => '(z)',
+);
diff --git a/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php b/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php
new file mode 100644
index 000000000..223396ec4
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php
@@ -0,0 +1,71 @@
+ true,
+  1 => true,
+  2 => true,
+  3 => true,
+  4 => true,
+  5 => true,
+  6 => true,
+  7 => true,
+  8 => true,
+  9 => true,
+  10 => true,
+  11 => true,
+  12 => true,
+  13 => true,
+  14 => true,
+  15 => true,
+  16 => true,
+  17 => true,
+  18 => true,
+  19 => true,
+  20 => true,
+  21 => true,
+  22 => true,
+  23 => true,
+  24 => true,
+  25 => true,
+  26 => true,
+  27 => true,
+  28 => true,
+  29 => true,
+  30 => true,
+  31 => true,
+  32 => true,
+  33 => true,
+  34 => true,
+  35 => true,
+  36 => true,
+  37 => true,
+  38 => true,
+  39 => true,
+  40 => true,
+  41 => true,
+  42 => true,
+  43 => true,
+  44 => true,
+  47 => true,
+  58 => true,
+  59 => true,
+  60 => true,
+  61 => true,
+  62 => true,
+  63 => true,
+  64 => true,
+  91 => true,
+  92 => true,
+  93 => true,
+  94 => true,
+  95 => true,
+  96 => true,
+  123 => true,
+  124 => true,
+  125 => true,
+  126 => true,
+  127 => true,
+  8800 => true,
+  8814 => true,
+  8815 => true,
+);
diff --git a/vendor/symfony/polyfill-intl-idn/Resources/unidata/ignored.php b/vendor/symfony/polyfill-intl-idn/Resources/unidata/ignored.php
new file mode 100644
index 000000000..b37784413
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-idn/Resources/unidata/ignored.php
@@ -0,0 +1,273 @@
+ true,
+  847 => true,
+  6155 => true,
+  6156 => true,
+  6157 => true,
+  8203 => true,
+  8288 => true,
+  8292 => true,
+  65024 => true,
+  65025 => true,
+  65026 => true,
+  65027 => true,
+  65028 => true,
+  65029 => true,
+  65030 => true,
+  65031 => true,
+  65032 => true,
+  65033 => true,
+  65034 => true,
+  65035 => true,
+  65036 => true,
+  65037 => true,
+  65038 => true,
+  65039 => true,
+  65279 => true,
+  113824 => true,
+  113825 => true,
+  113826 => true,
+  113827 => true,
+  917760 => true,
+  917761 => true,
+  917762 => true,
+  917763 => true,
+  917764 => true,
+  917765 => true,
+  917766 => true,
+  917767 => true,
+  917768 => true,
+  917769 => true,
+  917770 => true,
+  917771 => true,
+  917772 => true,
+  917773 => true,
+  917774 => true,
+  917775 => true,
+  917776 => true,
+  917777 => true,
+  917778 => true,
+  917779 => true,
+  917780 => true,
+  917781 => true,
+  917782 => true,
+  917783 => true,
+  917784 => true,
+  917785 => true,
+  917786 => true,
+  917787 => true,
+  917788 => true,
+  917789 => true,
+  917790 => true,
+  917791 => true,
+  917792 => true,
+  917793 => true,
+  917794 => true,
+  917795 => true,
+  917796 => true,
+  917797 => true,
+  917798 => true,
+  917799 => true,
+  917800 => true,
+  917801 => true,
+  917802 => true,
+  917803 => true,
+  917804 => true,
+  917805 => true,
+  917806 => true,
+  917807 => true,
+  917808 => true,
+  917809 => true,
+  917810 => true,
+  917811 => true,
+  917812 => true,
+  917813 => true,
+  917814 => true,
+  917815 => true,
+  917816 => true,
+  917817 => true,
+  917818 => true,
+  917819 => true,
+  917820 => true,
+  917821 => true,
+  917822 => true,
+  917823 => true,
+  917824 => true,
+  917825 => true,
+  917826 => true,
+  917827 => true,
+  917828 => true,
+  917829 => true,
+  917830 => true,
+  917831 => true,
+  917832 => true,
+  917833 => true,
+  917834 => true,
+  917835 => true,
+  917836 => true,
+  917837 => true,
+  917838 => true,
+  917839 => true,
+  917840 => true,
+  917841 => true,
+  917842 => true,
+  917843 => true,
+  917844 => true,
+  917845 => true,
+  917846 => true,
+  917847 => true,
+  917848 => true,
+  917849 => true,
+  917850 => true,
+  917851 => true,
+  917852 => true,
+  917853 => true,
+  917854 => true,
+  917855 => true,
+  917856 => true,
+  917857 => true,
+  917858 => true,
+  917859 => true,
+  917860 => true,
+  917861 => true,
+  917862 => true,
+  917863 => true,
+  917864 => true,
+  917865 => true,
+  917866 => true,
+  917867 => true,
+  917868 => true,
+  917869 => true,
+  917870 => true,
+  917871 => true,
+  917872 => true,
+  917873 => true,
+  917874 => true,
+  917875 => true,
+  917876 => true,
+  917877 => true,
+  917878 => true,
+  917879 => true,
+  917880 => true,
+  917881 => true,
+  917882 => true,
+  917883 => true,
+  917884 => true,
+  917885 => true,
+  917886 => true,
+  917887 => true,
+  917888 => true,
+  917889 => true,
+  917890 => true,
+  917891 => true,
+  917892 => true,
+  917893 => true,
+  917894 => true,
+  917895 => true,
+  917896 => true,
+  917897 => true,
+  917898 => true,
+  917899 => true,
+  917900 => true,
+  917901 => true,
+  917902 => true,
+  917903 => true,
+  917904 => true,
+  917905 => true,
+  917906 => true,
+  917907 => true,
+  917908 => true,
+  917909 => true,
+  917910 => true,
+  917911 => true,
+  917912 => true,
+  917913 => true,
+  917914 => true,
+  917915 => true,
+  917916 => true,
+  917917 => true,
+  917918 => true,
+  917919 => true,
+  917920 => true,
+  917921 => true,
+  917922 => true,
+  917923 => true,
+  917924 => true,
+  917925 => true,
+  917926 => true,
+  917927 => true,
+  917928 => true,
+  917929 => true,
+  917930 => true,
+  917931 => true,
+  917932 => true,
+  917933 => true,
+  917934 => true,
+  917935 => true,
+  917936 => true,
+  917937 => true,
+  917938 => true,
+  917939 => true,
+  917940 => true,
+  917941 => true,
+  917942 => true,
+  917943 => true,
+  917944 => true,
+  917945 => true,
+  917946 => true,
+  917947 => true,
+  917948 => true,
+  917949 => true,
+  917950 => true,
+  917951 => true,
+  917952 => true,
+  917953 => true,
+  917954 => true,
+  917955 => true,
+  917956 => true,
+  917957 => true,
+  917958 => true,
+  917959 => true,
+  917960 => true,
+  917961 => true,
+  917962 => true,
+  917963 => true,
+  917964 => true,
+  917965 => true,
+  917966 => true,
+  917967 => true,
+  917968 => true,
+  917969 => true,
+  917970 => true,
+  917971 => true,
+  917972 => true,
+  917973 => true,
+  917974 => true,
+  917975 => true,
+  917976 => true,
+  917977 => true,
+  917978 => true,
+  917979 => true,
+  917980 => true,
+  917981 => true,
+  917982 => true,
+  917983 => true,
+  917984 => true,
+  917985 => true,
+  917986 => true,
+  917987 => true,
+  917988 => true,
+  917989 => true,
+  917990 => true,
+  917991 => true,
+  917992 => true,
+  917993 => true,
+  917994 => true,
+  917995 => true,
+  917996 => true,
+  917997 => true,
+  917998 => true,
+  917999 => true,
+);
diff --git a/vendor/symfony/polyfill-intl-idn/Resources/unidata/mapped.php b/vendor/symfony/polyfill-intl-idn/Resources/unidata/mapped.php
new file mode 100644
index 000000000..9b85fe9d3
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-idn/Resources/unidata/mapped.php
@@ -0,0 +1,5778 @@
+ 'a',
+  66 => 'b',
+  67 => 'c',
+  68 => 'd',
+  69 => 'e',
+  70 => 'f',
+  71 => 'g',
+  72 => 'h',
+  73 => 'i',
+  74 => 'j',
+  75 => 'k',
+  76 => 'l',
+  77 => 'm',
+  78 => 'n',
+  79 => 'o',
+  80 => 'p',
+  81 => 'q',
+  82 => 'r',
+  83 => 's',
+  84 => 't',
+  85 => 'u',
+  86 => 'v',
+  87 => 'w',
+  88 => 'x',
+  89 => 'y',
+  90 => 'z',
+  170 => 'a',
+  178 => '2',
+  179 => '3',
+  181 => 'μ',
+  185 => '1',
+  186 => 'o',
+  188 => '1⁄4',
+  189 => '1⁄2',
+  190 => '3⁄4',
+  192 => 'à',
+  193 => 'á',
+  194 => 'â',
+  195 => 'ã',
+  196 => 'ä',
+  197 => 'å',
+  198 => 'æ',
+  199 => 'ç',
+  200 => 'è',
+  201 => 'é',
+  202 => 'ê',
+  203 => 'ë',
+  204 => 'ì',
+  205 => 'í',
+  206 => 'î',
+  207 => 'ï',
+  208 => 'ð',
+  209 => 'ñ',
+  210 => 'ò',
+  211 => 'ó',
+  212 => 'ô',
+  213 => 'õ',
+  214 => 'ö',
+  216 => 'ø',
+  217 => 'ù',
+  218 => 'ú',
+  219 => 'û',
+  220 => 'ü',
+  221 => 'ý',
+  222 => 'þ',
+  256 => 'ā',
+  258 => 'ă',
+  260 => 'ą',
+  262 => 'ć',
+  264 => 'ĉ',
+  266 => 'ċ',
+  268 => 'č',
+  270 => 'ď',
+  272 => 'đ',
+  274 => 'ē',
+  276 => 'ĕ',
+  278 => 'ė',
+  280 => 'ę',
+  282 => 'ě',
+  284 => 'ĝ',
+  286 => 'ğ',
+  288 => 'ġ',
+  290 => 'ģ',
+  292 => 'ĥ',
+  294 => 'ħ',
+  296 => 'ĩ',
+  298 => 'ī',
+  300 => 'ĭ',
+  302 => 'į',
+  304 => 'i̇',
+  306 => 'ij',
+  307 => 'ij',
+  308 => 'ĵ',
+  310 => 'ķ',
+  313 => 'ĺ',
+  315 => 'ļ',
+  317 => 'ľ',
+  319 => 'l·',
+  320 => 'l·',
+  321 => 'ł',
+  323 => 'ń',
+  325 => 'ņ',
+  327 => 'ň',
+  329 => 'ʼn',
+  330 => 'ŋ',
+  332 => 'ō',
+  334 => 'ŏ',
+  336 => 'ő',
+  338 => 'œ',
+  340 => 'ŕ',
+  342 => 'ŗ',
+  344 => 'ř',
+  346 => 'ś',
+  348 => 'ŝ',
+  350 => 'ş',
+  352 => 'š',
+  354 => 'ţ',
+  356 => 'ť',
+  358 => 'ŧ',
+  360 => 'ũ',
+  362 => 'ū',
+  364 => 'ŭ',
+  366 => 'ů',
+  368 => 'ű',
+  370 => 'ų',
+  372 => 'ŵ',
+  374 => 'ŷ',
+  376 => 'ÿ',
+  377 => 'ź',
+  379 => 'ż',
+  381 => 'ž',
+  383 => 's',
+  385 => 'ɓ',
+  386 => 'ƃ',
+  388 => 'ƅ',
+  390 => 'ɔ',
+  391 => 'ƈ',
+  393 => 'ɖ',
+  394 => 'ɗ',
+  395 => 'ƌ',
+  398 => 'ǝ',
+  399 => 'ə',
+  400 => 'ɛ',
+  401 => 'ƒ',
+  403 => 'ɠ',
+  404 => 'ɣ',
+  406 => 'ɩ',
+  407 => 'ɨ',
+  408 => 'ƙ',
+  412 => 'ɯ',
+  413 => 'ɲ',
+  415 => 'ɵ',
+  416 => 'ơ',
+  418 => 'ƣ',
+  420 => 'ƥ',
+  422 => 'ʀ',
+  423 => 'ƨ',
+  425 => 'ʃ',
+  428 => 'ƭ',
+  430 => 'ʈ',
+  431 => 'ư',
+  433 => 'ʊ',
+  434 => 'ʋ',
+  435 => 'ƴ',
+  437 => 'ƶ',
+  439 => 'ʒ',
+  440 => 'ƹ',
+  444 => 'ƽ',
+  452 => 'dž',
+  453 => 'dž',
+  454 => 'dž',
+  455 => 'lj',
+  456 => 'lj',
+  457 => 'lj',
+  458 => 'nj',
+  459 => 'nj',
+  460 => 'nj',
+  461 => 'ǎ',
+  463 => 'ǐ',
+  465 => 'ǒ',
+  467 => 'ǔ',
+  469 => 'ǖ',
+  471 => 'ǘ',
+  473 => 'ǚ',
+  475 => 'ǜ',
+  478 => 'ǟ',
+  480 => 'ǡ',
+  482 => 'ǣ',
+  484 => 'ǥ',
+  486 => 'ǧ',
+  488 => 'ǩ',
+  490 => 'ǫ',
+  492 => 'ǭ',
+  494 => 'ǯ',
+  497 => 'dz',
+  498 => 'dz',
+  499 => 'dz',
+  500 => 'ǵ',
+  502 => 'ƕ',
+  503 => 'ƿ',
+  504 => 'ǹ',
+  506 => 'ǻ',
+  508 => 'ǽ',
+  510 => 'ǿ',
+  512 => 'ȁ',
+  514 => 'ȃ',
+  516 => 'ȅ',
+  518 => 'ȇ',
+  520 => 'ȉ',
+  522 => 'ȋ',
+  524 => 'ȍ',
+  526 => 'ȏ',
+  528 => 'ȑ',
+  530 => 'ȓ',
+  532 => 'ȕ',
+  534 => 'ȗ',
+  536 => 'ș',
+  538 => 'ț',
+  540 => 'ȝ',
+  542 => 'ȟ',
+  544 => 'ƞ',
+  546 => 'ȣ',
+  548 => 'ȥ',
+  550 => 'ȧ',
+  552 => 'ȩ',
+  554 => 'ȫ',
+  556 => 'ȭ',
+  558 => 'ȯ',
+  560 => 'ȱ',
+  562 => 'ȳ',
+  570 => 'ⱥ',
+  571 => 'ȼ',
+  573 => 'ƚ',
+  574 => 'ⱦ',
+  577 => 'ɂ',
+  579 => 'ƀ',
+  580 => 'ʉ',
+  581 => 'ʌ',
+  582 => 'ɇ',
+  584 => 'ɉ',
+  586 => 'ɋ',
+  588 => 'ɍ',
+  590 => 'ɏ',
+  688 => 'h',
+  689 => 'ɦ',
+  690 => 'j',
+  691 => 'r',
+  692 => 'ɹ',
+  693 => 'ɻ',
+  694 => 'ʁ',
+  695 => 'w',
+  696 => 'y',
+  736 => 'ɣ',
+  737 => 'l',
+  738 => 's',
+  739 => 'x',
+  740 => 'ʕ',
+  832 => '̀',
+  833 => '́',
+  835 => '̓',
+  836 => '̈́',
+  837 => 'ι',
+  880 => 'ͱ',
+  882 => 'ͳ',
+  884 => 'ʹ',
+  886 => 'ͷ',
+  895 => 'ϳ',
+  902 => 'ά',
+  903 => '·',
+  904 => 'έ',
+  905 => 'ή',
+  906 => 'ί',
+  908 => 'ό',
+  910 => 'ύ',
+  911 => 'ώ',
+  913 => 'α',
+  914 => 'β',
+  915 => 'γ',
+  916 => 'δ',
+  917 => 'ε',
+  918 => 'ζ',
+  919 => 'η',
+  920 => 'θ',
+  921 => 'ι',
+  922 => 'κ',
+  923 => 'λ',
+  924 => 'μ',
+  925 => 'ν',
+  926 => 'ξ',
+  927 => 'ο',
+  928 => 'π',
+  929 => 'ρ',
+  931 => 'σ',
+  932 => 'τ',
+  933 => 'υ',
+  934 => 'φ',
+  935 => 'χ',
+  936 => 'ψ',
+  937 => 'ω',
+  938 => 'ϊ',
+  939 => 'ϋ',
+  975 => 'ϗ',
+  976 => 'β',
+  977 => 'θ',
+  978 => 'υ',
+  979 => 'ύ',
+  980 => 'ϋ',
+  981 => 'φ',
+  982 => 'π',
+  984 => 'ϙ',
+  986 => 'ϛ',
+  988 => 'ϝ',
+  990 => 'ϟ',
+  992 => 'ϡ',
+  994 => 'ϣ',
+  996 => 'ϥ',
+  998 => 'ϧ',
+  1000 => 'ϩ',
+  1002 => 'ϫ',
+  1004 => 'ϭ',
+  1006 => 'ϯ',
+  1008 => 'κ',
+  1009 => 'ρ',
+  1010 => 'σ',
+  1012 => 'θ',
+  1013 => 'ε',
+  1015 => 'ϸ',
+  1017 => 'σ',
+  1018 => 'ϻ',
+  1021 => 'ͻ',
+  1022 => 'ͼ',
+  1023 => 'ͽ',
+  1024 => 'ѐ',
+  1025 => 'ё',
+  1026 => 'ђ',
+  1027 => 'ѓ',
+  1028 => 'є',
+  1029 => 'ѕ',
+  1030 => 'і',
+  1031 => 'ї',
+  1032 => 'ј',
+  1033 => 'љ',
+  1034 => 'њ',
+  1035 => 'ћ',
+  1036 => 'ќ',
+  1037 => 'ѝ',
+  1038 => 'ў',
+  1039 => 'џ',
+  1040 => 'а',
+  1041 => 'б',
+  1042 => 'в',
+  1043 => 'г',
+  1044 => 'д',
+  1045 => 'е',
+  1046 => 'ж',
+  1047 => 'з',
+  1048 => 'и',
+  1049 => 'й',
+  1050 => 'к',
+  1051 => 'л',
+  1052 => 'м',
+  1053 => 'н',
+  1054 => 'о',
+  1055 => 'п',
+  1056 => 'р',
+  1057 => 'с',
+  1058 => 'т',
+  1059 => 'у',
+  1060 => 'ф',
+  1061 => 'х',
+  1062 => 'ц',
+  1063 => 'ч',
+  1064 => 'ш',
+  1065 => 'щ',
+  1066 => 'ъ',
+  1067 => 'ы',
+  1068 => 'ь',
+  1069 => 'э',
+  1070 => 'ю',
+  1071 => 'я',
+  1120 => 'ѡ',
+  1122 => 'ѣ',
+  1124 => 'ѥ',
+  1126 => 'ѧ',
+  1128 => 'ѩ',
+  1130 => 'ѫ',
+  1132 => 'ѭ',
+  1134 => 'ѯ',
+  1136 => 'ѱ',
+  1138 => 'ѳ',
+  1140 => 'ѵ',
+  1142 => 'ѷ',
+  1144 => 'ѹ',
+  1146 => 'ѻ',
+  1148 => 'ѽ',
+  1150 => 'ѿ',
+  1152 => 'ҁ',
+  1162 => 'ҋ',
+  1164 => 'ҍ',
+  1166 => 'ҏ',
+  1168 => 'ґ',
+  1170 => 'ғ',
+  1172 => 'ҕ',
+  1174 => 'җ',
+  1176 => 'ҙ',
+  1178 => 'қ',
+  1180 => 'ҝ',
+  1182 => 'ҟ',
+  1184 => 'ҡ',
+  1186 => 'ң',
+  1188 => 'ҥ',
+  1190 => 'ҧ',
+  1192 => 'ҩ',
+  1194 => 'ҫ',
+  1196 => 'ҭ',
+  1198 => 'ү',
+  1200 => 'ұ',
+  1202 => 'ҳ',
+  1204 => 'ҵ',
+  1206 => 'ҷ',
+  1208 => 'ҹ',
+  1210 => 'һ',
+  1212 => 'ҽ',
+  1214 => 'ҿ',
+  1217 => 'ӂ',
+  1219 => 'ӄ',
+  1221 => 'ӆ',
+  1223 => 'ӈ',
+  1225 => 'ӊ',
+  1227 => 'ӌ',
+  1229 => 'ӎ',
+  1232 => 'ӑ',
+  1234 => 'ӓ',
+  1236 => 'ӕ',
+  1238 => 'ӗ',
+  1240 => 'ә',
+  1242 => 'ӛ',
+  1244 => 'ӝ',
+  1246 => 'ӟ',
+  1248 => 'ӡ',
+  1250 => 'ӣ',
+  1252 => 'ӥ',
+  1254 => 'ӧ',
+  1256 => 'ө',
+  1258 => 'ӫ',
+  1260 => 'ӭ',
+  1262 => 'ӯ',
+  1264 => 'ӱ',
+  1266 => 'ӳ',
+  1268 => 'ӵ',
+  1270 => 'ӷ',
+  1272 => 'ӹ',
+  1274 => 'ӻ',
+  1276 => 'ӽ',
+  1278 => 'ӿ',
+  1280 => 'ԁ',
+  1282 => 'ԃ',
+  1284 => 'ԅ',
+  1286 => 'ԇ',
+  1288 => 'ԉ',
+  1290 => 'ԋ',
+  1292 => 'ԍ',
+  1294 => 'ԏ',
+  1296 => 'ԑ',
+  1298 => 'ԓ',
+  1300 => 'ԕ',
+  1302 => 'ԗ',
+  1304 => 'ԙ',
+  1306 => 'ԛ',
+  1308 => 'ԝ',
+  1310 => 'ԟ',
+  1312 => 'ԡ',
+  1314 => 'ԣ',
+  1316 => 'ԥ',
+  1318 => 'ԧ',
+  1320 => 'ԩ',
+  1322 => 'ԫ',
+  1324 => 'ԭ',
+  1326 => 'ԯ',
+  1329 => 'ա',
+  1330 => 'բ',
+  1331 => 'գ',
+  1332 => 'դ',
+  1333 => 'ե',
+  1334 => 'զ',
+  1335 => 'է',
+  1336 => 'ը',
+  1337 => 'թ',
+  1338 => 'ժ',
+  1339 => 'ի',
+  1340 => 'լ',
+  1341 => 'խ',
+  1342 => 'ծ',
+  1343 => 'կ',
+  1344 => 'հ',
+  1345 => 'ձ',
+  1346 => 'ղ',
+  1347 => 'ճ',
+  1348 => 'մ',
+  1349 => 'յ',
+  1350 => 'ն',
+  1351 => 'շ',
+  1352 => 'ո',
+  1353 => 'չ',
+  1354 => 'պ',
+  1355 => 'ջ',
+  1356 => 'ռ',
+  1357 => 'ս',
+  1358 => 'վ',
+  1359 => 'տ',
+  1360 => 'ր',
+  1361 => 'ց',
+  1362 => 'ւ',
+  1363 => 'փ',
+  1364 => 'ք',
+  1365 => 'օ',
+  1366 => 'ֆ',
+  1415 => 'եւ',
+  1653 => 'اٴ',
+  1654 => 'وٴ',
+  1655 => 'ۇٴ',
+  1656 => 'يٴ',
+  2392 => 'क़',
+  2393 => 'ख़',
+  2394 => 'ग़',
+  2395 => 'ज़',
+  2396 => 'ड़',
+  2397 => 'ढ़',
+  2398 => 'फ़',
+  2399 => 'य़',
+  2524 => 'ড়',
+  2525 => 'ঢ়',
+  2527 => 'য়',
+  2611 => 'ਲ਼',
+  2614 => 'ਸ਼',
+  2649 => 'ਖ਼',
+  2650 => 'ਗ਼',
+  2651 => 'ਜ਼',
+  2654 => 'ਫ਼',
+  2908 => 'ଡ଼',
+  2909 => 'ଢ଼',
+  3635 => 'ํา',
+  3763 => 'ໍາ',
+  3804 => 'ຫນ',
+  3805 => 'ຫມ',
+  3852 => '་',
+  3907 => 'གྷ',
+  3917 => 'ཌྷ',
+  3922 => 'དྷ',
+  3927 => 'བྷ',
+  3932 => 'ཛྷ',
+  3945 => 'ཀྵ',
+  3955 => 'ཱི',
+  3957 => 'ཱུ',
+  3958 => 'ྲྀ',
+  3959 => 'ྲཱྀ',
+  3960 => 'ླྀ',
+  3961 => 'ླཱྀ',
+  3969 => 'ཱྀ',
+  3987 => 'ྒྷ',
+  3997 => 'ྜྷ',
+  4002 => 'ྡྷ',
+  4007 => 'ྦྷ',
+  4012 => 'ྫྷ',
+  4025 => 'ྐྵ',
+  4295 => 'ⴧ',
+  4301 => 'ⴭ',
+  4348 => 'ნ',
+  5112 => 'Ᏸ',
+  5113 => 'Ᏹ',
+  5114 => 'Ᏺ',
+  5115 => 'Ᏻ',
+  5116 => 'Ᏼ',
+  5117 => 'Ᏽ',
+  7296 => 'в',
+  7297 => 'д',
+  7298 => 'о',
+  7299 => 'с',
+  7300 => 'т',
+  7301 => 'т',
+  7302 => 'ъ',
+  7303 => 'ѣ',
+  7304 => 'ꙋ',
+  7312 => 'ა',
+  7313 => 'ბ',
+  7314 => 'გ',
+  7315 => 'დ',
+  7316 => 'ე',
+  7317 => 'ვ',
+  7318 => 'ზ',
+  7319 => 'თ',
+  7320 => 'ი',
+  7321 => 'კ',
+  7322 => 'ლ',
+  7323 => 'მ',
+  7324 => 'ნ',
+  7325 => 'ო',
+  7326 => 'პ',
+  7327 => 'ჟ',
+  7328 => 'რ',
+  7329 => 'ს',
+  7330 => 'ტ',
+  7331 => 'უ',
+  7332 => 'ფ',
+  7333 => 'ქ',
+  7334 => 'ღ',
+  7335 => 'ყ',
+  7336 => 'შ',
+  7337 => 'ჩ',
+  7338 => 'ც',
+  7339 => 'ძ',
+  7340 => 'წ',
+  7341 => 'ჭ',
+  7342 => 'ხ',
+  7343 => 'ჯ',
+  7344 => 'ჰ',
+  7345 => 'ჱ',
+  7346 => 'ჲ',
+  7347 => 'ჳ',
+  7348 => 'ჴ',
+  7349 => 'ჵ',
+  7350 => 'ჶ',
+  7351 => 'ჷ',
+  7352 => 'ჸ',
+  7353 => 'ჹ',
+  7354 => 'ჺ',
+  7357 => 'ჽ',
+  7358 => 'ჾ',
+  7359 => 'ჿ',
+  7468 => 'a',
+  7469 => 'æ',
+  7470 => 'b',
+  7472 => 'd',
+  7473 => 'e',
+  7474 => 'ǝ',
+  7475 => 'g',
+  7476 => 'h',
+  7477 => 'i',
+  7478 => 'j',
+  7479 => 'k',
+  7480 => 'l',
+  7481 => 'm',
+  7482 => 'n',
+  7484 => 'o',
+  7485 => 'ȣ',
+  7486 => 'p',
+  7487 => 'r',
+  7488 => 't',
+  7489 => 'u',
+  7490 => 'w',
+  7491 => 'a',
+  7492 => 'ɐ',
+  7493 => 'ɑ',
+  7494 => 'ᴂ',
+  7495 => 'b',
+  7496 => 'd',
+  7497 => 'e',
+  7498 => 'ə',
+  7499 => 'ɛ',
+  7500 => 'ɜ',
+  7501 => 'g',
+  7503 => 'k',
+  7504 => 'm',
+  7505 => 'ŋ',
+  7506 => 'o',
+  7507 => 'ɔ',
+  7508 => 'ᴖ',
+  7509 => 'ᴗ',
+  7510 => 'p',
+  7511 => 't',
+  7512 => 'u',
+  7513 => 'ᴝ',
+  7514 => 'ɯ',
+  7515 => 'v',
+  7516 => 'ᴥ',
+  7517 => 'β',
+  7518 => 'γ',
+  7519 => 'δ',
+  7520 => 'φ',
+  7521 => 'χ',
+  7522 => 'i',
+  7523 => 'r',
+  7524 => 'u',
+  7525 => 'v',
+  7526 => 'β',
+  7527 => 'γ',
+  7528 => 'ρ',
+  7529 => 'φ',
+  7530 => 'χ',
+  7544 => 'н',
+  7579 => 'ɒ',
+  7580 => 'c',
+  7581 => 'ɕ',
+  7582 => 'ð',
+  7583 => 'ɜ',
+  7584 => 'f',
+  7585 => 'ɟ',
+  7586 => 'ɡ',
+  7587 => 'ɥ',
+  7588 => 'ɨ',
+  7589 => 'ɩ',
+  7590 => 'ɪ',
+  7591 => 'ᵻ',
+  7592 => 'ʝ',
+  7593 => 'ɭ',
+  7594 => 'ᶅ',
+  7595 => 'ʟ',
+  7596 => 'ɱ',
+  7597 => 'ɰ',
+  7598 => 'ɲ',
+  7599 => 'ɳ',
+  7600 => 'ɴ',
+  7601 => 'ɵ',
+  7602 => 'ɸ',
+  7603 => 'ʂ',
+  7604 => 'ʃ',
+  7605 => 'ƫ',
+  7606 => 'ʉ',
+  7607 => 'ʊ',
+  7608 => 'ᴜ',
+  7609 => 'ʋ',
+  7610 => 'ʌ',
+  7611 => 'z',
+  7612 => 'ʐ',
+  7613 => 'ʑ',
+  7614 => 'ʒ',
+  7615 => 'θ',
+  7680 => 'ḁ',
+  7682 => 'ḃ',
+  7684 => 'ḅ',
+  7686 => 'ḇ',
+  7688 => 'ḉ',
+  7690 => 'ḋ',
+  7692 => 'ḍ',
+  7694 => 'ḏ',
+  7696 => 'ḑ',
+  7698 => 'ḓ',
+  7700 => 'ḕ',
+  7702 => 'ḗ',
+  7704 => 'ḙ',
+  7706 => 'ḛ',
+  7708 => 'ḝ',
+  7710 => 'ḟ',
+  7712 => 'ḡ',
+  7714 => 'ḣ',
+  7716 => 'ḥ',
+  7718 => 'ḧ',
+  7720 => 'ḩ',
+  7722 => 'ḫ',
+  7724 => 'ḭ',
+  7726 => 'ḯ',
+  7728 => 'ḱ',
+  7730 => 'ḳ',
+  7732 => 'ḵ',
+  7734 => 'ḷ',
+  7736 => 'ḹ',
+  7738 => 'ḻ',
+  7740 => 'ḽ',
+  7742 => 'ḿ',
+  7744 => 'ṁ',
+  7746 => 'ṃ',
+  7748 => 'ṅ',
+  7750 => 'ṇ',
+  7752 => 'ṉ',
+  7754 => 'ṋ',
+  7756 => 'ṍ',
+  7758 => 'ṏ',
+  7760 => 'ṑ',
+  7762 => 'ṓ',
+  7764 => 'ṕ',
+  7766 => 'ṗ',
+  7768 => 'ṙ',
+  7770 => 'ṛ',
+  7772 => 'ṝ',
+  7774 => 'ṟ',
+  7776 => 'ṡ',
+  7778 => 'ṣ',
+  7780 => 'ṥ',
+  7782 => 'ṧ',
+  7784 => 'ṩ',
+  7786 => 'ṫ',
+  7788 => 'ṭ',
+  7790 => 'ṯ',
+  7792 => 'ṱ',
+  7794 => 'ṳ',
+  7796 => 'ṵ',
+  7798 => 'ṷ',
+  7800 => 'ṹ',
+  7802 => 'ṻ',
+  7804 => 'ṽ',
+  7806 => 'ṿ',
+  7808 => 'ẁ',
+  7810 => 'ẃ',
+  7812 => 'ẅ',
+  7814 => 'ẇ',
+  7816 => 'ẉ',
+  7818 => 'ẋ',
+  7820 => 'ẍ',
+  7822 => 'ẏ',
+  7824 => 'ẑ',
+  7826 => 'ẓ',
+  7828 => 'ẕ',
+  7834 => 'aʾ',
+  7835 => 'ṡ',
+  7838 => 'ss',
+  7840 => 'ạ',
+  7842 => 'ả',
+  7844 => 'ấ',
+  7846 => 'ầ',
+  7848 => 'ẩ',
+  7850 => 'ẫ',
+  7852 => 'ậ',
+  7854 => 'ắ',
+  7856 => 'ằ',
+  7858 => 'ẳ',
+  7860 => 'ẵ',
+  7862 => 'ặ',
+  7864 => 'ẹ',
+  7866 => 'ẻ',
+  7868 => 'ẽ',
+  7870 => 'ế',
+  7872 => 'ề',
+  7874 => 'ể',
+  7876 => 'ễ',
+  7878 => 'ệ',
+  7880 => 'ỉ',
+  7882 => 'ị',
+  7884 => 'ọ',
+  7886 => 'ỏ',
+  7888 => 'ố',
+  7890 => 'ồ',
+  7892 => 'ổ',
+  7894 => 'ỗ',
+  7896 => 'ộ',
+  7898 => 'ớ',
+  7900 => 'ờ',
+  7902 => 'ở',
+  7904 => 'ỡ',
+  7906 => 'ợ',
+  7908 => 'ụ',
+  7910 => 'ủ',
+  7912 => 'ứ',
+  7914 => 'ừ',
+  7916 => 'ử',
+  7918 => 'ữ',
+  7920 => 'ự',
+  7922 => 'ỳ',
+  7924 => 'ỵ',
+  7926 => 'ỷ',
+  7928 => 'ỹ',
+  7930 => 'ỻ',
+  7932 => 'ỽ',
+  7934 => 'ỿ',
+  7944 => 'ἀ',
+  7945 => 'ἁ',
+  7946 => 'ἂ',
+  7947 => 'ἃ',
+  7948 => 'ἄ',
+  7949 => 'ἅ',
+  7950 => 'ἆ',
+  7951 => 'ἇ',
+  7960 => 'ἐ',
+  7961 => 'ἑ',
+  7962 => 'ἒ',
+  7963 => 'ἓ',
+  7964 => 'ἔ',
+  7965 => 'ἕ',
+  7976 => 'ἠ',
+  7977 => 'ἡ',
+  7978 => 'ἢ',
+  7979 => 'ἣ',
+  7980 => 'ἤ',
+  7981 => 'ἥ',
+  7982 => 'ἦ',
+  7983 => 'ἧ',
+  7992 => 'ἰ',
+  7993 => 'ἱ',
+  7994 => 'ἲ',
+  7995 => 'ἳ',
+  7996 => 'ἴ',
+  7997 => 'ἵ',
+  7998 => 'ἶ',
+  7999 => 'ἷ',
+  8008 => 'ὀ',
+  8009 => 'ὁ',
+  8010 => 'ὂ',
+  8011 => 'ὃ',
+  8012 => 'ὄ',
+  8013 => 'ὅ',
+  8025 => 'ὑ',
+  8027 => 'ὓ',
+  8029 => 'ὕ',
+  8031 => 'ὗ',
+  8040 => 'ὠ',
+  8041 => 'ὡ',
+  8042 => 'ὢ',
+  8043 => 'ὣ',
+  8044 => 'ὤ',
+  8045 => 'ὥ',
+  8046 => 'ὦ',
+  8047 => 'ὧ',
+  8049 => 'ά',
+  8051 => 'έ',
+  8053 => 'ή',
+  8055 => 'ί',
+  8057 => 'ό',
+  8059 => 'ύ',
+  8061 => 'ώ',
+  8064 => 'ἀι',
+  8065 => 'ἁι',
+  8066 => 'ἂι',
+  8067 => 'ἃι',
+  8068 => 'ἄι',
+  8069 => 'ἅι',
+  8070 => 'ἆι',
+  8071 => 'ἇι',
+  8072 => 'ἀι',
+  8073 => 'ἁι',
+  8074 => 'ἂι',
+  8075 => 'ἃι',
+  8076 => 'ἄι',
+  8077 => 'ἅι',
+  8078 => 'ἆι',
+  8079 => 'ἇι',
+  8080 => 'ἠι',
+  8081 => 'ἡι',
+  8082 => 'ἢι',
+  8083 => 'ἣι',
+  8084 => 'ἤι',
+  8085 => 'ἥι',
+  8086 => 'ἦι',
+  8087 => 'ἧι',
+  8088 => 'ἠι',
+  8089 => 'ἡι',
+  8090 => 'ἢι',
+  8091 => 'ἣι',
+  8092 => 'ἤι',
+  8093 => 'ἥι',
+  8094 => 'ἦι',
+  8095 => 'ἧι',
+  8096 => 'ὠι',
+  8097 => 'ὡι',
+  8098 => 'ὢι',
+  8099 => 'ὣι',
+  8100 => 'ὤι',
+  8101 => 'ὥι',
+  8102 => 'ὦι',
+  8103 => 'ὧι',
+  8104 => 'ὠι',
+  8105 => 'ὡι',
+  8106 => 'ὢι',
+  8107 => 'ὣι',
+  8108 => 'ὤι',
+  8109 => 'ὥι',
+  8110 => 'ὦι',
+  8111 => 'ὧι',
+  8114 => 'ὰι',
+  8115 => 'αι',
+  8116 => 'άι',
+  8119 => 'ᾶι',
+  8120 => 'ᾰ',
+  8121 => 'ᾱ',
+  8122 => 'ὰ',
+  8123 => 'ά',
+  8124 => 'αι',
+  8126 => 'ι',
+  8130 => 'ὴι',
+  8131 => 'ηι',
+  8132 => 'ήι',
+  8135 => 'ῆι',
+  8136 => 'ὲ',
+  8137 => 'έ',
+  8138 => 'ὴ',
+  8139 => 'ή',
+  8140 => 'ηι',
+  8147 => 'ΐ',
+  8152 => 'ῐ',
+  8153 => 'ῑ',
+  8154 => 'ὶ',
+  8155 => 'ί',
+  8163 => 'ΰ',
+  8168 => 'ῠ',
+  8169 => 'ῡ',
+  8170 => 'ὺ',
+  8171 => 'ύ',
+  8172 => 'ῥ',
+  8178 => 'ὼι',
+  8179 => 'ωι',
+  8180 => 'ώι',
+  8183 => 'ῶι',
+  8184 => 'ὸ',
+  8185 => 'ό',
+  8186 => 'ὼ',
+  8187 => 'ώ',
+  8188 => 'ωι',
+  8209 => '‐',
+  8243 => '′′',
+  8244 => '′′′',
+  8246 => '‵‵',
+  8247 => '‵‵‵',
+  8279 => '′′′′',
+  8304 => '0',
+  8305 => 'i',
+  8308 => '4',
+  8309 => '5',
+  8310 => '6',
+  8311 => '7',
+  8312 => '8',
+  8313 => '9',
+  8315 => '−',
+  8319 => 'n',
+  8320 => '0',
+  8321 => '1',
+  8322 => '2',
+  8323 => '3',
+  8324 => '4',
+  8325 => '5',
+  8326 => '6',
+  8327 => '7',
+  8328 => '8',
+  8329 => '9',
+  8331 => '−',
+  8336 => 'a',
+  8337 => 'e',
+  8338 => 'o',
+  8339 => 'x',
+  8340 => 'ə',
+  8341 => 'h',
+  8342 => 'k',
+  8343 => 'l',
+  8344 => 'm',
+  8345 => 'n',
+  8346 => 'p',
+  8347 => 's',
+  8348 => 't',
+  8360 => 'rs',
+  8450 => 'c',
+  8451 => '°c',
+  8455 => 'ɛ',
+  8457 => '°f',
+  8458 => 'g',
+  8459 => 'h',
+  8460 => 'h',
+  8461 => 'h',
+  8462 => 'h',
+  8463 => 'ħ',
+  8464 => 'i',
+  8465 => 'i',
+  8466 => 'l',
+  8467 => 'l',
+  8469 => 'n',
+  8470 => 'no',
+  8473 => 'p',
+  8474 => 'q',
+  8475 => 'r',
+  8476 => 'r',
+  8477 => 'r',
+  8480 => 'sm',
+  8481 => 'tel',
+  8482 => 'tm',
+  8484 => 'z',
+  8486 => 'ω',
+  8488 => 'z',
+  8490 => 'k',
+  8491 => 'å',
+  8492 => 'b',
+  8493 => 'c',
+  8495 => 'e',
+  8496 => 'e',
+  8497 => 'f',
+  8499 => 'm',
+  8500 => 'o',
+  8501 => 'א',
+  8502 => 'ב',
+  8503 => 'ג',
+  8504 => 'ד',
+  8505 => 'i',
+  8507 => 'fax',
+  8508 => 'π',
+  8509 => 'γ',
+  8510 => 'γ',
+  8511 => 'π',
+  8512 => '∑',
+  8517 => 'd',
+  8518 => 'd',
+  8519 => 'e',
+  8520 => 'i',
+  8521 => 'j',
+  8528 => '1⁄7',
+  8529 => '1⁄9',
+  8530 => '1⁄10',
+  8531 => '1⁄3',
+  8532 => '2⁄3',
+  8533 => '1⁄5',
+  8534 => '2⁄5',
+  8535 => '3⁄5',
+  8536 => '4⁄5',
+  8537 => '1⁄6',
+  8538 => '5⁄6',
+  8539 => '1⁄8',
+  8540 => '3⁄8',
+  8541 => '5⁄8',
+  8542 => '7⁄8',
+  8543 => '1⁄',
+  8544 => 'i',
+  8545 => 'ii',
+  8546 => 'iii',
+  8547 => 'iv',
+  8548 => 'v',
+  8549 => 'vi',
+  8550 => 'vii',
+  8551 => 'viii',
+  8552 => 'ix',
+  8553 => 'x',
+  8554 => 'xi',
+  8555 => 'xii',
+  8556 => 'l',
+  8557 => 'c',
+  8558 => 'd',
+  8559 => 'm',
+  8560 => 'i',
+  8561 => 'ii',
+  8562 => 'iii',
+  8563 => 'iv',
+  8564 => 'v',
+  8565 => 'vi',
+  8566 => 'vii',
+  8567 => 'viii',
+  8568 => 'ix',
+  8569 => 'x',
+  8570 => 'xi',
+  8571 => 'xii',
+  8572 => 'l',
+  8573 => 'c',
+  8574 => 'd',
+  8575 => 'm',
+  8585 => '0⁄3',
+  8748 => '∫∫',
+  8749 => '∫∫∫',
+  8751 => '∮∮',
+  8752 => '∮∮∮',
+  9001 => '〈',
+  9002 => '〉',
+  9312 => '1',
+  9313 => '2',
+  9314 => '3',
+  9315 => '4',
+  9316 => '5',
+  9317 => '6',
+  9318 => '7',
+  9319 => '8',
+  9320 => '9',
+  9321 => '10',
+  9322 => '11',
+  9323 => '12',
+  9324 => '13',
+  9325 => '14',
+  9326 => '15',
+  9327 => '16',
+  9328 => '17',
+  9329 => '18',
+  9330 => '19',
+  9331 => '20',
+  9398 => 'a',
+  9399 => 'b',
+  9400 => 'c',
+  9401 => 'd',
+  9402 => 'e',
+  9403 => 'f',
+  9404 => 'g',
+  9405 => 'h',
+  9406 => 'i',
+  9407 => 'j',
+  9408 => 'k',
+  9409 => 'l',
+  9410 => 'm',
+  9411 => 'n',
+  9412 => 'o',
+  9413 => 'p',
+  9414 => 'q',
+  9415 => 'r',
+  9416 => 's',
+  9417 => 't',
+  9418 => 'u',
+  9419 => 'v',
+  9420 => 'w',
+  9421 => 'x',
+  9422 => 'y',
+  9423 => 'z',
+  9424 => 'a',
+  9425 => 'b',
+  9426 => 'c',
+  9427 => 'd',
+  9428 => 'e',
+  9429 => 'f',
+  9430 => 'g',
+  9431 => 'h',
+  9432 => 'i',
+  9433 => 'j',
+  9434 => 'k',
+  9435 => 'l',
+  9436 => 'm',
+  9437 => 'n',
+  9438 => 'o',
+  9439 => 'p',
+  9440 => 'q',
+  9441 => 'r',
+  9442 => 's',
+  9443 => 't',
+  9444 => 'u',
+  9445 => 'v',
+  9446 => 'w',
+  9447 => 'x',
+  9448 => 'y',
+  9449 => 'z',
+  9450 => '0',
+  10764 => '∫∫∫∫',
+  10972 => '⫝̸',
+  11264 => 'ⰰ',
+  11265 => 'ⰱ',
+  11266 => 'ⰲ',
+  11267 => 'ⰳ',
+  11268 => 'ⰴ',
+  11269 => 'ⰵ',
+  11270 => 'ⰶ',
+  11271 => 'ⰷ',
+  11272 => 'ⰸ',
+  11273 => 'ⰹ',
+  11274 => 'ⰺ',
+  11275 => 'ⰻ',
+  11276 => 'ⰼ',
+  11277 => 'ⰽ',
+  11278 => 'ⰾ',
+  11279 => 'ⰿ',
+  11280 => 'ⱀ',
+  11281 => 'ⱁ',
+  11282 => 'ⱂ',
+  11283 => 'ⱃ',
+  11284 => 'ⱄ',
+  11285 => 'ⱅ',
+  11286 => 'ⱆ',
+  11287 => 'ⱇ',
+  11288 => 'ⱈ',
+  11289 => 'ⱉ',
+  11290 => 'ⱊ',
+  11291 => 'ⱋ',
+  11292 => 'ⱌ',
+  11293 => 'ⱍ',
+  11294 => 'ⱎ',
+  11295 => 'ⱏ',
+  11296 => 'ⱐ',
+  11297 => 'ⱑ',
+  11298 => 'ⱒ',
+  11299 => 'ⱓ',
+  11300 => 'ⱔ',
+  11301 => 'ⱕ',
+  11302 => 'ⱖ',
+  11303 => 'ⱗ',
+  11304 => 'ⱘ',
+  11305 => 'ⱙ',
+  11306 => 'ⱚ',
+  11307 => 'ⱛ',
+  11308 => 'ⱜ',
+  11309 => 'ⱝ',
+  11310 => 'ⱞ',
+  11360 => 'ⱡ',
+  11362 => 'ɫ',
+  11363 => 'ᵽ',
+  11364 => 'ɽ',
+  11367 => 'ⱨ',
+  11369 => 'ⱪ',
+  11371 => 'ⱬ',
+  11373 => 'ɑ',
+  11374 => 'ɱ',
+  11375 => 'ɐ',
+  11376 => 'ɒ',
+  11378 => 'ⱳ',
+  11381 => 'ⱶ',
+  11388 => 'j',
+  11389 => 'v',
+  11390 => 'ȿ',
+  11391 => 'ɀ',
+  11392 => 'ⲁ',
+  11394 => 'ⲃ',
+  11396 => 'ⲅ',
+  11398 => 'ⲇ',
+  11400 => 'ⲉ',
+  11402 => 'ⲋ',
+  11404 => 'ⲍ',
+  11406 => 'ⲏ',
+  11408 => 'ⲑ',
+  11410 => 'ⲓ',
+  11412 => 'ⲕ',
+  11414 => 'ⲗ',
+  11416 => 'ⲙ',
+  11418 => 'ⲛ',
+  11420 => 'ⲝ',
+  11422 => 'ⲟ',
+  11424 => 'ⲡ',
+  11426 => 'ⲣ',
+  11428 => 'ⲥ',
+  11430 => 'ⲧ',
+  11432 => 'ⲩ',
+  11434 => 'ⲫ',
+  11436 => 'ⲭ',
+  11438 => 'ⲯ',
+  11440 => 'ⲱ',
+  11442 => 'ⲳ',
+  11444 => 'ⲵ',
+  11446 => 'ⲷ',
+  11448 => 'ⲹ',
+  11450 => 'ⲻ',
+  11452 => 'ⲽ',
+  11454 => 'ⲿ',
+  11456 => 'ⳁ',
+  11458 => 'ⳃ',
+  11460 => 'ⳅ',
+  11462 => 'ⳇ',
+  11464 => 'ⳉ',
+  11466 => 'ⳋ',
+  11468 => 'ⳍ',
+  11470 => 'ⳏ',
+  11472 => 'ⳑ',
+  11474 => 'ⳓ',
+  11476 => 'ⳕ',
+  11478 => 'ⳗ',
+  11480 => 'ⳙ',
+  11482 => 'ⳛ',
+  11484 => 'ⳝ',
+  11486 => 'ⳟ',
+  11488 => 'ⳡ',
+  11490 => 'ⳣ',
+  11499 => 'ⳬ',
+  11501 => 'ⳮ',
+  11506 => 'ⳳ',
+  11631 => 'ⵡ',
+  11935 => '母',
+  12019 => '龟',
+  12032 => '一',
+  12033 => '丨',
+  12034 => '丶',
+  12035 => '丿',
+  12036 => '乙',
+  12037 => '亅',
+  12038 => '二',
+  12039 => '亠',
+  12040 => '人',
+  12041 => '儿',
+  12042 => '入',
+  12043 => '八',
+  12044 => '冂',
+  12045 => '冖',
+  12046 => '冫',
+  12047 => '几',
+  12048 => '凵',
+  12049 => '刀',
+  12050 => '力',
+  12051 => '勹',
+  12052 => '匕',
+  12053 => '匚',
+  12054 => '匸',
+  12055 => '十',
+  12056 => '卜',
+  12057 => '卩',
+  12058 => '厂',
+  12059 => '厶',
+  12060 => '又',
+  12061 => '口',
+  12062 => '囗',
+  12063 => '土',
+  12064 => '士',
+  12065 => '夂',
+  12066 => '夊',
+  12067 => '夕',
+  12068 => '大',
+  12069 => '女',
+  12070 => '子',
+  12071 => '宀',
+  12072 => '寸',
+  12073 => '小',
+  12074 => '尢',
+  12075 => '尸',
+  12076 => '屮',
+  12077 => '山',
+  12078 => '巛',
+  12079 => '工',
+  12080 => '己',
+  12081 => '巾',
+  12082 => '干',
+  12083 => '幺',
+  12084 => '广',
+  12085 => '廴',
+  12086 => '廾',
+  12087 => '弋',
+  12088 => '弓',
+  12089 => '彐',
+  12090 => '彡',
+  12091 => '彳',
+  12092 => '心',
+  12093 => '戈',
+  12094 => '戶',
+  12095 => '手',
+  12096 => '支',
+  12097 => '攴',
+  12098 => '文',
+  12099 => '斗',
+  12100 => '斤',
+  12101 => '方',
+  12102 => '无',
+  12103 => '日',
+  12104 => '曰',
+  12105 => '月',
+  12106 => '木',
+  12107 => '欠',
+  12108 => '止',
+  12109 => '歹',
+  12110 => '殳',
+  12111 => '毋',
+  12112 => '比',
+  12113 => '毛',
+  12114 => '氏',
+  12115 => '气',
+  12116 => '水',
+  12117 => '火',
+  12118 => '爪',
+  12119 => '父',
+  12120 => '爻',
+  12121 => '爿',
+  12122 => '片',
+  12123 => '牙',
+  12124 => '牛',
+  12125 => '犬',
+  12126 => '玄',
+  12127 => '玉',
+  12128 => '瓜',
+  12129 => '瓦',
+  12130 => '甘',
+  12131 => '生',
+  12132 => '用',
+  12133 => '田',
+  12134 => '疋',
+  12135 => '疒',
+  12136 => '癶',
+  12137 => '白',
+  12138 => '皮',
+  12139 => '皿',
+  12140 => '目',
+  12141 => '矛',
+  12142 => '矢',
+  12143 => '石',
+  12144 => '示',
+  12145 => '禸',
+  12146 => '禾',
+  12147 => '穴',
+  12148 => '立',
+  12149 => '竹',
+  12150 => '米',
+  12151 => '糸',
+  12152 => '缶',
+  12153 => '网',
+  12154 => '羊',
+  12155 => '羽',
+  12156 => '老',
+  12157 => '而',
+  12158 => '耒',
+  12159 => '耳',
+  12160 => '聿',
+  12161 => '肉',
+  12162 => '臣',
+  12163 => '自',
+  12164 => '至',
+  12165 => '臼',
+  12166 => '舌',
+  12167 => '舛',
+  12168 => '舟',
+  12169 => '艮',
+  12170 => '色',
+  12171 => '艸',
+  12172 => '虍',
+  12173 => '虫',
+  12174 => '血',
+  12175 => '行',
+  12176 => '衣',
+  12177 => '襾',
+  12178 => '見',
+  12179 => '角',
+  12180 => '言',
+  12181 => '谷',
+  12182 => '豆',
+  12183 => '豕',
+  12184 => '豸',
+  12185 => '貝',
+  12186 => '赤',
+  12187 => '走',
+  12188 => '足',
+  12189 => '身',
+  12190 => '車',
+  12191 => '辛',
+  12192 => '辰',
+  12193 => '辵',
+  12194 => '邑',
+  12195 => '酉',
+  12196 => '釆',
+  12197 => '里',
+  12198 => '金',
+  12199 => '長',
+  12200 => '門',
+  12201 => '阜',
+  12202 => '隶',
+  12203 => '隹',
+  12204 => '雨',
+  12205 => '靑',
+  12206 => '非',
+  12207 => '面',
+  12208 => '革',
+  12209 => '韋',
+  12210 => '韭',
+  12211 => '音',
+  12212 => '頁',
+  12213 => '風',
+  12214 => '飛',
+  12215 => '食',
+  12216 => '首',
+  12217 => '香',
+  12218 => '馬',
+  12219 => '骨',
+  12220 => '高',
+  12221 => '髟',
+  12222 => '鬥',
+  12223 => '鬯',
+  12224 => '鬲',
+  12225 => '鬼',
+  12226 => '魚',
+  12227 => '鳥',
+  12228 => '鹵',
+  12229 => '鹿',
+  12230 => '麥',
+  12231 => '麻',
+  12232 => '黃',
+  12233 => '黍',
+  12234 => '黑',
+  12235 => '黹',
+  12236 => '黽',
+  12237 => '鼎',
+  12238 => '鼓',
+  12239 => '鼠',
+  12240 => '鼻',
+  12241 => '齊',
+  12242 => '齒',
+  12243 => '龍',
+  12244 => '龜',
+  12245 => '龠',
+  12290 => '.',
+  12342 => '〒',
+  12344 => '十',
+  12345 => '卄',
+  12346 => '卅',
+  12447 => 'より',
+  12543 => 'コト',
+  12593 => 'ᄀ',
+  12594 => 'ᄁ',
+  12595 => 'ᆪ',
+  12596 => 'ᄂ',
+  12597 => 'ᆬ',
+  12598 => 'ᆭ',
+  12599 => 'ᄃ',
+  12600 => 'ᄄ',
+  12601 => 'ᄅ',
+  12602 => 'ᆰ',
+  12603 => 'ᆱ',
+  12604 => 'ᆲ',
+  12605 => 'ᆳ',
+  12606 => 'ᆴ',
+  12607 => 'ᆵ',
+  12608 => 'ᄚ',
+  12609 => 'ᄆ',
+  12610 => 'ᄇ',
+  12611 => 'ᄈ',
+  12612 => 'ᄡ',
+  12613 => 'ᄉ',
+  12614 => 'ᄊ',
+  12615 => 'ᄋ',
+  12616 => 'ᄌ',
+  12617 => 'ᄍ',
+  12618 => 'ᄎ',
+  12619 => 'ᄏ',
+  12620 => 'ᄐ',
+  12621 => 'ᄑ',
+  12622 => 'ᄒ',
+  12623 => 'ᅡ',
+  12624 => 'ᅢ',
+  12625 => 'ᅣ',
+  12626 => 'ᅤ',
+  12627 => 'ᅥ',
+  12628 => 'ᅦ',
+  12629 => 'ᅧ',
+  12630 => 'ᅨ',
+  12631 => 'ᅩ',
+  12632 => 'ᅪ',
+  12633 => 'ᅫ',
+  12634 => 'ᅬ',
+  12635 => 'ᅭ',
+  12636 => 'ᅮ',
+  12637 => 'ᅯ',
+  12638 => 'ᅰ',
+  12639 => 'ᅱ',
+  12640 => 'ᅲ',
+  12641 => 'ᅳ',
+  12642 => 'ᅴ',
+  12643 => 'ᅵ',
+  12645 => 'ᄔ',
+  12646 => 'ᄕ',
+  12647 => 'ᇇ',
+  12648 => 'ᇈ',
+  12649 => 'ᇌ',
+  12650 => 'ᇎ',
+  12651 => 'ᇓ',
+  12652 => 'ᇗ',
+  12653 => 'ᇙ',
+  12654 => 'ᄜ',
+  12655 => 'ᇝ',
+  12656 => 'ᇟ',
+  12657 => 'ᄝ',
+  12658 => 'ᄞ',
+  12659 => 'ᄠ',
+  12660 => 'ᄢ',
+  12661 => 'ᄣ',
+  12662 => 'ᄧ',
+  12663 => 'ᄩ',
+  12664 => 'ᄫ',
+  12665 => 'ᄬ',
+  12666 => 'ᄭ',
+  12667 => 'ᄮ',
+  12668 => 'ᄯ',
+  12669 => 'ᄲ',
+  12670 => 'ᄶ',
+  12671 => 'ᅀ',
+  12672 => 'ᅇ',
+  12673 => 'ᅌ',
+  12674 => 'ᇱ',
+  12675 => 'ᇲ',
+  12676 => 'ᅗ',
+  12677 => 'ᅘ',
+  12678 => 'ᅙ',
+  12679 => 'ᆄ',
+  12680 => 'ᆅ',
+  12681 => 'ᆈ',
+  12682 => 'ᆑ',
+  12683 => 'ᆒ',
+  12684 => 'ᆔ',
+  12685 => 'ᆞ',
+  12686 => 'ᆡ',
+  12690 => '一',
+  12691 => '二',
+  12692 => '三',
+  12693 => '四',
+  12694 => '上',
+  12695 => '中',
+  12696 => '下',
+  12697 => '甲',
+  12698 => '乙',
+  12699 => '丙',
+  12700 => '丁',
+  12701 => '天',
+  12702 => '地',
+  12703 => '人',
+  12868 => '問',
+  12869 => '幼',
+  12870 => '文',
+  12871 => '箏',
+  12880 => 'pte',
+  12881 => '21',
+  12882 => '22',
+  12883 => '23',
+  12884 => '24',
+  12885 => '25',
+  12886 => '26',
+  12887 => '27',
+  12888 => '28',
+  12889 => '29',
+  12890 => '30',
+  12891 => '31',
+  12892 => '32',
+  12893 => '33',
+  12894 => '34',
+  12895 => '35',
+  12896 => 'ᄀ',
+  12897 => 'ᄂ',
+  12898 => 'ᄃ',
+  12899 => 'ᄅ',
+  12900 => 'ᄆ',
+  12901 => 'ᄇ',
+  12902 => 'ᄉ',
+  12903 => 'ᄋ',
+  12904 => 'ᄌ',
+  12905 => 'ᄎ',
+  12906 => 'ᄏ',
+  12907 => 'ᄐ',
+  12908 => 'ᄑ',
+  12909 => 'ᄒ',
+  12910 => '가',
+  12911 => '나',
+  12912 => '다',
+  12913 => '라',
+  12914 => '마',
+  12915 => '바',
+  12916 => '사',
+  12917 => '아',
+  12918 => '자',
+  12919 => '차',
+  12920 => '카',
+  12921 => '타',
+  12922 => '파',
+  12923 => '하',
+  12924 => '참고',
+  12925 => '주의',
+  12926 => '우',
+  12928 => '一',
+  12929 => '二',
+  12930 => '三',
+  12931 => '四',
+  12932 => '五',
+  12933 => '六',
+  12934 => '七',
+  12935 => '八',
+  12936 => '九',
+  12937 => '十',
+  12938 => '月',
+  12939 => '火',
+  12940 => '水',
+  12941 => '木',
+  12942 => '金',
+  12943 => '土',
+  12944 => '日',
+  12945 => '株',
+  12946 => '有',
+  12947 => '社',
+  12948 => '名',
+  12949 => '特',
+  12950 => '財',
+  12951 => '祝',
+  12952 => '労',
+  12953 => '秘',
+  12954 => '男',
+  12955 => '女',
+  12956 => '適',
+  12957 => '優',
+  12958 => '印',
+  12959 => '注',
+  12960 => '項',
+  12961 => '休',
+  12962 => '写',
+  12963 => '正',
+  12964 => '上',
+  12965 => '中',
+  12966 => '下',
+  12967 => '左',
+  12968 => '右',
+  12969 => '医',
+  12970 => '宗',
+  12971 => '学',
+  12972 => '監',
+  12973 => '企',
+  12974 => '資',
+  12975 => '協',
+  12976 => '夜',
+  12977 => '36',
+  12978 => '37',
+  12979 => '38',
+  12980 => '39',
+  12981 => '40',
+  12982 => '41',
+  12983 => '42',
+  12984 => '43',
+  12985 => '44',
+  12986 => '45',
+  12987 => '46',
+  12988 => '47',
+  12989 => '48',
+  12990 => '49',
+  12991 => '50',
+  12992 => '1月',
+  12993 => '2月',
+  12994 => '3月',
+  12995 => '4月',
+  12996 => '5月',
+  12997 => '6月',
+  12998 => '7月',
+  12999 => '8月',
+  13000 => '9月',
+  13001 => '10月',
+  13002 => '11月',
+  13003 => '12月',
+  13004 => 'hg',
+  13005 => 'erg',
+  13006 => 'ev',
+  13007 => 'ltd',
+  13008 => 'ア',
+  13009 => 'イ',
+  13010 => 'ウ',
+  13011 => 'エ',
+  13012 => 'オ',
+  13013 => 'カ',
+  13014 => 'キ',
+  13015 => 'ク',
+  13016 => 'ケ',
+  13017 => 'コ',
+  13018 => 'サ',
+  13019 => 'シ',
+  13020 => 'ス',
+  13021 => 'セ',
+  13022 => 'ソ',
+  13023 => 'タ',
+  13024 => 'チ',
+  13025 => 'ツ',
+  13026 => 'テ',
+  13027 => 'ト',
+  13028 => 'ナ',
+  13029 => 'ニ',
+  13030 => 'ヌ',
+  13031 => 'ネ',
+  13032 => 'ノ',
+  13033 => 'ハ',
+  13034 => 'ヒ',
+  13035 => 'フ',
+  13036 => 'ヘ',
+  13037 => 'ホ',
+  13038 => 'マ',
+  13039 => 'ミ',
+  13040 => 'ム',
+  13041 => 'メ',
+  13042 => 'モ',
+  13043 => 'ヤ',
+  13044 => 'ユ',
+  13045 => 'ヨ',
+  13046 => 'ラ',
+  13047 => 'リ',
+  13048 => 'ル',
+  13049 => 'レ',
+  13050 => 'ロ',
+  13051 => 'ワ',
+  13052 => 'ヰ',
+  13053 => 'ヱ',
+  13054 => 'ヲ',
+  13055 => '令和',
+  13056 => 'アパート',
+  13057 => 'アルファ',
+  13058 => 'アンペア',
+  13059 => 'アール',
+  13060 => 'イニング',
+  13061 => 'インチ',
+  13062 => 'ウォン',
+  13063 => 'エスクード',
+  13064 => 'エーカー',
+  13065 => 'オンス',
+  13066 => 'オーム',
+  13067 => 'カイリ',
+  13068 => 'カラット',
+  13069 => 'カロリー',
+  13070 => 'ガロン',
+  13071 => 'ガンマ',
+  13072 => 'ギガ',
+  13073 => 'ギニー',
+  13074 => 'キュリー',
+  13075 => 'ギルダー',
+  13076 => 'キロ',
+  13077 => 'キログラム',
+  13078 => 'キロメートル',
+  13079 => 'キロワット',
+  13080 => 'グラム',
+  13081 => 'グラムトン',
+  13082 => 'クルゼイロ',
+  13083 => 'クローネ',
+  13084 => 'ケース',
+  13085 => 'コルナ',
+  13086 => 'コーポ',
+  13087 => 'サイクル',
+  13088 => 'サンチーム',
+  13089 => 'シリング',
+  13090 => 'センチ',
+  13091 => 'セント',
+  13092 => 'ダース',
+  13093 => 'デシ',
+  13094 => 'ドル',
+  13095 => 'トン',
+  13096 => 'ナノ',
+  13097 => 'ノット',
+  13098 => 'ハイツ',
+  13099 => 'パーセント',
+  13100 => 'パーツ',
+  13101 => 'バーレル',
+  13102 => 'ピアストル',
+  13103 => 'ピクル',
+  13104 => 'ピコ',
+  13105 => 'ビル',
+  13106 => 'ファラッド',
+  13107 => 'フィート',
+  13108 => 'ブッシェル',
+  13109 => 'フラン',
+  13110 => 'ヘクタール',
+  13111 => 'ペソ',
+  13112 => 'ペニヒ',
+  13113 => 'ヘルツ',
+  13114 => 'ペンス',
+  13115 => 'ページ',
+  13116 => 'ベータ',
+  13117 => 'ポイント',
+  13118 => 'ボルト',
+  13119 => 'ホン',
+  13120 => 'ポンド',
+  13121 => 'ホール',
+  13122 => 'ホーン',
+  13123 => 'マイクロ',
+  13124 => 'マイル',
+  13125 => 'マッハ',
+  13126 => 'マルク',
+  13127 => 'マンション',
+  13128 => 'ミクロン',
+  13129 => 'ミリ',
+  13130 => 'ミリバール',
+  13131 => 'メガ',
+  13132 => 'メガトン',
+  13133 => 'メートル',
+  13134 => 'ヤード',
+  13135 => 'ヤール',
+  13136 => 'ユアン',
+  13137 => 'リットル',
+  13138 => 'リラ',
+  13139 => 'ルピー',
+  13140 => 'ルーブル',
+  13141 => 'レム',
+  13142 => 'レントゲン',
+  13143 => 'ワット',
+  13144 => '0点',
+  13145 => '1点',
+  13146 => '2点',
+  13147 => '3点',
+  13148 => '4点',
+  13149 => '5点',
+  13150 => '6点',
+  13151 => '7点',
+  13152 => '8点',
+  13153 => '9点',
+  13154 => '10点',
+  13155 => '11点',
+  13156 => '12点',
+  13157 => '13点',
+  13158 => '14点',
+  13159 => '15点',
+  13160 => '16点',
+  13161 => '17点',
+  13162 => '18点',
+  13163 => '19点',
+  13164 => '20点',
+  13165 => '21点',
+  13166 => '22点',
+  13167 => '23点',
+  13168 => '24点',
+  13169 => 'hpa',
+  13170 => 'da',
+  13171 => 'au',
+  13172 => 'bar',
+  13173 => 'ov',
+  13174 => 'pc',
+  13175 => 'dm',
+  13176 => 'dm2',
+  13177 => 'dm3',
+  13178 => 'iu',
+  13179 => '平成',
+  13180 => '昭和',
+  13181 => '大正',
+  13182 => '明治',
+  13183 => '株式会社',
+  13184 => 'pa',
+  13185 => 'na',
+  13186 => 'μa',
+  13187 => 'ma',
+  13188 => 'ka',
+  13189 => 'kb',
+  13190 => 'mb',
+  13191 => 'gb',
+  13192 => 'cal',
+  13193 => 'kcal',
+  13194 => 'pf',
+  13195 => 'nf',
+  13196 => 'μf',
+  13197 => 'μg',
+  13198 => 'mg',
+  13199 => 'kg',
+  13200 => 'hz',
+  13201 => 'khz',
+  13202 => 'mhz',
+  13203 => 'ghz',
+  13204 => 'thz',
+  13205 => 'μl',
+  13206 => 'ml',
+  13207 => 'dl',
+  13208 => 'kl',
+  13209 => 'fm',
+  13210 => 'nm',
+  13211 => 'μm',
+  13212 => 'mm',
+  13213 => 'cm',
+  13214 => 'km',
+  13215 => 'mm2',
+  13216 => 'cm2',
+  13217 => 'm2',
+  13218 => 'km2',
+  13219 => 'mm3',
+  13220 => 'cm3',
+  13221 => 'm3',
+  13222 => 'km3',
+  13223 => 'm∕s',
+  13224 => 'm∕s2',
+  13225 => 'pa',
+  13226 => 'kpa',
+  13227 => 'mpa',
+  13228 => 'gpa',
+  13229 => 'rad',
+  13230 => 'rad∕s',
+  13231 => 'rad∕s2',
+  13232 => 'ps',
+  13233 => 'ns',
+  13234 => 'μs',
+  13235 => 'ms',
+  13236 => 'pv',
+  13237 => 'nv',
+  13238 => 'μv',
+  13239 => 'mv',
+  13240 => 'kv',
+  13241 => 'mv',
+  13242 => 'pw',
+  13243 => 'nw',
+  13244 => 'μw',
+  13245 => 'mw',
+  13246 => 'kw',
+  13247 => 'mw',
+  13248 => 'kω',
+  13249 => 'mω',
+  13251 => 'bq',
+  13252 => 'cc',
+  13253 => 'cd',
+  13254 => 'c∕kg',
+  13256 => 'db',
+  13257 => 'gy',
+  13258 => 'ha',
+  13259 => 'hp',
+  13260 => 'in',
+  13261 => 'kk',
+  13262 => 'km',
+  13263 => 'kt',
+  13264 => 'lm',
+  13265 => 'ln',
+  13266 => 'log',
+  13267 => 'lx',
+  13268 => 'mb',
+  13269 => 'mil',
+  13270 => 'mol',
+  13271 => 'ph',
+  13273 => 'ppm',
+  13274 => 'pr',
+  13275 => 'sr',
+  13276 => 'sv',
+  13277 => 'wb',
+  13278 => 'v∕m',
+  13279 => 'a∕m',
+  13280 => '1日',
+  13281 => '2日',
+  13282 => '3日',
+  13283 => '4日',
+  13284 => '5日',
+  13285 => '6日',
+  13286 => '7日',
+  13287 => '8日',
+  13288 => '9日',
+  13289 => '10日',
+  13290 => '11日',
+  13291 => '12日',
+  13292 => '13日',
+  13293 => '14日',
+  13294 => '15日',
+  13295 => '16日',
+  13296 => '17日',
+  13297 => '18日',
+  13298 => '19日',
+  13299 => '20日',
+  13300 => '21日',
+  13301 => '22日',
+  13302 => '23日',
+  13303 => '24日',
+  13304 => '25日',
+  13305 => '26日',
+  13306 => '27日',
+  13307 => '28日',
+  13308 => '29日',
+  13309 => '30日',
+  13310 => '31日',
+  13311 => 'gal',
+  42560 => 'ꙁ',
+  42562 => 'ꙃ',
+  42564 => 'ꙅ',
+  42566 => 'ꙇ',
+  42568 => 'ꙉ',
+  42570 => 'ꙋ',
+  42572 => 'ꙍ',
+  42574 => 'ꙏ',
+  42576 => 'ꙑ',
+  42578 => 'ꙓ',
+  42580 => 'ꙕ',
+  42582 => 'ꙗ',
+  42584 => 'ꙙ',
+  42586 => 'ꙛ',
+  42588 => 'ꙝ',
+  42590 => 'ꙟ',
+  42592 => 'ꙡ',
+  42594 => 'ꙣ',
+  42596 => 'ꙥ',
+  42598 => 'ꙧ',
+  42600 => 'ꙩ',
+  42602 => 'ꙫ',
+  42604 => 'ꙭ',
+  42624 => 'ꚁ',
+  42626 => 'ꚃ',
+  42628 => 'ꚅ',
+  42630 => 'ꚇ',
+  42632 => 'ꚉ',
+  42634 => 'ꚋ',
+  42636 => 'ꚍ',
+  42638 => 'ꚏ',
+  42640 => 'ꚑ',
+  42642 => 'ꚓ',
+  42644 => 'ꚕ',
+  42646 => 'ꚗ',
+  42648 => 'ꚙ',
+  42650 => 'ꚛ',
+  42652 => 'ъ',
+  42653 => 'ь',
+  42786 => 'ꜣ',
+  42788 => 'ꜥ',
+  42790 => 'ꜧ',
+  42792 => 'ꜩ',
+  42794 => 'ꜫ',
+  42796 => 'ꜭ',
+  42798 => 'ꜯ',
+  42802 => 'ꜳ',
+  42804 => 'ꜵ',
+  42806 => 'ꜷ',
+  42808 => 'ꜹ',
+  42810 => 'ꜻ',
+  42812 => 'ꜽ',
+  42814 => 'ꜿ',
+  42816 => 'ꝁ',
+  42818 => 'ꝃ',
+  42820 => 'ꝅ',
+  42822 => 'ꝇ',
+  42824 => 'ꝉ',
+  42826 => 'ꝋ',
+  42828 => 'ꝍ',
+  42830 => 'ꝏ',
+  42832 => 'ꝑ',
+  42834 => 'ꝓ',
+  42836 => 'ꝕ',
+  42838 => 'ꝗ',
+  42840 => 'ꝙ',
+  42842 => 'ꝛ',
+  42844 => 'ꝝ',
+  42846 => 'ꝟ',
+  42848 => 'ꝡ',
+  42850 => 'ꝣ',
+  42852 => 'ꝥ',
+  42854 => 'ꝧ',
+  42856 => 'ꝩ',
+  42858 => 'ꝫ',
+  42860 => 'ꝭ',
+  42862 => 'ꝯ',
+  42864 => 'ꝯ',
+  42873 => 'ꝺ',
+  42875 => 'ꝼ',
+  42877 => 'ᵹ',
+  42878 => 'ꝿ',
+  42880 => 'ꞁ',
+  42882 => 'ꞃ',
+  42884 => 'ꞅ',
+  42886 => 'ꞇ',
+  42891 => 'ꞌ',
+  42893 => 'ɥ',
+  42896 => 'ꞑ',
+  42898 => 'ꞓ',
+  42902 => 'ꞗ',
+  42904 => 'ꞙ',
+  42906 => 'ꞛ',
+  42908 => 'ꞝ',
+  42910 => 'ꞟ',
+  42912 => 'ꞡ',
+  42914 => 'ꞣ',
+  42916 => 'ꞥ',
+  42918 => 'ꞧ',
+  42920 => 'ꞩ',
+  42922 => 'ɦ',
+  42923 => 'ɜ',
+  42924 => 'ɡ',
+  42925 => 'ɬ',
+  42926 => 'ɪ',
+  42928 => 'ʞ',
+  42929 => 'ʇ',
+  42930 => 'ʝ',
+  42931 => 'ꭓ',
+  42932 => 'ꞵ',
+  42934 => 'ꞷ',
+  42936 => 'ꞹ',
+  42938 => 'ꞻ',
+  42940 => 'ꞽ',
+  42942 => 'ꞿ',
+  42946 => 'ꟃ',
+  42948 => 'ꞔ',
+  42949 => 'ʂ',
+  42950 => 'ᶎ',
+  42951 => 'ꟈ',
+  42953 => 'ꟊ',
+  42997 => 'ꟶ',
+  43000 => 'ħ',
+  43001 => 'œ',
+  43868 => 'ꜧ',
+  43869 => 'ꬷ',
+  43870 => 'ɫ',
+  43871 => 'ꭒ',
+  43881 => 'ʍ',
+  43888 => 'Ꭰ',
+  43889 => 'Ꭱ',
+  43890 => 'Ꭲ',
+  43891 => 'Ꭳ',
+  43892 => 'Ꭴ',
+  43893 => 'Ꭵ',
+  43894 => 'Ꭶ',
+  43895 => 'Ꭷ',
+  43896 => 'Ꭸ',
+  43897 => 'Ꭹ',
+  43898 => 'Ꭺ',
+  43899 => 'Ꭻ',
+  43900 => 'Ꭼ',
+  43901 => 'Ꭽ',
+  43902 => 'Ꭾ',
+  43903 => 'Ꭿ',
+  43904 => 'Ꮀ',
+  43905 => 'Ꮁ',
+  43906 => 'Ꮂ',
+  43907 => 'Ꮃ',
+  43908 => 'Ꮄ',
+  43909 => 'Ꮅ',
+  43910 => 'Ꮆ',
+  43911 => 'Ꮇ',
+  43912 => 'Ꮈ',
+  43913 => 'Ꮉ',
+  43914 => 'Ꮊ',
+  43915 => 'Ꮋ',
+  43916 => 'Ꮌ',
+  43917 => 'Ꮍ',
+  43918 => 'Ꮎ',
+  43919 => 'Ꮏ',
+  43920 => 'Ꮐ',
+  43921 => 'Ꮑ',
+  43922 => 'Ꮒ',
+  43923 => 'Ꮓ',
+  43924 => 'Ꮔ',
+  43925 => 'Ꮕ',
+  43926 => 'Ꮖ',
+  43927 => 'Ꮗ',
+  43928 => 'Ꮘ',
+  43929 => 'Ꮙ',
+  43930 => 'Ꮚ',
+  43931 => 'Ꮛ',
+  43932 => 'Ꮜ',
+  43933 => 'Ꮝ',
+  43934 => 'Ꮞ',
+  43935 => 'Ꮟ',
+  43936 => 'Ꮠ',
+  43937 => 'Ꮡ',
+  43938 => 'Ꮢ',
+  43939 => 'Ꮣ',
+  43940 => 'Ꮤ',
+  43941 => 'Ꮥ',
+  43942 => 'Ꮦ',
+  43943 => 'Ꮧ',
+  43944 => 'Ꮨ',
+  43945 => 'Ꮩ',
+  43946 => 'Ꮪ',
+  43947 => 'Ꮫ',
+  43948 => 'Ꮬ',
+  43949 => 'Ꮭ',
+  43950 => 'Ꮮ',
+  43951 => 'Ꮯ',
+  43952 => 'Ꮰ',
+  43953 => 'Ꮱ',
+  43954 => 'Ꮲ',
+  43955 => 'Ꮳ',
+  43956 => 'Ꮴ',
+  43957 => 'Ꮵ',
+  43958 => 'Ꮶ',
+  43959 => 'Ꮷ',
+  43960 => 'Ꮸ',
+  43961 => 'Ꮹ',
+  43962 => 'Ꮺ',
+  43963 => 'Ꮻ',
+  43964 => 'Ꮼ',
+  43965 => 'Ꮽ',
+  43966 => 'Ꮾ',
+  43967 => 'Ꮿ',
+  63744 => '豈',
+  63745 => '更',
+  63746 => '車',
+  63747 => '賈',
+  63748 => '滑',
+  63749 => '串',
+  63750 => '句',
+  63751 => '龜',
+  63752 => '龜',
+  63753 => '契',
+  63754 => '金',
+  63755 => '喇',
+  63756 => '奈',
+  63757 => '懶',
+  63758 => '癩',
+  63759 => '羅',
+  63760 => '蘿',
+  63761 => '螺',
+  63762 => '裸',
+  63763 => '邏',
+  63764 => '樂',
+  63765 => '洛',
+  63766 => '烙',
+  63767 => '珞',
+  63768 => '落',
+  63769 => '酪',
+  63770 => '駱',
+  63771 => '亂',
+  63772 => '卵',
+  63773 => '欄',
+  63774 => '爛',
+  63775 => '蘭',
+  63776 => '鸞',
+  63777 => '嵐',
+  63778 => '濫',
+  63779 => '藍',
+  63780 => '襤',
+  63781 => '拉',
+  63782 => '臘',
+  63783 => '蠟',
+  63784 => '廊',
+  63785 => '朗',
+  63786 => '浪',
+  63787 => '狼',
+  63788 => '郎',
+  63789 => '來',
+  63790 => '冷',
+  63791 => '勞',
+  63792 => '擄',
+  63793 => '櫓',
+  63794 => '爐',
+  63795 => '盧',
+  63796 => '老',
+  63797 => '蘆',
+  63798 => '虜',
+  63799 => '路',
+  63800 => '露',
+  63801 => '魯',
+  63802 => '鷺',
+  63803 => '碌',
+  63804 => '祿',
+  63805 => '綠',
+  63806 => '菉',
+  63807 => '錄',
+  63808 => '鹿',
+  63809 => '論',
+  63810 => '壟',
+  63811 => '弄',
+  63812 => '籠',
+  63813 => '聾',
+  63814 => '牢',
+  63815 => '磊',
+  63816 => '賂',
+  63817 => '雷',
+  63818 => '壘',
+  63819 => '屢',
+  63820 => '樓',
+  63821 => '淚',
+  63822 => '漏',
+  63823 => '累',
+  63824 => '縷',
+  63825 => '陋',
+  63826 => '勒',
+  63827 => '肋',
+  63828 => '凜',
+  63829 => '凌',
+  63830 => '稜',
+  63831 => '綾',
+  63832 => '菱',
+  63833 => '陵',
+  63834 => '讀',
+  63835 => '拏',
+  63836 => '樂',
+  63837 => '諾',
+  63838 => '丹',
+  63839 => '寧',
+  63840 => '怒',
+  63841 => '率',
+  63842 => '異',
+  63843 => '北',
+  63844 => '磻',
+  63845 => '便',
+  63846 => '復',
+  63847 => '不',
+  63848 => '泌',
+  63849 => '數',
+  63850 => '索',
+  63851 => '參',
+  63852 => '塞',
+  63853 => '省',
+  63854 => '葉',
+  63855 => '說',
+  63856 => '殺',
+  63857 => '辰',
+  63858 => '沈',
+  63859 => '拾',
+  63860 => '若',
+  63861 => '掠',
+  63862 => '略',
+  63863 => '亮',
+  63864 => '兩',
+  63865 => '凉',
+  63866 => '梁',
+  63867 => '糧',
+  63868 => '良',
+  63869 => '諒',
+  63870 => '量',
+  63871 => '勵',
+  63872 => '呂',
+  63873 => '女',
+  63874 => '廬',
+  63875 => '旅',
+  63876 => '濾',
+  63877 => '礪',
+  63878 => '閭',
+  63879 => '驪',
+  63880 => '麗',
+  63881 => '黎',
+  63882 => '力',
+  63883 => '曆',
+  63884 => '歷',
+  63885 => '轢',
+  63886 => '年',
+  63887 => '憐',
+  63888 => '戀',
+  63889 => '撚',
+  63890 => '漣',
+  63891 => '煉',
+  63892 => '璉',
+  63893 => '秊',
+  63894 => '練',
+  63895 => '聯',
+  63896 => '輦',
+  63897 => '蓮',
+  63898 => '連',
+  63899 => '鍊',
+  63900 => '列',
+  63901 => '劣',
+  63902 => '咽',
+  63903 => '烈',
+  63904 => '裂',
+  63905 => '說',
+  63906 => '廉',
+  63907 => '念',
+  63908 => '捻',
+  63909 => '殮',
+  63910 => '簾',
+  63911 => '獵',
+  63912 => '令',
+  63913 => '囹',
+  63914 => '寧',
+  63915 => '嶺',
+  63916 => '怜',
+  63917 => '玲',
+  63918 => '瑩',
+  63919 => '羚',
+  63920 => '聆',
+  63921 => '鈴',
+  63922 => '零',
+  63923 => '靈',
+  63924 => '領',
+  63925 => '例',
+  63926 => '禮',
+  63927 => '醴',
+  63928 => '隸',
+  63929 => '惡',
+  63930 => '了',
+  63931 => '僚',
+  63932 => '寮',
+  63933 => '尿',
+  63934 => '料',
+  63935 => '樂',
+  63936 => '燎',
+  63937 => '療',
+  63938 => '蓼',
+  63939 => '遼',
+  63940 => '龍',
+  63941 => '暈',
+  63942 => '阮',
+  63943 => '劉',
+  63944 => '杻',
+  63945 => '柳',
+  63946 => '流',
+  63947 => '溜',
+  63948 => '琉',
+  63949 => '留',
+  63950 => '硫',
+  63951 => '紐',
+  63952 => '類',
+  63953 => '六',
+  63954 => '戮',
+  63955 => '陸',
+  63956 => '倫',
+  63957 => '崙',
+  63958 => '淪',
+  63959 => '輪',
+  63960 => '律',
+  63961 => '慄',
+  63962 => '栗',
+  63963 => '率',
+  63964 => '隆',
+  63965 => '利',
+  63966 => '吏',
+  63967 => '履',
+  63968 => '易',
+  63969 => '李',
+  63970 => '梨',
+  63971 => '泥',
+  63972 => '理',
+  63973 => '痢',
+  63974 => '罹',
+  63975 => '裏',
+  63976 => '裡',
+  63977 => '里',
+  63978 => '離',
+  63979 => '匿',
+  63980 => '溺',
+  63981 => '吝',
+  63982 => '燐',
+  63983 => '璘',
+  63984 => '藺',
+  63985 => '隣',
+  63986 => '鱗',
+  63987 => '麟',
+  63988 => '林',
+  63989 => '淋',
+  63990 => '臨',
+  63991 => '立',
+  63992 => '笠',
+  63993 => '粒',
+  63994 => '狀',
+  63995 => '炙',
+  63996 => '識',
+  63997 => '什',
+  63998 => '茶',
+  63999 => '刺',
+  64000 => '切',
+  64001 => '度',
+  64002 => '拓',
+  64003 => '糖',
+  64004 => '宅',
+  64005 => '洞',
+  64006 => '暴',
+  64007 => '輻',
+  64008 => '行',
+  64009 => '降',
+  64010 => '見',
+  64011 => '廓',
+  64012 => '兀',
+  64013 => '嗀',
+  64016 => '塚',
+  64018 => '晴',
+  64021 => '凞',
+  64022 => '猪',
+  64023 => '益',
+  64024 => '礼',
+  64025 => '神',
+  64026 => '祥',
+  64027 => '福',
+  64028 => '靖',
+  64029 => '精',
+  64030 => '羽',
+  64032 => '蘒',
+  64034 => '諸',
+  64037 => '逸',
+  64038 => '都',
+  64042 => '飯',
+  64043 => '飼',
+  64044 => '館',
+  64045 => '鶴',
+  64046 => '郞',
+  64047 => '隷',
+  64048 => '侮',
+  64049 => '僧',
+  64050 => '免',
+  64051 => '勉',
+  64052 => '勤',
+  64053 => '卑',
+  64054 => '喝',
+  64055 => '嘆',
+  64056 => '器',
+  64057 => '塀',
+  64058 => '墨',
+  64059 => '層',
+  64060 => '屮',
+  64061 => '悔',
+  64062 => '慨',
+  64063 => '憎',
+  64064 => '懲',
+  64065 => '敏',
+  64066 => '既',
+  64067 => '暑',
+  64068 => '梅',
+  64069 => '海',
+  64070 => '渚',
+  64071 => '漢',
+  64072 => '煮',
+  64073 => '爫',
+  64074 => '琢',
+  64075 => '碑',
+  64076 => '社',
+  64077 => '祉',
+  64078 => '祈',
+  64079 => '祐',
+  64080 => '祖',
+  64081 => '祝',
+  64082 => '禍',
+  64083 => '禎',
+  64084 => '穀',
+  64085 => '突',
+  64086 => '節',
+  64087 => '練',
+  64088 => '縉',
+  64089 => '繁',
+  64090 => '署',
+  64091 => '者',
+  64092 => '臭',
+  64093 => '艹',
+  64094 => '艹',
+  64095 => '著',
+  64096 => '褐',
+  64097 => '視',
+  64098 => '謁',
+  64099 => '謹',
+  64100 => '賓',
+  64101 => '贈',
+  64102 => '辶',
+  64103 => '逸',
+  64104 => '難',
+  64105 => '響',
+  64106 => '頻',
+  64107 => '恵',
+  64108 => '𤋮',
+  64109 => '舘',
+  64112 => '並',
+  64113 => '况',
+  64114 => '全',
+  64115 => '侀',
+  64116 => '充',
+  64117 => '冀',
+  64118 => '勇',
+  64119 => '勺',
+  64120 => '喝',
+  64121 => '啕',
+  64122 => '喙',
+  64123 => '嗢',
+  64124 => '塚',
+  64125 => '墳',
+  64126 => '奄',
+  64127 => '奔',
+  64128 => '婢',
+  64129 => '嬨',
+  64130 => '廒',
+  64131 => '廙',
+  64132 => '彩',
+  64133 => '徭',
+  64134 => '惘',
+  64135 => '慎',
+  64136 => '愈',
+  64137 => '憎',
+  64138 => '慠',
+  64139 => '懲',
+  64140 => '戴',
+  64141 => '揄',
+  64142 => '搜',
+  64143 => '摒',
+  64144 => '敖',
+  64145 => '晴',
+  64146 => '朗',
+  64147 => '望',
+  64148 => '杖',
+  64149 => '歹',
+  64150 => '殺',
+  64151 => '流',
+  64152 => '滛',
+  64153 => '滋',
+  64154 => '漢',
+  64155 => '瀞',
+  64156 => '煮',
+  64157 => '瞧',
+  64158 => '爵',
+  64159 => '犯',
+  64160 => '猪',
+  64161 => '瑱',
+  64162 => '甆',
+  64163 => '画',
+  64164 => '瘝',
+  64165 => '瘟',
+  64166 => '益',
+  64167 => '盛',
+  64168 => '直',
+  64169 => '睊',
+  64170 => '着',
+  64171 => '磌',
+  64172 => '窱',
+  64173 => '節',
+  64174 => '类',
+  64175 => '絛',
+  64176 => '練',
+  64177 => '缾',
+  64178 => '者',
+  64179 => '荒',
+  64180 => '華',
+  64181 => '蝹',
+  64182 => '襁',
+  64183 => '覆',
+  64184 => '視',
+  64185 => '調',
+  64186 => '諸',
+  64187 => '請',
+  64188 => '謁',
+  64189 => '諾',
+  64190 => '諭',
+  64191 => '謹',
+  64192 => '變',
+  64193 => '贈',
+  64194 => '輸',
+  64195 => '遲',
+  64196 => '醙',
+  64197 => '鉶',
+  64198 => '陼',
+  64199 => '難',
+  64200 => '靖',
+  64201 => '韛',
+  64202 => '響',
+  64203 => '頋',
+  64204 => '頻',
+  64205 => '鬒',
+  64206 => '龜',
+  64207 => '𢡊',
+  64208 => '𢡄',
+  64209 => '𣏕',
+  64210 => '㮝',
+  64211 => '䀘',
+  64212 => '䀹',
+  64213 => '𥉉',
+  64214 => '𥳐',
+  64215 => '𧻓',
+  64216 => '齃',
+  64217 => '龎',
+  64256 => 'ff',
+  64257 => 'fi',
+  64258 => 'fl',
+  64259 => 'ffi',
+  64260 => 'ffl',
+  64261 => 'st',
+  64262 => 'st',
+  64275 => 'մն',
+  64276 => 'մե',
+  64277 => 'մի',
+  64278 => 'վն',
+  64279 => 'մխ',
+  64285 => 'יִ',
+  64287 => 'ײַ',
+  64288 => 'ע',
+  64289 => 'א',
+  64290 => 'ד',
+  64291 => 'ה',
+  64292 => 'כ',
+  64293 => 'ל',
+  64294 => 'ם',
+  64295 => 'ר',
+  64296 => 'ת',
+  64298 => 'שׁ',
+  64299 => 'שׂ',
+  64300 => 'שּׁ',
+  64301 => 'שּׂ',
+  64302 => 'אַ',
+  64303 => 'אָ',
+  64304 => 'אּ',
+  64305 => 'בּ',
+  64306 => 'גּ',
+  64307 => 'דּ',
+  64308 => 'הּ',
+  64309 => 'וּ',
+  64310 => 'זּ',
+  64312 => 'טּ',
+  64313 => 'יּ',
+  64314 => 'ךּ',
+  64315 => 'כּ',
+  64316 => 'לּ',
+  64318 => 'מּ',
+  64320 => 'נּ',
+  64321 => 'סּ',
+  64323 => 'ףּ',
+  64324 => 'פּ',
+  64326 => 'צּ',
+  64327 => 'קּ',
+  64328 => 'רּ',
+  64329 => 'שּ',
+  64330 => 'תּ',
+  64331 => 'וֹ',
+  64332 => 'בֿ',
+  64333 => 'כֿ',
+  64334 => 'פֿ',
+  64335 => 'אל',
+  64336 => 'ٱ',
+  64337 => 'ٱ',
+  64338 => 'ٻ',
+  64339 => 'ٻ',
+  64340 => 'ٻ',
+  64341 => 'ٻ',
+  64342 => 'پ',
+  64343 => 'پ',
+  64344 => 'پ',
+  64345 => 'پ',
+  64346 => 'ڀ',
+  64347 => 'ڀ',
+  64348 => 'ڀ',
+  64349 => 'ڀ',
+  64350 => 'ٺ',
+  64351 => 'ٺ',
+  64352 => 'ٺ',
+  64353 => 'ٺ',
+  64354 => 'ٿ',
+  64355 => 'ٿ',
+  64356 => 'ٿ',
+  64357 => 'ٿ',
+  64358 => 'ٹ',
+  64359 => 'ٹ',
+  64360 => 'ٹ',
+  64361 => 'ٹ',
+  64362 => 'ڤ',
+  64363 => 'ڤ',
+  64364 => 'ڤ',
+  64365 => 'ڤ',
+  64366 => 'ڦ',
+  64367 => 'ڦ',
+  64368 => 'ڦ',
+  64369 => 'ڦ',
+  64370 => 'ڄ',
+  64371 => 'ڄ',
+  64372 => 'ڄ',
+  64373 => 'ڄ',
+  64374 => 'ڃ',
+  64375 => 'ڃ',
+  64376 => 'ڃ',
+  64377 => 'ڃ',
+  64378 => 'چ',
+  64379 => 'چ',
+  64380 => 'چ',
+  64381 => 'چ',
+  64382 => 'ڇ',
+  64383 => 'ڇ',
+  64384 => 'ڇ',
+  64385 => 'ڇ',
+  64386 => 'ڍ',
+  64387 => 'ڍ',
+  64388 => 'ڌ',
+  64389 => 'ڌ',
+  64390 => 'ڎ',
+  64391 => 'ڎ',
+  64392 => 'ڈ',
+  64393 => 'ڈ',
+  64394 => 'ژ',
+  64395 => 'ژ',
+  64396 => 'ڑ',
+  64397 => 'ڑ',
+  64398 => 'ک',
+  64399 => 'ک',
+  64400 => 'ک',
+  64401 => 'ک',
+  64402 => 'گ',
+  64403 => 'گ',
+  64404 => 'گ',
+  64405 => 'گ',
+  64406 => 'ڳ',
+  64407 => 'ڳ',
+  64408 => 'ڳ',
+  64409 => 'ڳ',
+  64410 => 'ڱ',
+  64411 => 'ڱ',
+  64412 => 'ڱ',
+  64413 => 'ڱ',
+  64414 => 'ں',
+  64415 => 'ں',
+  64416 => 'ڻ',
+  64417 => 'ڻ',
+  64418 => 'ڻ',
+  64419 => 'ڻ',
+  64420 => 'ۀ',
+  64421 => 'ۀ',
+  64422 => 'ہ',
+  64423 => 'ہ',
+  64424 => 'ہ',
+  64425 => 'ہ',
+  64426 => 'ھ',
+  64427 => 'ھ',
+  64428 => 'ھ',
+  64429 => 'ھ',
+  64430 => 'ے',
+  64431 => 'ے',
+  64432 => 'ۓ',
+  64433 => 'ۓ',
+  64467 => 'ڭ',
+  64468 => 'ڭ',
+  64469 => 'ڭ',
+  64470 => 'ڭ',
+  64471 => 'ۇ',
+  64472 => 'ۇ',
+  64473 => 'ۆ',
+  64474 => 'ۆ',
+  64475 => 'ۈ',
+  64476 => 'ۈ',
+  64477 => 'ۇٴ',
+  64478 => 'ۋ',
+  64479 => 'ۋ',
+  64480 => 'ۅ',
+  64481 => 'ۅ',
+  64482 => 'ۉ',
+  64483 => 'ۉ',
+  64484 => 'ې',
+  64485 => 'ې',
+  64486 => 'ې',
+  64487 => 'ې',
+  64488 => 'ى',
+  64489 => 'ى',
+  64490 => 'ئا',
+  64491 => 'ئا',
+  64492 => 'ئە',
+  64493 => 'ئە',
+  64494 => 'ئو',
+  64495 => 'ئو',
+  64496 => 'ئۇ',
+  64497 => 'ئۇ',
+  64498 => 'ئۆ',
+  64499 => 'ئۆ',
+  64500 => 'ئۈ',
+  64501 => 'ئۈ',
+  64502 => 'ئې',
+  64503 => 'ئې',
+  64504 => 'ئې',
+  64505 => 'ئى',
+  64506 => 'ئى',
+  64507 => 'ئى',
+  64508 => 'ی',
+  64509 => 'ی',
+  64510 => 'ی',
+  64511 => 'ی',
+  64512 => 'ئج',
+  64513 => 'ئح',
+  64514 => 'ئم',
+  64515 => 'ئى',
+  64516 => 'ئي',
+  64517 => 'بج',
+  64518 => 'بح',
+  64519 => 'بخ',
+  64520 => 'بم',
+  64521 => 'بى',
+  64522 => 'بي',
+  64523 => 'تج',
+  64524 => 'تح',
+  64525 => 'تخ',
+  64526 => 'تم',
+  64527 => 'تى',
+  64528 => 'تي',
+  64529 => 'ثج',
+  64530 => 'ثم',
+  64531 => 'ثى',
+  64532 => 'ثي',
+  64533 => 'جح',
+  64534 => 'جم',
+  64535 => 'حج',
+  64536 => 'حم',
+  64537 => 'خج',
+  64538 => 'خح',
+  64539 => 'خم',
+  64540 => 'سج',
+  64541 => 'سح',
+  64542 => 'سخ',
+  64543 => 'سم',
+  64544 => 'صح',
+  64545 => 'صم',
+  64546 => 'ضج',
+  64547 => 'ضح',
+  64548 => 'ضخ',
+  64549 => 'ضم',
+  64550 => 'طح',
+  64551 => 'طم',
+  64552 => 'ظم',
+  64553 => 'عج',
+  64554 => 'عم',
+  64555 => 'غج',
+  64556 => 'غم',
+  64557 => 'فج',
+  64558 => 'فح',
+  64559 => 'فخ',
+  64560 => 'فم',
+  64561 => 'فى',
+  64562 => 'في',
+  64563 => 'قح',
+  64564 => 'قم',
+  64565 => 'قى',
+  64566 => 'قي',
+  64567 => 'كا',
+  64568 => 'كج',
+  64569 => 'كح',
+  64570 => 'كخ',
+  64571 => 'كل',
+  64572 => 'كم',
+  64573 => 'كى',
+  64574 => 'كي',
+  64575 => 'لج',
+  64576 => 'لح',
+  64577 => 'لخ',
+  64578 => 'لم',
+  64579 => 'لى',
+  64580 => 'لي',
+  64581 => 'مج',
+  64582 => 'مح',
+  64583 => 'مخ',
+  64584 => 'مم',
+  64585 => 'مى',
+  64586 => 'مي',
+  64587 => 'نج',
+  64588 => 'نح',
+  64589 => 'نخ',
+  64590 => 'نم',
+  64591 => 'نى',
+  64592 => 'ني',
+  64593 => 'هج',
+  64594 => 'هم',
+  64595 => 'هى',
+  64596 => 'هي',
+  64597 => 'يج',
+  64598 => 'يح',
+  64599 => 'يخ',
+  64600 => 'يم',
+  64601 => 'يى',
+  64602 => 'يي',
+  64603 => 'ذٰ',
+  64604 => 'رٰ',
+  64605 => 'ىٰ',
+  64612 => 'ئر',
+  64613 => 'ئز',
+  64614 => 'ئم',
+  64615 => 'ئن',
+  64616 => 'ئى',
+  64617 => 'ئي',
+  64618 => 'بر',
+  64619 => 'بز',
+  64620 => 'بم',
+  64621 => 'بن',
+  64622 => 'بى',
+  64623 => 'بي',
+  64624 => 'تر',
+  64625 => 'تز',
+  64626 => 'تم',
+  64627 => 'تن',
+  64628 => 'تى',
+  64629 => 'تي',
+  64630 => 'ثر',
+  64631 => 'ثز',
+  64632 => 'ثم',
+  64633 => 'ثن',
+  64634 => 'ثى',
+  64635 => 'ثي',
+  64636 => 'فى',
+  64637 => 'في',
+  64638 => 'قى',
+  64639 => 'قي',
+  64640 => 'كا',
+  64641 => 'كل',
+  64642 => 'كم',
+  64643 => 'كى',
+  64644 => 'كي',
+  64645 => 'لم',
+  64646 => 'لى',
+  64647 => 'لي',
+  64648 => 'ما',
+  64649 => 'مم',
+  64650 => 'نر',
+  64651 => 'نز',
+  64652 => 'نم',
+  64653 => 'نن',
+  64654 => 'نى',
+  64655 => 'ني',
+  64656 => 'ىٰ',
+  64657 => 'ير',
+  64658 => 'يز',
+  64659 => 'يم',
+  64660 => 'ين',
+  64661 => 'يى',
+  64662 => 'يي',
+  64663 => 'ئج',
+  64664 => 'ئح',
+  64665 => 'ئخ',
+  64666 => 'ئم',
+  64667 => 'ئه',
+  64668 => 'بج',
+  64669 => 'بح',
+  64670 => 'بخ',
+  64671 => 'بم',
+  64672 => 'به',
+  64673 => 'تج',
+  64674 => 'تح',
+  64675 => 'تخ',
+  64676 => 'تم',
+  64677 => 'ته',
+  64678 => 'ثم',
+  64679 => 'جح',
+  64680 => 'جم',
+  64681 => 'حج',
+  64682 => 'حم',
+  64683 => 'خج',
+  64684 => 'خم',
+  64685 => 'سج',
+  64686 => 'سح',
+  64687 => 'سخ',
+  64688 => 'سم',
+  64689 => 'صح',
+  64690 => 'صخ',
+  64691 => 'صم',
+  64692 => 'ضج',
+  64693 => 'ضح',
+  64694 => 'ضخ',
+  64695 => 'ضم',
+  64696 => 'طح',
+  64697 => 'ظم',
+  64698 => 'عج',
+  64699 => 'عم',
+  64700 => 'غج',
+  64701 => 'غم',
+  64702 => 'فج',
+  64703 => 'فح',
+  64704 => 'فخ',
+  64705 => 'فم',
+  64706 => 'قح',
+  64707 => 'قم',
+  64708 => 'كج',
+  64709 => 'كح',
+  64710 => 'كخ',
+  64711 => 'كل',
+  64712 => 'كم',
+  64713 => 'لج',
+  64714 => 'لح',
+  64715 => 'لخ',
+  64716 => 'لم',
+  64717 => 'له',
+  64718 => 'مج',
+  64719 => 'مح',
+  64720 => 'مخ',
+  64721 => 'مم',
+  64722 => 'نج',
+  64723 => 'نح',
+  64724 => 'نخ',
+  64725 => 'نم',
+  64726 => 'نه',
+  64727 => 'هج',
+  64728 => 'هم',
+  64729 => 'هٰ',
+  64730 => 'يج',
+  64731 => 'يح',
+  64732 => 'يخ',
+  64733 => 'يم',
+  64734 => 'يه',
+  64735 => 'ئم',
+  64736 => 'ئه',
+  64737 => 'بم',
+  64738 => 'به',
+  64739 => 'تم',
+  64740 => 'ته',
+  64741 => 'ثم',
+  64742 => 'ثه',
+  64743 => 'سم',
+  64744 => 'سه',
+  64745 => 'شم',
+  64746 => 'شه',
+  64747 => 'كل',
+  64748 => 'كم',
+  64749 => 'لم',
+  64750 => 'نم',
+  64751 => 'نه',
+  64752 => 'يم',
+  64753 => 'يه',
+  64754 => 'ـَّ',
+  64755 => 'ـُّ',
+  64756 => 'ـِّ',
+  64757 => 'طى',
+  64758 => 'طي',
+  64759 => 'عى',
+  64760 => 'عي',
+  64761 => 'غى',
+  64762 => 'غي',
+  64763 => 'سى',
+  64764 => 'سي',
+  64765 => 'شى',
+  64766 => 'شي',
+  64767 => 'حى',
+  64768 => 'حي',
+  64769 => 'جى',
+  64770 => 'جي',
+  64771 => 'خى',
+  64772 => 'خي',
+  64773 => 'صى',
+  64774 => 'صي',
+  64775 => 'ضى',
+  64776 => 'ضي',
+  64777 => 'شج',
+  64778 => 'شح',
+  64779 => 'شخ',
+  64780 => 'شم',
+  64781 => 'شر',
+  64782 => 'سر',
+  64783 => 'صر',
+  64784 => 'ضر',
+  64785 => 'طى',
+  64786 => 'طي',
+  64787 => 'عى',
+  64788 => 'عي',
+  64789 => 'غى',
+  64790 => 'غي',
+  64791 => 'سى',
+  64792 => 'سي',
+  64793 => 'شى',
+  64794 => 'شي',
+  64795 => 'حى',
+  64796 => 'حي',
+  64797 => 'جى',
+  64798 => 'جي',
+  64799 => 'خى',
+  64800 => 'خي',
+  64801 => 'صى',
+  64802 => 'صي',
+  64803 => 'ضى',
+  64804 => 'ضي',
+  64805 => 'شج',
+  64806 => 'شح',
+  64807 => 'شخ',
+  64808 => 'شم',
+  64809 => 'شر',
+  64810 => 'سر',
+  64811 => 'صر',
+  64812 => 'ضر',
+  64813 => 'شج',
+  64814 => 'شح',
+  64815 => 'شخ',
+  64816 => 'شم',
+  64817 => 'سه',
+  64818 => 'شه',
+  64819 => 'طم',
+  64820 => 'سج',
+  64821 => 'سح',
+  64822 => 'سخ',
+  64823 => 'شج',
+  64824 => 'شح',
+  64825 => 'شخ',
+  64826 => 'طم',
+  64827 => 'ظم',
+  64828 => 'اً',
+  64829 => 'اً',
+  64848 => 'تجم',
+  64849 => 'تحج',
+  64850 => 'تحج',
+  64851 => 'تحم',
+  64852 => 'تخم',
+  64853 => 'تمج',
+  64854 => 'تمح',
+  64855 => 'تمخ',
+  64856 => 'جمح',
+  64857 => 'جمح',
+  64858 => 'حمي',
+  64859 => 'حمى',
+  64860 => 'سحج',
+  64861 => 'سجح',
+  64862 => 'سجى',
+  64863 => 'سمح',
+  64864 => 'سمح',
+  64865 => 'سمج',
+  64866 => 'سمم',
+  64867 => 'سمم',
+  64868 => 'صحح',
+  64869 => 'صحح',
+  64870 => 'صمم',
+  64871 => 'شحم',
+  64872 => 'شحم',
+  64873 => 'شجي',
+  64874 => 'شمخ',
+  64875 => 'شمخ',
+  64876 => 'شمم',
+  64877 => 'شمم',
+  64878 => 'ضحى',
+  64879 => 'ضخم',
+  64880 => 'ضخم',
+  64881 => 'طمح',
+  64882 => 'طمح',
+  64883 => 'طمم',
+  64884 => 'طمي',
+  64885 => 'عجم',
+  64886 => 'عمم',
+  64887 => 'عمم',
+  64888 => 'عمى',
+  64889 => 'غمم',
+  64890 => 'غمي',
+  64891 => 'غمى',
+  64892 => 'فخم',
+  64893 => 'فخم',
+  64894 => 'قمح',
+  64895 => 'قمم',
+  64896 => 'لحم',
+  64897 => 'لحي',
+  64898 => 'لحى',
+  64899 => 'لجج',
+  64900 => 'لجج',
+  64901 => 'لخم',
+  64902 => 'لخم',
+  64903 => 'لمح',
+  64904 => 'لمح',
+  64905 => 'محج',
+  64906 => 'محم',
+  64907 => 'محي',
+  64908 => 'مجح',
+  64909 => 'مجم',
+  64910 => 'مخج',
+  64911 => 'مخم',
+  64914 => 'مجخ',
+  64915 => 'همج',
+  64916 => 'همم',
+  64917 => 'نحم',
+  64918 => 'نحى',
+  64919 => 'نجم',
+  64920 => 'نجم',
+  64921 => 'نجى',
+  64922 => 'نمي',
+  64923 => 'نمى',
+  64924 => 'يمم',
+  64925 => 'يمم',
+  64926 => 'بخي',
+  64927 => 'تجي',
+  64928 => 'تجى',
+  64929 => 'تخي',
+  64930 => 'تخى',
+  64931 => 'تمي',
+  64932 => 'تمى',
+  64933 => 'جمي',
+  64934 => 'جحى',
+  64935 => 'جمى',
+  64936 => 'سخى',
+  64937 => 'صحي',
+  64938 => 'شحي',
+  64939 => 'ضحي',
+  64940 => 'لجي',
+  64941 => 'لمي',
+  64942 => 'يحي',
+  64943 => 'يجي',
+  64944 => 'يمي',
+  64945 => 'ممي',
+  64946 => 'قمي',
+  64947 => 'نحي',
+  64948 => 'قمح',
+  64949 => 'لحم',
+  64950 => 'عمي',
+  64951 => 'كمي',
+  64952 => 'نجح',
+  64953 => 'مخي',
+  64954 => 'لجم',
+  64955 => 'كمم',
+  64956 => 'لجم',
+  64957 => 'نجح',
+  64958 => 'جحي',
+  64959 => 'حجي',
+  64960 => 'مجي',
+  64961 => 'فمي',
+  64962 => 'بحي',
+  64963 => 'كمم',
+  64964 => 'عجم',
+  64965 => 'صمم',
+  64966 => 'سخي',
+  64967 => 'نجي',
+  65008 => 'صلے',
+  65009 => 'قلے',
+  65010 => 'الله',
+  65011 => 'اكبر',
+  65012 => 'محمد',
+  65013 => 'صلعم',
+  65014 => 'رسول',
+  65015 => 'عليه',
+  65016 => 'وسلم',
+  65017 => 'صلى',
+  65020 => 'ریال',
+  65041 => '、',
+  65047 => '〖',
+  65048 => '〗',
+  65073 => '—',
+  65074 => '–',
+  65081 => '〔',
+  65082 => '〕',
+  65083 => '【',
+  65084 => '】',
+  65085 => '《',
+  65086 => '》',
+  65087 => '〈',
+  65088 => '〉',
+  65089 => '「',
+  65090 => '」',
+  65091 => '『',
+  65092 => '』',
+  65105 => '、',
+  65112 => '—',
+  65117 => '〔',
+  65118 => '〕',
+  65123 => '-',
+  65137 => 'ـً',
+  65143 => 'ـَ',
+  65145 => 'ـُ',
+  65147 => 'ـِ',
+  65149 => 'ـّ',
+  65151 => 'ـْ',
+  65152 => 'ء',
+  65153 => 'آ',
+  65154 => 'آ',
+  65155 => 'أ',
+  65156 => 'أ',
+  65157 => 'ؤ',
+  65158 => 'ؤ',
+  65159 => 'إ',
+  65160 => 'إ',
+  65161 => 'ئ',
+  65162 => 'ئ',
+  65163 => 'ئ',
+  65164 => 'ئ',
+  65165 => 'ا',
+  65166 => 'ا',
+  65167 => 'ب',
+  65168 => 'ب',
+  65169 => 'ب',
+  65170 => 'ب',
+  65171 => 'ة',
+  65172 => 'ة',
+  65173 => 'ت',
+  65174 => 'ت',
+  65175 => 'ت',
+  65176 => 'ت',
+  65177 => 'ث',
+  65178 => 'ث',
+  65179 => 'ث',
+  65180 => 'ث',
+  65181 => 'ج',
+  65182 => 'ج',
+  65183 => 'ج',
+  65184 => 'ج',
+  65185 => 'ح',
+  65186 => 'ح',
+  65187 => 'ح',
+  65188 => 'ح',
+  65189 => 'خ',
+  65190 => 'خ',
+  65191 => 'خ',
+  65192 => 'خ',
+  65193 => 'د',
+  65194 => 'د',
+  65195 => 'ذ',
+  65196 => 'ذ',
+  65197 => 'ر',
+  65198 => 'ر',
+  65199 => 'ز',
+  65200 => 'ز',
+  65201 => 'س',
+  65202 => 'س',
+  65203 => 'س',
+  65204 => 'س',
+  65205 => 'ش',
+  65206 => 'ش',
+  65207 => 'ش',
+  65208 => 'ش',
+  65209 => 'ص',
+  65210 => 'ص',
+  65211 => 'ص',
+  65212 => 'ص',
+  65213 => 'ض',
+  65214 => 'ض',
+  65215 => 'ض',
+  65216 => 'ض',
+  65217 => 'ط',
+  65218 => 'ط',
+  65219 => 'ط',
+  65220 => 'ط',
+  65221 => 'ظ',
+  65222 => 'ظ',
+  65223 => 'ظ',
+  65224 => 'ظ',
+  65225 => 'ع',
+  65226 => 'ع',
+  65227 => 'ع',
+  65228 => 'ع',
+  65229 => 'غ',
+  65230 => 'غ',
+  65231 => 'غ',
+  65232 => 'غ',
+  65233 => 'ف',
+  65234 => 'ف',
+  65235 => 'ف',
+  65236 => 'ف',
+  65237 => 'ق',
+  65238 => 'ق',
+  65239 => 'ق',
+  65240 => 'ق',
+  65241 => 'ك',
+  65242 => 'ك',
+  65243 => 'ك',
+  65244 => 'ك',
+  65245 => 'ل',
+  65246 => 'ل',
+  65247 => 'ل',
+  65248 => 'ل',
+  65249 => 'م',
+  65250 => 'م',
+  65251 => 'م',
+  65252 => 'م',
+  65253 => 'ن',
+  65254 => 'ن',
+  65255 => 'ن',
+  65256 => 'ن',
+  65257 => 'ه',
+  65258 => 'ه',
+  65259 => 'ه',
+  65260 => 'ه',
+  65261 => 'و',
+  65262 => 'و',
+  65263 => 'ى',
+  65264 => 'ى',
+  65265 => 'ي',
+  65266 => 'ي',
+  65267 => 'ي',
+  65268 => 'ي',
+  65269 => 'لآ',
+  65270 => 'لآ',
+  65271 => 'لأ',
+  65272 => 'لأ',
+  65273 => 'لإ',
+  65274 => 'لإ',
+  65275 => 'لا',
+  65276 => 'لا',
+  65293 => '-',
+  65294 => '.',
+  65296 => '0',
+  65297 => '1',
+  65298 => '2',
+  65299 => '3',
+  65300 => '4',
+  65301 => '5',
+  65302 => '6',
+  65303 => '7',
+  65304 => '8',
+  65305 => '9',
+  65313 => 'a',
+  65314 => 'b',
+  65315 => 'c',
+  65316 => 'd',
+  65317 => 'e',
+  65318 => 'f',
+  65319 => 'g',
+  65320 => 'h',
+  65321 => 'i',
+  65322 => 'j',
+  65323 => 'k',
+  65324 => 'l',
+  65325 => 'm',
+  65326 => 'n',
+  65327 => 'o',
+  65328 => 'p',
+  65329 => 'q',
+  65330 => 'r',
+  65331 => 's',
+  65332 => 't',
+  65333 => 'u',
+  65334 => 'v',
+  65335 => 'w',
+  65336 => 'x',
+  65337 => 'y',
+  65338 => 'z',
+  65345 => 'a',
+  65346 => 'b',
+  65347 => 'c',
+  65348 => 'd',
+  65349 => 'e',
+  65350 => 'f',
+  65351 => 'g',
+  65352 => 'h',
+  65353 => 'i',
+  65354 => 'j',
+  65355 => 'k',
+  65356 => 'l',
+  65357 => 'm',
+  65358 => 'n',
+  65359 => 'o',
+  65360 => 'p',
+  65361 => 'q',
+  65362 => 'r',
+  65363 => 's',
+  65364 => 't',
+  65365 => 'u',
+  65366 => 'v',
+  65367 => 'w',
+  65368 => 'x',
+  65369 => 'y',
+  65370 => 'z',
+  65375 => '⦅',
+  65376 => '⦆',
+  65377 => '.',
+  65378 => '「',
+  65379 => '」',
+  65380 => '、',
+  65381 => '・',
+  65382 => 'ヲ',
+  65383 => 'ァ',
+  65384 => 'ィ',
+  65385 => 'ゥ',
+  65386 => 'ェ',
+  65387 => 'ォ',
+  65388 => 'ャ',
+  65389 => 'ュ',
+  65390 => 'ョ',
+  65391 => 'ッ',
+  65392 => 'ー',
+  65393 => 'ア',
+  65394 => 'イ',
+  65395 => 'ウ',
+  65396 => 'エ',
+  65397 => 'オ',
+  65398 => 'カ',
+  65399 => 'キ',
+  65400 => 'ク',
+  65401 => 'ケ',
+  65402 => 'コ',
+  65403 => 'サ',
+  65404 => 'シ',
+  65405 => 'ス',
+  65406 => 'セ',
+  65407 => 'ソ',
+  65408 => 'タ',
+  65409 => 'チ',
+  65410 => 'ツ',
+  65411 => 'テ',
+  65412 => 'ト',
+  65413 => 'ナ',
+  65414 => 'ニ',
+  65415 => 'ヌ',
+  65416 => 'ネ',
+  65417 => 'ノ',
+  65418 => 'ハ',
+  65419 => 'ヒ',
+  65420 => 'フ',
+  65421 => 'ヘ',
+  65422 => 'ホ',
+  65423 => 'マ',
+  65424 => 'ミ',
+  65425 => 'ム',
+  65426 => 'メ',
+  65427 => 'モ',
+  65428 => 'ヤ',
+  65429 => 'ユ',
+  65430 => 'ヨ',
+  65431 => 'ラ',
+  65432 => 'リ',
+  65433 => 'ル',
+  65434 => 'レ',
+  65435 => 'ロ',
+  65436 => 'ワ',
+  65437 => 'ン',
+  65438 => '゙',
+  65439 => '゚',
+  65441 => 'ᄀ',
+  65442 => 'ᄁ',
+  65443 => 'ᆪ',
+  65444 => 'ᄂ',
+  65445 => 'ᆬ',
+  65446 => 'ᆭ',
+  65447 => 'ᄃ',
+  65448 => 'ᄄ',
+  65449 => 'ᄅ',
+  65450 => 'ᆰ',
+  65451 => 'ᆱ',
+  65452 => 'ᆲ',
+  65453 => 'ᆳ',
+  65454 => 'ᆴ',
+  65455 => 'ᆵ',
+  65456 => 'ᄚ',
+  65457 => 'ᄆ',
+  65458 => 'ᄇ',
+  65459 => 'ᄈ',
+  65460 => 'ᄡ',
+  65461 => 'ᄉ',
+  65462 => 'ᄊ',
+  65463 => 'ᄋ',
+  65464 => 'ᄌ',
+  65465 => 'ᄍ',
+  65466 => 'ᄎ',
+  65467 => 'ᄏ',
+  65468 => 'ᄐ',
+  65469 => 'ᄑ',
+  65470 => 'ᄒ',
+  65474 => 'ᅡ',
+  65475 => 'ᅢ',
+  65476 => 'ᅣ',
+  65477 => 'ᅤ',
+  65478 => 'ᅥ',
+  65479 => 'ᅦ',
+  65482 => 'ᅧ',
+  65483 => 'ᅨ',
+  65484 => 'ᅩ',
+  65485 => 'ᅪ',
+  65486 => 'ᅫ',
+  65487 => 'ᅬ',
+  65490 => 'ᅭ',
+  65491 => 'ᅮ',
+  65492 => 'ᅯ',
+  65493 => 'ᅰ',
+  65494 => 'ᅱ',
+  65495 => 'ᅲ',
+  65498 => 'ᅳ',
+  65499 => 'ᅴ',
+  65500 => 'ᅵ',
+  65504 => '¢',
+  65505 => '£',
+  65506 => '¬',
+  65508 => '¦',
+  65509 => '¥',
+  65510 => '₩',
+  65512 => '│',
+  65513 => '←',
+  65514 => '↑',
+  65515 => '→',
+  65516 => '↓',
+  65517 => '■',
+  65518 => '○',
+  66560 => '𐐨',
+  66561 => '𐐩',
+  66562 => '𐐪',
+  66563 => '𐐫',
+  66564 => '𐐬',
+  66565 => '𐐭',
+  66566 => '𐐮',
+  66567 => '𐐯',
+  66568 => '𐐰',
+  66569 => '𐐱',
+  66570 => '𐐲',
+  66571 => '𐐳',
+  66572 => '𐐴',
+  66573 => '𐐵',
+  66574 => '𐐶',
+  66575 => '𐐷',
+  66576 => '𐐸',
+  66577 => '𐐹',
+  66578 => '𐐺',
+  66579 => '𐐻',
+  66580 => '𐐼',
+  66581 => '𐐽',
+  66582 => '𐐾',
+  66583 => '𐐿',
+  66584 => '𐑀',
+  66585 => '𐑁',
+  66586 => '𐑂',
+  66587 => '𐑃',
+  66588 => '𐑄',
+  66589 => '𐑅',
+  66590 => '𐑆',
+  66591 => '𐑇',
+  66592 => '𐑈',
+  66593 => '𐑉',
+  66594 => '𐑊',
+  66595 => '𐑋',
+  66596 => '𐑌',
+  66597 => '𐑍',
+  66598 => '𐑎',
+  66599 => '𐑏',
+  66736 => '𐓘',
+  66737 => '𐓙',
+  66738 => '𐓚',
+  66739 => '𐓛',
+  66740 => '𐓜',
+  66741 => '𐓝',
+  66742 => '𐓞',
+  66743 => '𐓟',
+  66744 => '𐓠',
+  66745 => '𐓡',
+  66746 => '𐓢',
+  66747 => '𐓣',
+  66748 => '𐓤',
+  66749 => '𐓥',
+  66750 => '𐓦',
+  66751 => '𐓧',
+  66752 => '𐓨',
+  66753 => '𐓩',
+  66754 => '𐓪',
+  66755 => '𐓫',
+  66756 => '𐓬',
+  66757 => '𐓭',
+  66758 => '𐓮',
+  66759 => '𐓯',
+  66760 => '𐓰',
+  66761 => '𐓱',
+  66762 => '𐓲',
+  66763 => '𐓳',
+  66764 => '𐓴',
+  66765 => '𐓵',
+  66766 => '𐓶',
+  66767 => '𐓷',
+  66768 => '𐓸',
+  66769 => '𐓹',
+  66770 => '𐓺',
+  66771 => '𐓻',
+  68736 => '𐳀',
+  68737 => '𐳁',
+  68738 => '𐳂',
+  68739 => '𐳃',
+  68740 => '𐳄',
+  68741 => '𐳅',
+  68742 => '𐳆',
+  68743 => '𐳇',
+  68744 => '𐳈',
+  68745 => '𐳉',
+  68746 => '𐳊',
+  68747 => '𐳋',
+  68748 => '𐳌',
+  68749 => '𐳍',
+  68750 => '𐳎',
+  68751 => '𐳏',
+  68752 => '𐳐',
+  68753 => '𐳑',
+  68754 => '𐳒',
+  68755 => '𐳓',
+  68756 => '𐳔',
+  68757 => '𐳕',
+  68758 => '𐳖',
+  68759 => '𐳗',
+  68760 => '𐳘',
+  68761 => '𐳙',
+  68762 => '𐳚',
+  68763 => '𐳛',
+  68764 => '𐳜',
+  68765 => '𐳝',
+  68766 => '𐳞',
+  68767 => '𐳟',
+  68768 => '𐳠',
+  68769 => '𐳡',
+  68770 => '𐳢',
+  68771 => '𐳣',
+  68772 => '𐳤',
+  68773 => '𐳥',
+  68774 => '𐳦',
+  68775 => '𐳧',
+  68776 => '𐳨',
+  68777 => '𐳩',
+  68778 => '𐳪',
+  68779 => '𐳫',
+  68780 => '𐳬',
+  68781 => '𐳭',
+  68782 => '𐳮',
+  68783 => '𐳯',
+  68784 => '𐳰',
+  68785 => '𐳱',
+  68786 => '𐳲',
+  71840 => '𑣀',
+  71841 => '𑣁',
+  71842 => '𑣂',
+  71843 => '𑣃',
+  71844 => '𑣄',
+  71845 => '𑣅',
+  71846 => '𑣆',
+  71847 => '𑣇',
+  71848 => '𑣈',
+  71849 => '𑣉',
+  71850 => '𑣊',
+  71851 => '𑣋',
+  71852 => '𑣌',
+  71853 => '𑣍',
+  71854 => '𑣎',
+  71855 => '𑣏',
+  71856 => '𑣐',
+  71857 => '𑣑',
+  71858 => '𑣒',
+  71859 => '𑣓',
+  71860 => '𑣔',
+  71861 => '𑣕',
+  71862 => '𑣖',
+  71863 => '𑣗',
+  71864 => '𑣘',
+  71865 => '𑣙',
+  71866 => '𑣚',
+  71867 => '𑣛',
+  71868 => '𑣜',
+  71869 => '𑣝',
+  71870 => '𑣞',
+  71871 => '𑣟',
+  93760 => '𖹠',
+  93761 => '𖹡',
+  93762 => '𖹢',
+  93763 => '𖹣',
+  93764 => '𖹤',
+  93765 => '𖹥',
+  93766 => '𖹦',
+  93767 => '𖹧',
+  93768 => '𖹨',
+  93769 => '𖹩',
+  93770 => '𖹪',
+  93771 => '𖹫',
+  93772 => '𖹬',
+  93773 => '𖹭',
+  93774 => '𖹮',
+  93775 => '𖹯',
+  93776 => '𖹰',
+  93777 => '𖹱',
+  93778 => '𖹲',
+  93779 => '𖹳',
+  93780 => '𖹴',
+  93781 => '𖹵',
+  93782 => '𖹶',
+  93783 => '𖹷',
+  93784 => '𖹸',
+  93785 => '𖹹',
+  93786 => '𖹺',
+  93787 => '𖹻',
+  93788 => '𖹼',
+  93789 => '𖹽',
+  93790 => '𖹾',
+  93791 => '𖹿',
+  119134 => '𝅗𝅥',
+  119135 => '𝅘𝅥',
+  119136 => '𝅘𝅥𝅮',
+  119137 => '𝅘𝅥𝅯',
+  119138 => '𝅘𝅥𝅰',
+  119139 => '𝅘𝅥𝅱',
+  119140 => '𝅘𝅥𝅲',
+  119227 => '𝆹𝅥',
+  119228 => '𝆺𝅥',
+  119229 => '𝆹𝅥𝅮',
+  119230 => '𝆺𝅥𝅮',
+  119231 => '𝆹𝅥𝅯',
+  119232 => '𝆺𝅥𝅯',
+  119808 => 'a',
+  119809 => 'b',
+  119810 => 'c',
+  119811 => 'd',
+  119812 => 'e',
+  119813 => 'f',
+  119814 => 'g',
+  119815 => 'h',
+  119816 => 'i',
+  119817 => 'j',
+  119818 => 'k',
+  119819 => 'l',
+  119820 => 'm',
+  119821 => 'n',
+  119822 => 'o',
+  119823 => 'p',
+  119824 => 'q',
+  119825 => 'r',
+  119826 => 's',
+  119827 => 't',
+  119828 => 'u',
+  119829 => 'v',
+  119830 => 'w',
+  119831 => 'x',
+  119832 => 'y',
+  119833 => 'z',
+  119834 => 'a',
+  119835 => 'b',
+  119836 => 'c',
+  119837 => 'd',
+  119838 => 'e',
+  119839 => 'f',
+  119840 => 'g',
+  119841 => 'h',
+  119842 => 'i',
+  119843 => 'j',
+  119844 => 'k',
+  119845 => 'l',
+  119846 => 'm',
+  119847 => 'n',
+  119848 => 'o',
+  119849 => 'p',
+  119850 => 'q',
+  119851 => 'r',
+  119852 => 's',
+  119853 => 't',
+  119854 => 'u',
+  119855 => 'v',
+  119856 => 'w',
+  119857 => 'x',
+  119858 => 'y',
+  119859 => 'z',
+  119860 => 'a',
+  119861 => 'b',
+  119862 => 'c',
+  119863 => 'd',
+  119864 => 'e',
+  119865 => 'f',
+  119866 => 'g',
+  119867 => 'h',
+  119868 => 'i',
+  119869 => 'j',
+  119870 => 'k',
+  119871 => 'l',
+  119872 => 'm',
+  119873 => 'n',
+  119874 => 'o',
+  119875 => 'p',
+  119876 => 'q',
+  119877 => 'r',
+  119878 => 's',
+  119879 => 't',
+  119880 => 'u',
+  119881 => 'v',
+  119882 => 'w',
+  119883 => 'x',
+  119884 => 'y',
+  119885 => 'z',
+  119886 => 'a',
+  119887 => 'b',
+  119888 => 'c',
+  119889 => 'd',
+  119890 => 'e',
+  119891 => 'f',
+  119892 => 'g',
+  119894 => 'i',
+  119895 => 'j',
+  119896 => 'k',
+  119897 => 'l',
+  119898 => 'm',
+  119899 => 'n',
+  119900 => 'o',
+  119901 => 'p',
+  119902 => 'q',
+  119903 => 'r',
+  119904 => 's',
+  119905 => 't',
+  119906 => 'u',
+  119907 => 'v',
+  119908 => 'w',
+  119909 => 'x',
+  119910 => 'y',
+  119911 => 'z',
+  119912 => 'a',
+  119913 => 'b',
+  119914 => 'c',
+  119915 => 'd',
+  119916 => 'e',
+  119917 => 'f',
+  119918 => 'g',
+  119919 => 'h',
+  119920 => 'i',
+  119921 => 'j',
+  119922 => 'k',
+  119923 => 'l',
+  119924 => 'm',
+  119925 => 'n',
+  119926 => 'o',
+  119927 => 'p',
+  119928 => 'q',
+  119929 => 'r',
+  119930 => 's',
+  119931 => 't',
+  119932 => 'u',
+  119933 => 'v',
+  119934 => 'w',
+  119935 => 'x',
+  119936 => 'y',
+  119937 => 'z',
+  119938 => 'a',
+  119939 => 'b',
+  119940 => 'c',
+  119941 => 'd',
+  119942 => 'e',
+  119943 => 'f',
+  119944 => 'g',
+  119945 => 'h',
+  119946 => 'i',
+  119947 => 'j',
+  119948 => 'k',
+  119949 => 'l',
+  119950 => 'm',
+  119951 => 'n',
+  119952 => 'o',
+  119953 => 'p',
+  119954 => 'q',
+  119955 => 'r',
+  119956 => 's',
+  119957 => 't',
+  119958 => 'u',
+  119959 => 'v',
+  119960 => 'w',
+  119961 => 'x',
+  119962 => 'y',
+  119963 => 'z',
+  119964 => 'a',
+  119966 => 'c',
+  119967 => 'd',
+  119970 => 'g',
+  119973 => 'j',
+  119974 => 'k',
+  119977 => 'n',
+  119978 => 'o',
+  119979 => 'p',
+  119980 => 'q',
+  119982 => 's',
+  119983 => 't',
+  119984 => 'u',
+  119985 => 'v',
+  119986 => 'w',
+  119987 => 'x',
+  119988 => 'y',
+  119989 => 'z',
+  119990 => 'a',
+  119991 => 'b',
+  119992 => 'c',
+  119993 => 'd',
+  119995 => 'f',
+  119997 => 'h',
+  119998 => 'i',
+  119999 => 'j',
+  120000 => 'k',
+  120001 => 'l',
+  120002 => 'm',
+  120003 => 'n',
+  120005 => 'p',
+  120006 => 'q',
+  120007 => 'r',
+  120008 => 's',
+  120009 => 't',
+  120010 => 'u',
+  120011 => 'v',
+  120012 => 'w',
+  120013 => 'x',
+  120014 => 'y',
+  120015 => 'z',
+  120016 => 'a',
+  120017 => 'b',
+  120018 => 'c',
+  120019 => 'd',
+  120020 => 'e',
+  120021 => 'f',
+  120022 => 'g',
+  120023 => 'h',
+  120024 => 'i',
+  120025 => 'j',
+  120026 => 'k',
+  120027 => 'l',
+  120028 => 'm',
+  120029 => 'n',
+  120030 => 'o',
+  120031 => 'p',
+  120032 => 'q',
+  120033 => 'r',
+  120034 => 's',
+  120035 => 't',
+  120036 => 'u',
+  120037 => 'v',
+  120038 => 'w',
+  120039 => 'x',
+  120040 => 'y',
+  120041 => 'z',
+  120042 => 'a',
+  120043 => 'b',
+  120044 => 'c',
+  120045 => 'd',
+  120046 => 'e',
+  120047 => 'f',
+  120048 => 'g',
+  120049 => 'h',
+  120050 => 'i',
+  120051 => 'j',
+  120052 => 'k',
+  120053 => 'l',
+  120054 => 'm',
+  120055 => 'n',
+  120056 => 'o',
+  120057 => 'p',
+  120058 => 'q',
+  120059 => 'r',
+  120060 => 's',
+  120061 => 't',
+  120062 => 'u',
+  120063 => 'v',
+  120064 => 'w',
+  120065 => 'x',
+  120066 => 'y',
+  120067 => 'z',
+  120068 => 'a',
+  120069 => 'b',
+  120071 => 'd',
+  120072 => 'e',
+  120073 => 'f',
+  120074 => 'g',
+  120077 => 'j',
+  120078 => 'k',
+  120079 => 'l',
+  120080 => 'm',
+  120081 => 'n',
+  120082 => 'o',
+  120083 => 'p',
+  120084 => 'q',
+  120086 => 's',
+  120087 => 't',
+  120088 => 'u',
+  120089 => 'v',
+  120090 => 'w',
+  120091 => 'x',
+  120092 => 'y',
+  120094 => 'a',
+  120095 => 'b',
+  120096 => 'c',
+  120097 => 'd',
+  120098 => 'e',
+  120099 => 'f',
+  120100 => 'g',
+  120101 => 'h',
+  120102 => 'i',
+  120103 => 'j',
+  120104 => 'k',
+  120105 => 'l',
+  120106 => 'm',
+  120107 => 'n',
+  120108 => 'o',
+  120109 => 'p',
+  120110 => 'q',
+  120111 => 'r',
+  120112 => 's',
+  120113 => 't',
+  120114 => 'u',
+  120115 => 'v',
+  120116 => 'w',
+  120117 => 'x',
+  120118 => 'y',
+  120119 => 'z',
+  120120 => 'a',
+  120121 => 'b',
+  120123 => 'd',
+  120124 => 'e',
+  120125 => 'f',
+  120126 => 'g',
+  120128 => 'i',
+  120129 => 'j',
+  120130 => 'k',
+  120131 => 'l',
+  120132 => 'm',
+  120134 => 'o',
+  120138 => 's',
+  120139 => 't',
+  120140 => 'u',
+  120141 => 'v',
+  120142 => 'w',
+  120143 => 'x',
+  120144 => 'y',
+  120146 => 'a',
+  120147 => 'b',
+  120148 => 'c',
+  120149 => 'd',
+  120150 => 'e',
+  120151 => 'f',
+  120152 => 'g',
+  120153 => 'h',
+  120154 => 'i',
+  120155 => 'j',
+  120156 => 'k',
+  120157 => 'l',
+  120158 => 'm',
+  120159 => 'n',
+  120160 => 'o',
+  120161 => 'p',
+  120162 => 'q',
+  120163 => 'r',
+  120164 => 's',
+  120165 => 't',
+  120166 => 'u',
+  120167 => 'v',
+  120168 => 'w',
+  120169 => 'x',
+  120170 => 'y',
+  120171 => 'z',
+  120172 => 'a',
+  120173 => 'b',
+  120174 => 'c',
+  120175 => 'd',
+  120176 => 'e',
+  120177 => 'f',
+  120178 => 'g',
+  120179 => 'h',
+  120180 => 'i',
+  120181 => 'j',
+  120182 => 'k',
+  120183 => 'l',
+  120184 => 'm',
+  120185 => 'n',
+  120186 => 'o',
+  120187 => 'p',
+  120188 => 'q',
+  120189 => 'r',
+  120190 => 's',
+  120191 => 't',
+  120192 => 'u',
+  120193 => 'v',
+  120194 => 'w',
+  120195 => 'x',
+  120196 => 'y',
+  120197 => 'z',
+  120198 => 'a',
+  120199 => 'b',
+  120200 => 'c',
+  120201 => 'd',
+  120202 => 'e',
+  120203 => 'f',
+  120204 => 'g',
+  120205 => 'h',
+  120206 => 'i',
+  120207 => 'j',
+  120208 => 'k',
+  120209 => 'l',
+  120210 => 'm',
+  120211 => 'n',
+  120212 => 'o',
+  120213 => 'p',
+  120214 => 'q',
+  120215 => 'r',
+  120216 => 's',
+  120217 => 't',
+  120218 => 'u',
+  120219 => 'v',
+  120220 => 'w',
+  120221 => 'x',
+  120222 => 'y',
+  120223 => 'z',
+  120224 => 'a',
+  120225 => 'b',
+  120226 => 'c',
+  120227 => 'd',
+  120228 => 'e',
+  120229 => 'f',
+  120230 => 'g',
+  120231 => 'h',
+  120232 => 'i',
+  120233 => 'j',
+  120234 => 'k',
+  120235 => 'l',
+  120236 => 'm',
+  120237 => 'n',
+  120238 => 'o',
+  120239 => 'p',
+  120240 => 'q',
+  120241 => 'r',
+  120242 => 's',
+  120243 => 't',
+  120244 => 'u',
+  120245 => 'v',
+  120246 => 'w',
+  120247 => 'x',
+  120248 => 'y',
+  120249 => 'z',
+  120250 => 'a',
+  120251 => 'b',
+  120252 => 'c',
+  120253 => 'd',
+  120254 => 'e',
+  120255 => 'f',
+  120256 => 'g',
+  120257 => 'h',
+  120258 => 'i',
+  120259 => 'j',
+  120260 => 'k',
+  120261 => 'l',
+  120262 => 'm',
+  120263 => 'n',
+  120264 => 'o',
+  120265 => 'p',
+  120266 => 'q',
+  120267 => 'r',
+  120268 => 's',
+  120269 => 't',
+  120270 => 'u',
+  120271 => 'v',
+  120272 => 'w',
+  120273 => 'x',
+  120274 => 'y',
+  120275 => 'z',
+  120276 => 'a',
+  120277 => 'b',
+  120278 => 'c',
+  120279 => 'd',
+  120280 => 'e',
+  120281 => 'f',
+  120282 => 'g',
+  120283 => 'h',
+  120284 => 'i',
+  120285 => 'j',
+  120286 => 'k',
+  120287 => 'l',
+  120288 => 'm',
+  120289 => 'n',
+  120290 => 'o',
+  120291 => 'p',
+  120292 => 'q',
+  120293 => 'r',
+  120294 => 's',
+  120295 => 't',
+  120296 => 'u',
+  120297 => 'v',
+  120298 => 'w',
+  120299 => 'x',
+  120300 => 'y',
+  120301 => 'z',
+  120302 => 'a',
+  120303 => 'b',
+  120304 => 'c',
+  120305 => 'd',
+  120306 => 'e',
+  120307 => 'f',
+  120308 => 'g',
+  120309 => 'h',
+  120310 => 'i',
+  120311 => 'j',
+  120312 => 'k',
+  120313 => 'l',
+  120314 => 'm',
+  120315 => 'n',
+  120316 => 'o',
+  120317 => 'p',
+  120318 => 'q',
+  120319 => 'r',
+  120320 => 's',
+  120321 => 't',
+  120322 => 'u',
+  120323 => 'v',
+  120324 => 'w',
+  120325 => 'x',
+  120326 => 'y',
+  120327 => 'z',
+  120328 => 'a',
+  120329 => 'b',
+  120330 => 'c',
+  120331 => 'd',
+  120332 => 'e',
+  120333 => 'f',
+  120334 => 'g',
+  120335 => 'h',
+  120336 => 'i',
+  120337 => 'j',
+  120338 => 'k',
+  120339 => 'l',
+  120340 => 'm',
+  120341 => 'n',
+  120342 => 'o',
+  120343 => 'p',
+  120344 => 'q',
+  120345 => 'r',
+  120346 => 's',
+  120347 => 't',
+  120348 => 'u',
+  120349 => 'v',
+  120350 => 'w',
+  120351 => 'x',
+  120352 => 'y',
+  120353 => 'z',
+  120354 => 'a',
+  120355 => 'b',
+  120356 => 'c',
+  120357 => 'd',
+  120358 => 'e',
+  120359 => 'f',
+  120360 => 'g',
+  120361 => 'h',
+  120362 => 'i',
+  120363 => 'j',
+  120364 => 'k',
+  120365 => 'l',
+  120366 => 'm',
+  120367 => 'n',
+  120368 => 'o',
+  120369 => 'p',
+  120370 => 'q',
+  120371 => 'r',
+  120372 => 's',
+  120373 => 't',
+  120374 => 'u',
+  120375 => 'v',
+  120376 => 'w',
+  120377 => 'x',
+  120378 => 'y',
+  120379 => 'z',
+  120380 => 'a',
+  120381 => 'b',
+  120382 => 'c',
+  120383 => 'd',
+  120384 => 'e',
+  120385 => 'f',
+  120386 => 'g',
+  120387 => 'h',
+  120388 => 'i',
+  120389 => 'j',
+  120390 => 'k',
+  120391 => 'l',
+  120392 => 'm',
+  120393 => 'n',
+  120394 => 'o',
+  120395 => 'p',
+  120396 => 'q',
+  120397 => 'r',
+  120398 => 's',
+  120399 => 't',
+  120400 => 'u',
+  120401 => 'v',
+  120402 => 'w',
+  120403 => 'x',
+  120404 => 'y',
+  120405 => 'z',
+  120406 => 'a',
+  120407 => 'b',
+  120408 => 'c',
+  120409 => 'd',
+  120410 => 'e',
+  120411 => 'f',
+  120412 => 'g',
+  120413 => 'h',
+  120414 => 'i',
+  120415 => 'j',
+  120416 => 'k',
+  120417 => 'l',
+  120418 => 'm',
+  120419 => 'n',
+  120420 => 'o',
+  120421 => 'p',
+  120422 => 'q',
+  120423 => 'r',
+  120424 => 's',
+  120425 => 't',
+  120426 => 'u',
+  120427 => 'v',
+  120428 => 'w',
+  120429 => 'x',
+  120430 => 'y',
+  120431 => 'z',
+  120432 => 'a',
+  120433 => 'b',
+  120434 => 'c',
+  120435 => 'd',
+  120436 => 'e',
+  120437 => 'f',
+  120438 => 'g',
+  120439 => 'h',
+  120440 => 'i',
+  120441 => 'j',
+  120442 => 'k',
+  120443 => 'l',
+  120444 => 'm',
+  120445 => 'n',
+  120446 => 'o',
+  120447 => 'p',
+  120448 => 'q',
+  120449 => 'r',
+  120450 => 's',
+  120451 => 't',
+  120452 => 'u',
+  120453 => 'v',
+  120454 => 'w',
+  120455 => 'x',
+  120456 => 'y',
+  120457 => 'z',
+  120458 => 'a',
+  120459 => 'b',
+  120460 => 'c',
+  120461 => 'd',
+  120462 => 'e',
+  120463 => 'f',
+  120464 => 'g',
+  120465 => 'h',
+  120466 => 'i',
+  120467 => 'j',
+  120468 => 'k',
+  120469 => 'l',
+  120470 => 'm',
+  120471 => 'n',
+  120472 => 'o',
+  120473 => 'p',
+  120474 => 'q',
+  120475 => 'r',
+  120476 => 's',
+  120477 => 't',
+  120478 => 'u',
+  120479 => 'v',
+  120480 => 'w',
+  120481 => 'x',
+  120482 => 'y',
+  120483 => 'z',
+  120484 => 'ı',
+  120485 => 'ȷ',
+  120488 => 'α',
+  120489 => 'β',
+  120490 => 'γ',
+  120491 => 'δ',
+  120492 => 'ε',
+  120493 => 'ζ',
+  120494 => 'η',
+  120495 => 'θ',
+  120496 => 'ι',
+  120497 => 'κ',
+  120498 => 'λ',
+  120499 => 'μ',
+  120500 => 'ν',
+  120501 => 'ξ',
+  120502 => 'ο',
+  120503 => 'π',
+  120504 => 'ρ',
+  120505 => 'θ',
+  120506 => 'σ',
+  120507 => 'τ',
+  120508 => 'υ',
+  120509 => 'φ',
+  120510 => 'χ',
+  120511 => 'ψ',
+  120512 => 'ω',
+  120513 => '∇',
+  120514 => 'α',
+  120515 => 'β',
+  120516 => 'γ',
+  120517 => 'δ',
+  120518 => 'ε',
+  120519 => 'ζ',
+  120520 => 'η',
+  120521 => 'θ',
+  120522 => 'ι',
+  120523 => 'κ',
+  120524 => 'λ',
+  120525 => 'μ',
+  120526 => 'ν',
+  120527 => 'ξ',
+  120528 => 'ο',
+  120529 => 'π',
+  120530 => 'ρ',
+  120531 => 'σ',
+  120532 => 'σ',
+  120533 => 'τ',
+  120534 => 'υ',
+  120535 => 'φ',
+  120536 => 'χ',
+  120537 => 'ψ',
+  120538 => 'ω',
+  120539 => '∂',
+  120540 => 'ε',
+  120541 => 'θ',
+  120542 => 'κ',
+  120543 => 'φ',
+  120544 => 'ρ',
+  120545 => 'π',
+  120546 => 'α',
+  120547 => 'β',
+  120548 => 'γ',
+  120549 => 'δ',
+  120550 => 'ε',
+  120551 => 'ζ',
+  120552 => 'η',
+  120553 => 'θ',
+  120554 => 'ι',
+  120555 => 'κ',
+  120556 => 'λ',
+  120557 => 'μ',
+  120558 => 'ν',
+  120559 => 'ξ',
+  120560 => 'ο',
+  120561 => 'π',
+  120562 => 'ρ',
+  120563 => 'θ',
+  120564 => 'σ',
+  120565 => 'τ',
+  120566 => 'υ',
+  120567 => 'φ',
+  120568 => 'χ',
+  120569 => 'ψ',
+  120570 => 'ω',
+  120571 => '∇',
+  120572 => 'α',
+  120573 => 'β',
+  120574 => 'γ',
+  120575 => 'δ',
+  120576 => 'ε',
+  120577 => 'ζ',
+  120578 => 'η',
+  120579 => 'θ',
+  120580 => 'ι',
+  120581 => 'κ',
+  120582 => 'λ',
+  120583 => 'μ',
+  120584 => 'ν',
+  120585 => 'ξ',
+  120586 => 'ο',
+  120587 => 'π',
+  120588 => 'ρ',
+  120589 => 'σ',
+  120590 => 'σ',
+  120591 => 'τ',
+  120592 => 'υ',
+  120593 => 'φ',
+  120594 => 'χ',
+  120595 => 'ψ',
+  120596 => 'ω',
+  120597 => '∂',
+  120598 => 'ε',
+  120599 => 'θ',
+  120600 => 'κ',
+  120601 => 'φ',
+  120602 => 'ρ',
+  120603 => 'π',
+  120604 => 'α',
+  120605 => 'β',
+  120606 => 'γ',
+  120607 => 'δ',
+  120608 => 'ε',
+  120609 => 'ζ',
+  120610 => 'η',
+  120611 => 'θ',
+  120612 => 'ι',
+  120613 => 'κ',
+  120614 => 'λ',
+  120615 => 'μ',
+  120616 => 'ν',
+  120617 => 'ξ',
+  120618 => 'ο',
+  120619 => 'π',
+  120620 => 'ρ',
+  120621 => 'θ',
+  120622 => 'σ',
+  120623 => 'τ',
+  120624 => 'υ',
+  120625 => 'φ',
+  120626 => 'χ',
+  120627 => 'ψ',
+  120628 => 'ω',
+  120629 => '∇',
+  120630 => 'α',
+  120631 => 'β',
+  120632 => 'γ',
+  120633 => 'δ',
+  120634 => 'ε',
+  120635 => 'ζ',
+  120636 => 'η',
+  120637 => 'θ',
+  120638 => 'ι',
+  120639 => 'κ',
+  120640 => 'λ',
+  120641 => 'μ',
+  120642 => 'ν',
+  120643 => 'ξ',
+  120644 => 'ο',
+  120645 => 'π',
+  120646 => 'ρ',
+  120647 => 'σ',
+  120648 => 'σ',
+  120649 => 'τ',
+  120650 => 'υ',
+  120651 => 'φ',
+  120652 => 'χ',
+  120653 => 'ψ',
+  120654 => 'ω',
+  120655 => '∂',
+  120656 => 'ε',
+  120657 => 'θ',
+  120658 => 'κ',
+  120659 => 'φ',
+  120660 => 'ρ',
+  120661 => 'π',
+  120662 => 'α',
+  120663 => 'β',
+  120664 => 'γ',
+  120665 => 'δ',
+  120666 => 'ε',
+  120667 => 'ζ',
+  120668 => 'η',
+  120669 => 'θ',
+  120670 => 'ι',
+  120671 => 'κ',
+  120672 => 'λ',
+  120673 => 'μ',
+  120674 => 'ν',
+  120675 => 'ξ',
+  120676 => 'ο',
+  120677 => 'π',
+  120678 => 'ρ',
+  120679 => 'θ',
+  120680 => 'σ',
+  120681 => 'τ',
+  120682 => 'υ',
+  120683 => 'φ',
+  120684 => 'χ',
+  120685 => 'ψ',
+  120686 => 'ω',
+  120687 => '∇',
+  120688 => 'α',
+  120689 => 'β',
+  120690 => 'γ',
+  120691 => 'δ',
+  120692 => 'ε',
+  120693 => 'ζ',
+  120694 => 'η',
+  120695 => 'θ',
+  120696 => 'ι',
+  120697 => 'κ',
+  120698 => 'λ',
+  120699 => 'μ',
+  120700 => 'ν',
+  120701 => 'ξ',
+  120702 => 'ο',
+  120703 => 'π',
+  120704 => 'ρ',
+  120705 => 'σ',
+  120706 => 'σ',
+  120707 => 'τ',
+  120708 => 'υ',
+  120709 => 'φ',
+  120710 => 'χ',
+  120711 => 'ψ',
+  120712 => 'ω',
+  120713 => '∂',
+  120714 => 'ε',
+  120715 => 'θ',
+  120716 => 'κ',
+  120717 => 'φ',
+  120718 => 'ρ',
+  120719 => 'π',
+  120720 => 'α',
+  120721 => 'β',
+  120722 => 'γ',
+  120723 => 'δ',
+  120724 => 'ε',
+  120725 => 'ζ',
+  120726 => 'η',
+  120727 => 'θ',
+  120728 => 'ι',
+  120729 => 'κ',
+  120730 => 'λ',
+  120731 => 'μ',
+  120732 => 'ν',
+  120733 => 'ξ',
+  120734 => 'ο',
+  120735 => 'π',
+  120736 => 'ρ',
+  120737 => 'θ',
+  120738 => 'σ',
+  120739 => 'τ',
+  120740 => 'υ',
+  120741 => 'φ',
+  120742 => 'χ',
+  120743 => 'ψ',
+  120744 => 'ω',
+  120745 => '∇',
+  120746 => 'α',
+  120747 => 'β',
+  120748 => 'γ',
+  120749 => 'δ',
+  120750 => 'ε',
+  120751 => 'ζ',
+  120752 => 'η',
+  120753 => 'θ',
+  120754 => 'ι',
+  120755 => 'κ',
+  120756 => 'λ',
+  120757 => 'μ',
+  120758 => 'ν',
+  120759 => 'ξ',
+  120760 => 'ο',
+  120761 => 'π',
+  120762 => 'ρ',
+  120763 => 'σ',
+  120764 => 'σ',
+  120765 => 'τ',
+  120766 => 'υ',
+  120767 => 'φ',
+  120768 => 'χ',
+  120769 => 'ψ',
+  120770 => 'ω',
+  120771 => '∂',
+  120772 => 'ε',
+  120773 => 'θ',
+  120774 => 'κ',
+  120775 => 'φ',
+  120776 => 'ρ',
+  120777 => 'π',
+  120778 => 'ϝ',
+  120779 => 'ϝ',
+  120782 => '0',
+  120783 => '1',
+  120784 => '2',
+  120785 => '3',
+  120786 => '4',
+  120787 => '5',
+  120788 => '6',
+  120789 => '7',
+  120790 => '8',
+  120791 => '9',
+  120792 => '0',
+  120793 => '1',
+  120794 => '2',
+  120795 => '3',
+  120796 => '4',
+  120797 => '5',
+  120798 => '6',
+  120799 => '7',
+  120800 => '8',
+  120801 => '9',
+  120802 => '0',
+  120803 => '1',
+  120804 => '2',
+  120805 => '3',
+  120806 => '4',
+  120807 => '5',
+  120808 => '6',
+  120809 => '7',
+  120810 => '8',
+  120811 => '9',
+  120812 => '0',
+  120813 => '1',
+  120814 => '2',
+  120815 => '3',
+  120816 => '4',
+  120817 => '5',
+  120818 => '6',
+  120819 => '7',
+  120820 => '8',
+  120821 => '9',
+  120822 => '0',
+  120823 => '1',
+  120824 => '2',
+  120825 => '3',
+  120826 => '4',
+  120827 => '5',
+  120828 => '6',
+  120829 => '7',
+  120830 => '8',
+  120831 => '9',
+  125184 => '𞤢',
+  125185 => '𞤣',
+  125186 => '𞤤',
+  125187 => '𞤥',
+  125188 => '𞤦',
+  125189 => '𞤧',
+  125190 => '𞤨',
+  125191 => '𞤩',
+  125192 => '𞤪',
+  125193 => '𞤫',
+  125194 => '𞤬',
+  125195 => '𞤭',
+  125196 => '𞤮',
+  125197 => '𞤯',
+  125198 => '𞤰',
+  125199 => '𞤱',
+  125200 => '𞤲',
+  125201 => '𞤳',
+  125202 => '𞤴',
+  125203 => '𞤵',
+  125204 => '𞤶',
+  125205 => '𞤷',
+  125206 => '𞤸',
+  125207 => '𞤹',
+  125208 => '𞤺',
+  125209 => '𞤻',
+  125210 => '𞤼',
+  125211 => '𞤽',
+  125212 => '𞤾',
+  125213 => '𞤿',
+  125214 => '𞥀',
+  125215 => '𞥁',
+  125216 => '𞥂',
+  125217 => '𞥃',
+  126464 => 'ا',
+  126465 => 'ب',
+  126466 => 'ج',
+  126467 => 'د',
+  126469 => 'و',
+  126470 => 'ز',
+  126471 => 'ح',
+  126472 => 'ط',
+  126473 => 'ي',
+  126474 => 'ك',
+  126475 => 'ل',
+  126476 => 'م',
+  126477 => 'ن',
+  126478 => 'س',
+  126479 => 'ع',
+  126480 => 'ف',
+  126481 => 'ص',
+  126482 => 'ق',
+  126483 => 'ر',
+  126484 => 'ش',
+  126485 => 'ت',
+  126486 => 'ث',
+  126487 => 'خ',
+  126488 => 'ذ',
+  126489 => 'ض',
+  126490 => 'ظ',
+  126491 => 'غ',
+  126492 => 'ٮ',
+  126493 => 'ں',
+  126494 => 'ڡ',
+  126495 => 'ٯ',
+  126497 => 'ب',
+  126498 => 'ج',
+  126500 => 'ه',
+  126503 => 'ح',
+  126505 => 'ي',
+  126506 => 'ك',
+  126507 => 'ل',
+  126508 => 'م',
+  126509 => 'ن',
+  126510 => 'س',
+  126511 => 'ع',
+  126512 => 'ف',
+  126513 => 'ص',
+  126514 => 'ق',
+  126516 => 'ش',
+  126517 => 'ت',
+  126518 => 'ث',
+  126519 => 'خ',
+  126521 => 'ض',
+  126523 => 'غ',
+  126530 => 'ج',
+  126535 => 'ح',
+  126537 => 'ي',
+  126539 => 'ل',
+  126541 => 'ن',
+  126542 => 'س',
+  126543 => 'ع',
+  126545 => 'ص',
+  126546 => 'ق',
+  126548 => 'ش',
+  126551 => 'خ',
+  126553 => 'ض',
+  126555 => 'غ',
+  126557 => 'ں',
+  126559 => 'ٯ',
+  126561 => 'ب',
+  126562 => 'ج',
+  126564 => 'ه',
+  126567 => 'ح',
+  126568 => 'ط',
+  126569 => 'ي',
+  126570 => 'ك',
+  126572 => 'م',
+  126573 => 'ن',
+  126574 => 'س',
+  126575 => 'ع',
+  126576 => 'ف',
+  126577 => 'ص',
+  126578 => 'ق',
+  126580 => 'ش',
+  126581 => 'ت',
+  126582 => 'ث',
+  126583 => 'خ',
+  126585 => 'ض',
+  126586 => 'ظ',
+  126587 => 'غ',
+  126588 => 'ٮ',
+  126590 => 'ڡ',
+  126592 => 'ا',
+  126593 => 'ب',
+  126594 => 'ج',
+  126595 => 'د',
+  126596 => 'ه',
+  126597 => 'و',
+  126598 => 'ز',
+  126599 => 'ح',
+  126600 => 'ط',
+  126601 => 'ي',
+  126603 => 'ل',
+  126604 => 'م',
+  126605 => 'ن',
+  126606 => 'س',
+  126607 => 'ع',
+  126608 => 'ف',
+  126609 => 'ص',
+  126610 => 'ق',
+  126611 => 'ر',
+  126612 => 'ش',
+  126613 => 'ت',
+  126614 => 'ث',
+  126615 => 'خ',
+  126616 => 'ذ',
+  126617 => 'ض',
+  126618 => 'ظ',
+  126619 => 'غ',
+  126625 => 'ب',
+  126626 => 'ج',
+  126627 => 'د',
+  126629 => 'و',
+  126630 => 'ز',
+  126631 => 'ح',
+  126632 => 'ط',
+  126633 => 'ي',
+  126635 => 'ل',
+  126636 => 'م',
+  126637 => 'ن',
+  126638 => 'س',
+  126639 => 'ع',
+  126640 => 'ف',
+  126641 => 'ص',
+  126642 => 'ق',
+  126643 => 'ر',
+  126644 => 'ش',
+  126645 => 'ت',
+  126646 => 'ث',
+  126647 => 'خ',
+  126648 => 'ذ',
+  126649 => 'ض',
+  126650 => 'ظ',
+  126651 => 'غ',
+  127274 => '〔s〕',
+  127275 => 'c',
+  127276 => 'r',
+  127277 => 'cd',
+  127278 => 'wz',
+  127280 => 'a',
+  127281 => 'b',
+  127282 => 'c',
+  127283 => 'd',
+  127284 => 'e',
+  127285 => 'f',
+  127286 => 'g',
+  127287 => 'h',
+  127288 => 'i',
+  127289 => 'j',
+  127290 => 'k',
+  127291 => 'l',
+  127292 => 'm',
+  127293 => 'n',
+  127294 => 'o',
+  127295 => 'p',
+  127296 => 'q',
+  127297 => 'r',
+  127298 => 's',
+  127299 => 't',
+  127300 => 'u',
+  127301 => 'v',
+  127302 => 'w',
+  127303 => 'x',
+  127304 => 'y',
+  127305 => 'z',
+  127306 => 'hv',
+  127307 => 'mv',
+  127308 => 'sd',
+  127309 => 'ss',
+  127310 => 'ppv',
+  127311 => 'wc',
+  127338 => 'mc',
+  127339 => 'md',
+  127340 => 'mr',
+  127376 => 'dj',
+  127488 => 'ほか',
+  127489 => 'ココ',
+  127490 => 'サ',
+  127504 => '手',
+  127505 => '字',
+  127506 => '双',
+  127507 => 'デ',
+  127508 => '二',
+  127509 => '多',
+  127510 => '解',
+  127511 => '天',
+  127512 => '交',
+  127513 => '映',
+  127514 => '無',
+  127515 => '料',
+  127516 => '前',
+  127517 => '後',
+  127518 => '再',
+  127519 => '新',
+  127520 => '初',
+  127521 => '終',
+  127522 => '生',
+  127523 => '販',
+  127524 => '声',
+  127525 => '吹',
+  127526 => '演',
+  127527 => '投',
+  127528 => '捕',
+  127529 => '一',
+  127530 => '三',
+  127531 => '遊',
+  127532 => '左',
+  127533 => '中',
+  127534 => '右',
+  127535 => '指',
+  127536 => '走',
+  127537 => '打',
+  127538 => '禁',
+  127539 => '空',
+  127540 => '合',
+  127541 => '満',
+  127542 => '有',
+  127543 => '月',
+  127544 => '申',
+  127545 => '割',
+  127546 => '営',
+  127547 => '配',
+  127552 => '〔本〕',
+  127553 => '〔三〕',
+  127554 => '〔二〕',
+  127555 => '〔安〕',
+  127556 => '〔点〕',
+  127557 => '〔打〕',
+  127558 => '〔盗〕',
+  127559 => '〔勝〕',
+  127560 => '〔敗〕',
+  127568 => '得',
+  127569 => '可',
+  130032 => '0',
+  130033 => '1',
+  130034 => '2',
+  130035 => '3',
+  130036 => '4',
+  130037 => '5',
+  130038 => '6',
+  130039 => '7',
+  130040 => '8',
+  130041 => '9',
+  194560 => '丽',
+  194561 => '丸',
+  194562 => '乁',
+  194563 => '𠄢',
+  194564 => '你',
+  194565 => '侮',
+  194566 => '侻',
+  194567 => '倂',
+  194568 => '偺',
+  194569 => '備',
+  194570 => '僧',
+  194571 => '像',
+  194572 => '㒞',
+  194573 => '𠘺',
+  194574 => '免',
+  194575 => '兔',
+  194576 => '兤',
+  194577 => '具',
+  194578 => '𠔜',
+  194579 => '㒹',
+  194580 => '內',
+  194581 => '再',
+  194582 => '𠕋',
+  194583 => '冗',
+  194584 => '冤',
+  194585 => '仌',
+  194586 => '冬',
+  194587 => '况',
+  194588 => '𩇟',
+  194589 => '凵',
+  194590 => '刃',
+  194591 => '㓟',
+  194592 => '刻',
+  194593 => '剆',
+  194594 => '割',
+  194595 => '剷',
+  194596 => '㔕',
+  194597 => '勇',
+  194598 => '勉',
+  194599 => '勤',
+  194600 => '勺',
+  194601 => '包',
+  194602 => '匆',
+  194603 => '北',
+  194604 => '卉',
+  194605 => '卑',
+  194606 => '博',
+  194607 => '即',
+  194608 => '卽',
+  194609 => '卿',
+  194610 => '卿',
+  194611 => '卿',
+  194612 => '𠨬',
+  194613 => '灰',
+  194614 => '及',
+  194615 => '叟',
+  194616 => '𠭣',
+  194617 => '叫',
+  194618 => '叱',
+  194619 => '吆',
+  194620 => '咞',
+  194621 => '吸',
+  194622 => '呈',
+  194623 => '周',
+  194624 => '咢',
+  194625 => '哶',
+  194626 => '唐',
+  194627 => '啓',
+  194628 => '啣',
+  194629 => '善',
+  194630 => '善',
+  194631 => '喙',
+  194632 => '喫',
+  194633 => '喳',
+  194634 => '嗂',
+  194635 => '圖',
+  194636 => '嘆',
+  194637 => '圗',
+  194638 => '噑',
+  194639 => '噴',
+  194640 => '切',
+  194641 => '壮',
+  194642 => '城',
+  194643 => '埴',
+  194644 => '堍',
+  194645 => '型',
+  194646 => '堲',
+  194647 => '報',
+  194648 => '墬',
+  194649 => '𡓤',
+  194650 => '売',
+  194651 => '壷',
+  194652 => '夆',
+  194653 => '多',
+  194654 => '夢',
+  194655 => '奢',
+  194656 => '𡚨',
+  194657 => '𡛪',
+  194658 => '姬',
+  194659 => '娛',
+  194660 => '娧',
+  194661 => '姘',
+  194662 => '婦',
+  194663 => '㛮',
+  194665 => '嬈',
+  194666 => '嬾',
+  194667 => '嬾',
+  194668 => '𡧈',
+  194669 => '寃',
+  194670 => '寘',
+  194671 => '寧',
+  194672 => '寳',
+  194673 => '𡬘',
+  194674 => '寿',
+  194675 => '将',
+  194677 => '尢',
+  194678 => '㞁',
+  194679 => '屠',
+  194680 => '屮',
+  194681 => '峀',
+  194682 => '岍',
+  194683 => '𡷤',
+  194684 => '嵃',
+  194685 => '𡷦',
+  194686 => '嵮',
+  194687 => '嵫',
+  194688 => '嵼',
+  194689 => '巡',
+  194690 => '巢',
+  194691 => '㠯',
+  194692 => '巽',
+  194693 => '帨',
+  194694 => '帽',
+  194695 => '幩',
+  194696 => '㡢',
+  194697 => '𢆃',
+  194698 => '㡼',
+  194699 => '庰',
+  194700 => '庳',
+  194701 => '庶',
+  194702 => '廊',
+  194703 => '𪎒',
+  194704 => '廾',
+  194705 => '𢌱',
+  194706 => '𢌱',
+  194707 => '舁',
+  194708 => '弢',
+  194709 => '弢',
+  194710 => '㣇',
+  194711 => '𣊸',
+  194712 => '𦇚',
+  194713 => '形',
+  194714 => '彫',
+  194715 => '㣣',
+  194716 => '徚',
+  194717 => '忍',
+  194718 => '志',
+  194719 => '忹',
+  194720 => '悁',
+  194721 => '㤺',
+  194722 => '㤜',
+  194723 => '悔',
+  194724 => '𢛔',
+  194725 => '惇',
+  194726 => '慈',
+  194727 => '慌',
+  194728 => '慎',
+  194729 => '慌',
+  194730 => '慺',
+  194731 => '憎',
+  194732 => '憲',
+  194733 => '憤',
+  194734 => '憯',
+  194735 => '懞',
+  194736 => '懲',
+  194737 => '懶',
+  194738 => '成',
+  194739 => '戛',
+  194740 => '扝',
+  194741 => '抱',
+  194742 => '拔',
+  194743 => '捐',
+  194744 => '𢬌',
+  194745 => '挽',
+  194746 => '拼',
+  194747 => '捨',
+  194748 => '掃',
+  194749 => '揤',
+  194750 => '𢯱',
+  194751 => '搢',
+  194752 => '揅',
+  194753 => '掩',
+  194754 => '㨮',
+  194755 => '摩',
+  194756 => '摾',
+  194757 => '撝',
+  194758 => '摷',
+  194759 => '㩬',
+  194760 => '敏',
+  194761 => '敬',
+  194762 => '𣀊',
+  194763 => '旣',
+  194764 => '書',
+  194765 => '晉',
+  194766 => '㬙',
+  194767 => '暑',
+  194768 => '㬈',
+  194769 => '㫤',
+  194770 => '冒',
+  194771 => '冕',
+  194772 => '最',
+  194773 => '暜',
+  194774 => '肭',
+  194775 => '䏙',
+  194776 => '朗',
+  194777 => '望',
+  194778 => '朡',
+  194779 => '杞',
+  194780 => '杓',
+  194781 => '𣏃',
+  194782 => '㭉',
+  194783 => '柺',
+  194784 => '枅',
+  194785 => '桒',
+  194786 => '梅',
+  194787 => '𣑭',
+  194788 => '梎',
+  194789 => '栟',
+  194790 => '椔',
+  194791 => '㮝',
+  194792 => '楂',
+  194793 => '榣',
+  194794 => '槪',
+  194795 => '檨',
+  194796 => '𣚣',
+  194797 => '櫛',
+  194798 => '㰘',
+  194799 => '次',
+  194800 => '𣢧',
+  194801 => '歔',
+  194802 => '㱎',
+  194803 => '歲',
+  194804 => '殟',
+  194805 => '殺',
+  194806 => '殻',
+  194807 => '𣪍',
+  194808 => '𡴋',
+  194809 => '𣫺',
+  194810 => '汎',
+  194811 => '𣲼',
+  194812 => '沿',
+  194813 => '泍',
+  194814 => '汧',
+  194815 => '洖',
+  194816 => '派',
+  194817 => '海',
+  194818 => '流',
+  194819 => '浩',
+  194820 => '浸',
+  194821 => '涅',
+  194822 => '𣴞',
+  194823 => '洴',
+  194824 => '港',
+  194825 => '湮',
+  194826 => '㴳',
+  194827 => '滋',
+  194828 => '滇',
+  194829 => '𣻑',
+  194830 => '淹',
+  194831 => '潮',
+  194832 => '𣽞',
+  194833 => '𣾎',
+  194834 => '濆',
+  194835 => '瀹',
+  194836 => '瀞',
+  194837 => '瀛',
+  194838 => '㶖',
+  194839 => '灊',
+  194840 => '災',
+  194841 => '灷',
+  194842 => '炭',
+  194843 => '𠔥',
+  194844 => '煅',
+  194845 => '𤉣',
+  194846 => '熜',
+  194848 => '爨',
+  194849 => '爵',
+  194850 => '牐',
+  194851 => '𤘈',
+  194852 => '犀',
+  194853 => '犕',
+  194854 => '𤜵',
+  194855 => '𤠔',
+  194856 => '獺',
+  194857 => '王',
+  194858 => '㺬',
+  194859 => '玥',
+  194860 => '㺸',
+  194861 => '㺸',
+  194862 => '瑇',
+  194863 => '瑜',
+  194864 => '瑱',
+  194865 => '璅',
+  194866 => '瓊',
+  194867 => '㼛',
+  194868 => '甤',
+  194869 => '𤰶',
+  194870 => '甾',
+  194871 => '𤲒',
+  194872 => '異',
+  194873 => '𢆟',
+  194874 => '瘐',
+  194875 => '𤾡',
+  194876 => '𤾸',
+  194877 => '𥁄',
+  194878 => '㿼',
+  194879 => '䀈',
+  194880 => '直',
+  194881 => '𥃳',
+  194882 => '𥃲',
+  194883 => '𥄙',
+  194884 => '𥄳',
+  194885 => '眞',
+  194886 => '真',
+  194887 => '真',
+  194888 => '睊',
+  194889 => '䀹',
+  194890 => '瞋',
+  194891 => '䁆',
+  194892 => '䂖',
+  194893 => '𥐝',
+  194894 => '硎',
+  194895 => '碌',
+  194896 => '磌',
+  194897 => '䃣',
+  194898 => '𥘦',
+  194899 => '祖',
+  194900 => '𥚚',
+  194901 => '𥛅',
+  194902 => '福',
+  194903 => '秫',
+  194904 => '䄯',
+  194905 => '穀',
+  194906 => '穊',
+  194907 => '穏',
+  194908 => '𥥼',
+  194909 => '𥪧',
+  194910 => '𥪧',
+  194912 => '䈂',
+  194913 => '𥮫',
+  194914 => '篆',
+  194915 => '築',
+  194916 => '䈧',
+  194917 => '𥲀',
+  194918 => '糒',
+  194919 => '䊠',
+  194920 => '糨',
+  194921 => '糣',
+  194922 => '紀',
+  194923 => '𥾆',
+  194924 => '絣',
+  194925 => '䌁',
+  194926 => '緇',
+  194927 => '縂',
+  194928 => '繅',
+  194929 => '䌴',
+  194930 => '𦈨',
+  194931 => '𦉇',
+  194932 => '䍙',
+  194933 => '𦋙',
+  194934 => '罺',
+  194935 => '𦌾',
+  194936 => '羕',
+  194937 => '翺',
+  194938 => '者',
+  194939 => '𦓚',
+  194940 => '𦔣',
+  194941 => '聠',
+  194942 => '𦖨',
+  194943 => '聰',
+  194944 => '𣍟',
+  194945 => '䏕',
+  194946 => '育',
+  194947 => '脃',
+  194948 => '䐋',
+  194949 => '脾',
+  194950 => '媵',
+  194951 => '𦞧',
+  194952 => '𦞵',
+  194953 => '𣎓',
+  194954 => '𣎜',
+  194955 => '舁',
+  194956 => '舄',
+  194957 => '辞',
+  194958 => '䑫',
+  194959 => '芑',
+  194960 => '芋',
+  194961 => '芝',
+  194962 => '劳',
+  194963 => '花',
+  194964 => '芳',
+  194965 => '芽',
+  194966 => '苦',
+  194967 => '𦬼',
+  194968 => '若',
+  194969 => '茝',
+  194970 => '荣',
+  194971 => '莭',
+  194972 => '茣',
+  194973 => '莽',
+  194974 => '菧',
+  194975 => '著',
+  194976 => '荓',
+  194977 => '菊',
+  194978 => '菌',
+  194979 => '菜',
+  194980 => '𦰶',
+  194981 => '𦵫',
+  194982 => '𦳕',
+  194983 => '䔫',
+  194984 => '蓱',
+  194985 => '蓳',
+  194986 => '蔖',
+  194987 => '𧏊',
+  194988 => '蕤',
+  194989 => '𦼬',
+  194990 => '䕝',
+  194991 => '䕡',
+  194992 => '𦾱',
+  194993 => '𧃒',
+  194994 => '䕫',
+  194995 => '虐',
+  194996 => '虜',
+  194997 => '虧',
+  194998 => '虩',
+  194999 => '蚩',
+  195000 => '蚈',
+  195001 => '蜎',
+  195002 => '蛢',
+  195003 => '蝹',
+  195004 => '蜨',
+  195005 => '蝫',
+  195006 => '螆',
+  195008 => '蟡',
+  195009 => '蠁',
+  195010 => '䗹',
+  195011 => '衠',
+  195012 => '衣',
+  195013 => '𧙧',
+  195014 => '裗',
+  195015 => '裞',
+  195016 => '䘵',
+  195017 => '裺',
+  195018 => '㒻',
+  195019 => '𧢮',
+  195020 => '𧥦',
+  195021 => '䚾',
+  195022 => '䛇',
+  195023 => '誠',
+  195024 => '諭',
+  195025 => '變',
+  195026 => '豕',
+  195027 => '𧲨',
+  195028 => '貫',
+  195029 => '賁',
+  195030 => '贛',
+  195031 => '起',
+  195032 => '𧼯',
+  195033 => '𠠄',
+  195034 => '跋',
+  195035 => '趼',
+  195036 => '跰',
+  195037 => '𠣞',
+  195038 => '軔',
+  195039 => '輸',
+  195040 => '𨗒',
+  195041 => '𨗭',
+  195042 => '邔',
+  195043 => '郱',
+  195044 => '鄑',
+  195045 => '𨜮',
+  195046 => '鄛',
+  195047 => '鈸',
+  195048 => '鋗',
+  195049 => '鋘',
+  195050 => '鉼',
+  195051 => '鏹',
+  195052 => '鐕',
+  195053 => '𨯺',
+  195054 => '開',
+  195055 => '䦕',
+  195056 => '閷',
+  195057 => '𨵷',
+  195058 => '䧦',
+  195059 => '雃',
+  195060 => '嶲',
+  195061 => '霣',
+  195062 => '𩅅',
+  195063 => '𩈚',
+  195064 => '䩮',
+  195065 => '䩶',
+  195066 => '韠',
+  195067 => '𩐊',
+  195068 => '䪲',
+  195069 => '𩒖',
+  195070 => '頋',
+  195071 => '頋',
+  195072 => '頩',
+  195073 => '𩖶',
+  195074 => '飢',
+  195075 => '䬳',
+  195076 => '餩',
+  195077 => '馧',
+  195078 => '駂',
+  195079 => '駾',
+  195080 => '䯎',
+  195081 => '𩬰',
+  195082 => '鬒',
+  195083 => '鱀',
+  195084 => '鳽',
+  195085 => '䳎',
+  195086 => '䳭',
+  195087 => '鵧',
+  195088 => '𪃎',
+  195089 => '䳸',
+  195090 => '𪄅',
+  195091 => '𪈎',
+  195092 => '𪊑',
+  195093 => '麻',
+  195094 => '䵖',
+  195095 => '黹',
+  195096 => '黾',
+  195097 => '鼅',
+  195098 => '鼏',
+  195099 => '鼖',
+  195100 => '鼻',
+  195101 => '𪘀',
+);
diff --git a/vendor/symfony/polyfill-intl-idn/Resources/unidata/virama.php b/vendor/symfony/polyfill-intl-idn/Resources/unidata/virama.php
new file mode 100644
index 000000000..1958e37ed
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-idn/Resources/unidata/virama.php
@@ -0,0 +1,65 @@
+ 9,
+  2509 => 9,
+  2637 => 9,
+  2765 => 9,
+  2893 => 9,
+  3021 => 9,
+  3149 => 9,
+  3277 => 9,
+  3387 => 9,
+  3388 => 9,
+  3405 => 9,
+  3530 => 9,
+  3642 => 9,
+  3770 => 9,
+  3972 => 9,
+  4153 => 9,
+  4154 => 9,
+  5908 => 9,
+  5940 => 9,
+  6098 => 9,
+  6752 => 9,
+  6980 => 9,
+  7082 => 9,
+  7083 => 9,
+  7154 => 9,
+  7155 => 9,
+  11647 => 9,
+  43014 => 9,
+  43052 => 9,
+  43204 => 9,
+  43347 => 9,
+  43456 => 9,
+  43766 => 9,
+  44013 => 9,
+  68159 => 9,
+  69702 => 9,
+  69759 => 9,
+  69817 => 9,
+  69939 => 9,
+  69940 => 9,
+  70080 => 9,
+  70197 => 9,
+  70378 => 9,
+  70477 => 9,
+  70722 => 9,
+  70850 => 9,
+  71103 => 9,
+  71231 => 9,
+  71350 => 9,
+  71467 => 9,
+  71737 => 9,
+  71997 => 9,
+  71998 => 9,
+  72160 => 9,
+  72244 => 9,
+  72263 => 9,
+  72345 => 9,
+  72767 => 9,
+  73028 => 9,
+  73029 => 9,
+  73111 => 9,
+);
diff --git a/vendor/symfony/polyfill-intl-idn/bootstrap.php b/vendor/symfony/polyfill-intl-idn/bootstrap.php
index f02d5de73..57c78356c 100644
--- a/vendor/symfony/polyfill-intl-idn/bootstrap.php
+++ b/vendor/symfony/polyfill-intl-idn/bootstrap.php
@@ -15,6 +15,10 @@
     return;
 }
 
+if (\PHP_VERSION_ID >= 80000) {
+    return require __DIR__.'/bootstrap80.php';
+}
+
 if (!defined('U_IDNA_PROHIBITED_ERROR')) {
     define('U_IDNA_PROHIBITED_ERROR', 66560);
 }
@@ -124,18 +128,18 @@
     define('IDNA_ERROR_CONTEXTJ', 4096);
 }
 
-if (PHP_VERSION_ID < 70400) {
+if (\PHP_VERSION_ID < 70400) {
     if (!function_exists('idn_to_ascii')) {
-        function idn_to_ascii($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_2003, &$idna_info = array()) { return p\Idn::idn_to_ascii($domain, $options, $variant, $idna_info); }
+        function idn_to_ascii($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_2003, &$idna_info = null) { return p\Idn::idn_to_ascii($domain, $flags, $variant, $idna_info); }
     }
     if (!function_exists('idn_to_utf8')) {
-        function idn_to_utf8($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_2003, &$idna_info = array()) { return p\Idn::idn_to_utf8($domain, $options, $variant, $idna_info); }
+        function idn_to_utf8($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_2003, &$idna_info = null) { return p\Idn::idn_to_utf8($domain, $flags, $variant, $idna_info); }
     }
 } else {
     if (!function_exists('idn_to_ascii')) {
-        function idn_to_ascii($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = array()) { return p\Idn::idn_to_ascii($domain, $options, $variant, $idna_info); }
+        function idn_to_ascii($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_UTS46, &$idna_info = null) { return p\Idn::idn_to_ascii($domain, $flags, $variant, $idna_info); }
     }
     if (!function_exists('idn_to_utf8')) {
-        function idn_to_utf8($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = array()) { return p\Idn::idn_to_utf8($domain, $options, $variant, $idna_info); }
+        function idn_to_utf8($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_UTS46, &$idna_info = null) { return p\Idn::idn_to_utf8($domain, $flags, $variant, $idna_info); }
     }
 }
diff --git a/vendor/symfony/polyfill-intl-idn/bootstrap80.php b/vendor/symfony/polyfill-intl-idn/bootstrap80.php
new file mode 100644
index 000000000..896538697
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-idn/bootstrap80.php
@@ -0,0 +1,128 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Intl\Idn as p;
+
+if (!defined('U_IDNA_PROHIBITED_ERROR')) {
+    define('U_IDNA_PROHIBITED_ERROR', 66560);
+}
+if (!defined('U_IDNA_ERROR_START')) {
+    define('U_IDNA_ERROR_START', 66560);
+}
+if (!defined('U_IDNA_UNASSIGNED_ERROR')) {
+    define('U_IDNA_UNASSIGNED_ERROR', 66561);
+}
+if (!defined('U_IDNA_CHECK_BIDI_ERROR')) {
+    define('U_IDNA_CHECK_BIDI_ERROR', 66562);
+}
+if (!defined('U_IDNA_STD3_ASCII_RULES_ERROR')) {
+    define('U_IDNA_STD3_ASCII_RULES_ERROR', 66563);
+}
+if (!defined('U_IDNA_ACE_PREFIX_ERROR')) {
+    define('U_IDNA_ACE_PREFIX_ERROR', 66564);
+}
+if (!defined('U_IDNA_VERIFICATION_ERROR')) {
+    define('U_IDNA_VERIFICATION_ERROR', 66565);
+}
+if (!defined('U_IDNA_LABEL_TOO_LONG_ERROR')) {
+    define('U_IDNA_LABEL_TOO_LONG_ERROR', 66566);
+}
+if (!defined('U_IDNA_ZERO_LENGTH_LABEL_ERROR')) {
+    define('U_IDNA_ZERO_LENGTH_LABEL_ERROR', 66567);
+}
+if (!defined('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR')) {
+    define('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR', 66568);
+}
+if (!defined('U_IDNA_ERROR_LIMIT')) {
+    define('U_IDNA_ERROR_LIMIT', 66569);
+}
+if (!defined('U_STRINGPREP_PROHIBITED_ERROR')) {
+    define('U_STRINGPREP_PROHIBITED_ERROR', 66560);
+}
+if (!defined('U_STRINGPREP_UNASSIGNED_ERROR')) {
+    define('U_STRINGPREP_UNASSIGNED_ERROR', 66561);
+}
+if (!defined('U_STRINGPREP_CHECK_BIDI_ERROR')) {
+    define('U_STRINGPREP_CHECK_BIDI_ERROR', 66562);
+}
+if (!defined('IDNA_DEFAULT')) {
+    define('IDNA_DEFAULT', 0);
+}
+if (!defined('IDNA_ALLOW_UNASSIGNED')) {
+    define('IDNA_ALLOW_UNASSIGNED', 1);
+}
+if (!defined('IDNA_USE_STD3_RULES')) {
+    define('IDNA_USE_STD3_RULES', 2);
+}
+if (!defined('IDNA_CHECK_BIDI')) {
+    define('IDNA_CHECK_BIDI', 4);
+}
+if (!defined('IDNA_CHECK_CONTEXTJ')) {
+    define('IDNA_CHECK_CONTEXTJ', 8);
+}
+if (!defined('IDNA_NONTRANSITIONAL_TO_ASCII')) {
+    define('IDNA_NONTRANSITIONAL_TO_ASCII', 16);
+}
+if (!defined('IDNA_NONTRANSITIONAL_TO_UNICODE')) {
+    define('IDNA_NONTRANSITIONAL_TO_UNICODE', 32);
+}
+if (!defined('INTL_IDNA_VARIANT_2003')) {
+    define('INTL_IDNA_VARIANT_2003', 0);
+}
+if (!defined('INTL_IDNA_VARIANT_UTS46')) {
+    define('INTL_IDNA_VARIANT_UTS46', 1);
+}
+if (!defined('IDNA_ERROR_EMPTY_LABEL')) {
+    define('IDNA_ERROR_EMPTY_LABEL', 1);
+}
+if (!defined('IDNA_ERROR_LABEL_TOO_LONG')) {
+    define('IDNA_ERROR_LABEL_TOO_LONG', 2);
+}
+if (!defined('IDNA_ERROR_DOMAIN_NAME_TOO_LONG')) {
+    define('IDNA_ERROR_DOMAIN_NAME_TOO_LONG', 4);
+}
+if (!defined('IDNA_ERROR_LEADING_HYPHEN')) {
+    define('IDNA_ERROR_LEADING_HYPHEN', 8);
+}
+if (!defined('IDNA_ERROR_TRAILING_HYPHEN')) {
+    define('IDNA_ERROR_TRAILING_HYPHEN', 16);
+}
+if (!defined('IDNA_ERROR_HYPHEN_3_4')) {
+    define('IDNA_ERROR_HYPHEN_3_4', 32);
+}
+if (!defined('IDNA_ERROR_LEADING_COMBINING_MARK')) {
+    define('IDNA_ERROR_LEADING_COMBINING_MARK', 64);
+}
+if (!defined('IDNA_ERROR_DISALLOWED')) {
+    define('IDNA_ERROR_DISALLOWED', 128);
+}
+if (!defined('IDNA_ERROR_PUNYCODE')) {
+    define('IDNA_ERROR_PUNYCODE', 256);
+}
+if (!defined('IDNA_ERROR_LABEL_HAS_DOT')) {
+    define('IDNA_ERROR_LABEL_HAS_DOT', 512);
+}
+if (!defined('IDNA_ERROR_INVALID_ACE_LABEL')) {
+    define('IDNA_ERROR_INVALID_ACE_LABEL', 1024);
+}
+if (!defined('IDNA_ERROR_BIDI')) {
+    define('IDNA_ERROR_BIDI', 2048);
+}
+if (!defined('IDNA_ERROR_CONTEXTJ')) {
+    define('IDNA_ERROR_CONTEXTJ', 4096);
+}
+
+if (!function_exists('idn_to_ascii')) {
+    function idn_to_ascii(?string $domain, ?int $flags = 0, ?int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_ascii((string) $domain, (int) $flags, (int) $variant, $idna_info); }
+}
+if (!function_exists('idn_to_utf8')) {
+    function idn_to_utf8(?string $domain, ?int $flags = 0, ?int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_utf8((string) $domain, (int) $flags, (int) $variant, $idna_info); }
+}
diff --git a/vendor/symfony/polyfill-intl-idn/composer.json b/vendor/symfony/polyfill-intl-idn/composer.json
index 1c64accf6..450d1e7b2 100644
--- a/vendor/symfony/polyfill-intl-idn/composer.json
+++ b/vendor/symfony/polyfill-intl-idn/composer.json
@@ -10,14 +10,18 @@
             "name": "Laurent Bassin",
             "email": "laurent@bassin.info"
         },
+        {
+            "name": "Trevor Rowbotham",
+            "email": "trevor.rowbotham@pm.me"
+        },
         {
             "name": "Symfony Community",
             "homepage": "https://symfony.com/contributors"
         }
     ],
     "require": {
-        "php": ">=5.3.3",
-        "symfony/polyfill-mbstring": "^1.3",
+        "php": ">=7.1",
+        "symfony/polyfill-intl-normalizer": "^1.10",
         "symfony/polyfill-php72": "^1.10"
     },
     "autoload": {
@@ -30,7 +34,7 @@
     "minimum-stability": "dev",
     "extra": {
         "branch-alias": {
-            "dev-master": "1.17-dev"
+            "dev-main": "1.22-dev"
         },
         "thanks": {
             "name": "symfony/polyfill",
diff --git a/vendor/symfony/polyfill-mbstring/LICENSE b/vendor/symfony/polyfill-intl-normalizer/LICENSE
similarity index 100%
rename from vendor/symfony/polyfill-mbstring/LICENSE
rename to vendor/symfony/polyfill-intl-normalizer/LICENSE
diff --git a/vendor/symfony/polyfill-intl-normalizer/Normalizer.php b/vendor/symfony/polyfill-intl-normalizer/Normalizer.php
new file mode 100644
index 000000000..4443c2322
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-normalizer/Normalizer.php
@@ -0,0 +1,310 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Polyfill\Intl\Normalizer;
+
+/**
+ * Normalizer is a PHP fallback implementation of the Normalizer class provided by the intl extension.
+ *
+ * It has been validated with Unicode 6.3 Normalization Conformance Test.
+ * See http://www.unicode.org/reports/tr15/ for detailed info about Unicode normalizations.
+ *
+ * @author Nicolas Grekas 
+ *
+ * @internal
+ */
+class Normalizer
+{
+    public const FORM_D = \Normalizer::FORM_D;
+    public const FORM_KD = \Normalizer::FORM_KD;
+    public const FORM_C = \Normalizer::FORM_C;
+    public const FORM_KC = \Normalizer::FORM_KC;
+    public const NFD = \Normalizer::NFD;
+    public const NFKD = \Normalizer::NFKD;
+    public const NFC = \Normalizer::NFC;
+    public const NFKC = \Normalizer::NFKC;
+
+    private static $C;
+    private static $D;
+    private static $KD;
+    private static $cC;
+    private static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4];
+    private static $ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
+
+    public static function isNormalized(string $s, int $form = self::FORM_C)
+    {
+        if (!\in_array($form, [self::NFD, self::NFKD, self::NFC, self::NFKC])) {
+            return false;
+        }
+        if (!isset($s[strspn($s, self::$ASCII)])) {
+            return true;
+        }
+        if (self::NFC == $form && preg_match('//u', $s) && !preg_match('/[^\x00-\x{2FF}]/u', $s)) {
+            return true;
+        }
+
+        return self::normalize($s, $form) === $s;
+    }
+
+    public static function normalize(string $s, int $form = self::FORM_C)
+    {
+        if (!preg_match('//u', $s)) {
+            return false;
+        }
+
+        switch ($form) {
+            case self::NFC: $C = true; $K = false; break;
+            case self::NFD: $C = false; $K = false; break;
+            case self::NFKC: $C = true; $K = true; break;
+            case self::NFKD: $C = false; $K = true; break;
+            default:
+                if (\defined('Normalizer::NONE') && \Normalizer::NONE == $form) {
+                    return $s;
+                }
+
+                if (80000 > \PHP_VERSION_ID) {
+                    return false;
+                }
+
+                throw new \ValueError('normalizer_normalize(): Argument #2 ($form) must be a a valid normalization form');
+        }
+
+        if ('' === $s) {
+            return '';
+        }
+
+        if ($K && null === self::$KD) {
+            self::$KD = self::getData('compatibilityDecomposition');
+        }
+
+        if (null === self::$D) {
+            self::$D = self::getData('canonicalDecomposition');
+            self::$cC = self::getData('combiningClass');
+        }
+
+        if (null !== $mbEncoding = (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) ? mb_internal_encoding() : null) {
+            mb_internal_encoding('8bit');
+        }
+
+        $r = self::decompose($s, $K);
+
+        if ($C) {
+            if (null === self::$C) {
+                self::$C = self::getData('canonicalComposition');
+            }
+
+            $r = self::recompose($r);
+        }
+        if (null !== $mbEncoding) {
+            mb_internal_encoding($mbEncoding);
+        }
+
+        return $r;
+    }
+
+    private static function recompose($s)
+    {
+        $ASCII = self::$ASCII;
+        $compMap = self::$C;
+        $combClass = self::$cC;
+        $ulenMask = self::$ulenMask;
+
+        $result = $tail = '';
+
+        $i = $s[0] < "\x80" ? 1 : $ulenMask[$s[0] & "\xF0"];
+        $len = \strlen($s);
+
+        $lastUchr = substr($s, 0, $i);
+        $lastUcls = isset($combClass[$lastUchr]) ? 256 : 0;
+
+        while ($i < $len) {
+            if ($s[$i] < "\x80") {
+                // ASCII chars
+
+                if ($tail) {
+                    $lastUchr .= $tail;
+                    $tail = '';
+                }
+
+                if ($j = strspn($s, $ASCII, $i + 1)) {
+                    $lastUchr .= substr($s, $i, $j);
+                    $i += $j;
+                }
+
+                $result .= $lastUchr;
+                $lastUchr = $s[$i];
+                $lastUcls = 0;
+                ++$i;
+                continue;
+            }
+
+            $ulen = $ulenMask[$s[$i] & "\xF0"];
+            $uchr = substr($s, $i, $ulen);
+
+            if ($lastUchr < "\xE1\x84\x80" || "\xE1\x84\x92" < $lastUchr
+                || $uchr < "\xE1\x85\xA1" || "\xE1\x85\xB5" < $uchr
+                || $lastUcls) {
+                // Table lookup and combining chars composition
+
+                $ucls = $combClass[$uchr] ?? 0;
+
+                if (isset($compMap[$lastUchr.$uchr]) && (!$lastUcls || $lastUcls < $ucls)) {
+                    $lastUchr = $compMap[$lastUchr.$uchr];
+                } elseif ($lastUcls = $ucls) {
+                    $tail .= $uchr;
+                } else {
+                    if ($tail) {
+                        $lastUchr .= $tail;
+                        $tail = '';
+                    }
+
+                    $result .= $lastUchr;
+                    $lastUchr = $uchr;
+                }
+            } else {
+                // Hangul chars
+
+                $L = \ord($lastUchr[2]) - 0x80;
+                $V = \ord($uchr[2]) - 0xA1;
+                $T = 0;
+
+                $uchr = substr($s, $i + $ulen, 3);
+
+                if ("\xE1\x86\xA7" <= $uchr && $uchr <= "\xE1\x87\x82") {
+                    $T = \ord($uchr[2]) - 0xA7;
+                    0 > $T && $T += 0x40;
+                    $ulen += 3;
+                }
+
+                $L = 0xAC00 + ($L * 21 + $V) * 28 + $T;
+                $lastUchr = \chr(0xE0 | $L >> 12).\chr(0x80 | $L >> 6 & 0x3F).\chr(0x80 | $L & 0x3F);
+            }
+
+            $i += $ulen;
+        }
+
+        return $result.$lastUchr.$tail;
+    }
+
+    private static function decompose($s, $c)
+    {
+        $result = '';
+
+        $ASCII = self::$ASCII;
+        $decompMap = self::$D;
+        $combClass = self::$cC;
+        $ulenMask = self::$ulenMask;
+        if ($c) {
+            $compatMap = self::$KD;
+        }
+
+        $c = [];
+        $i = 0;
+        $len = \strlen($s);
+
+        while ($i < $len) {
+            if ($s[$i] < "\x80") {
+                // ASCII chars
+
+                if ($c) {
+                    ksort($c);
+                    $result .= implode('', $c);
+                    $c = [];
+                }
+
+                $j = 1 + strspn($s, $ASCII, $i + 1);
+                $result .= substr($s, $i, $j);
+                $i += $j;
+                continue;
+            }
+
+            $ulen = $ulenMask[$s[$i] & "\xF0"];
+            $uchr = substr($s, $i, $ulen);
+            $i += $ulen;
+
+            if ($uchr < "\xEA\xB0\x80" || "\xED\x9E\xA3" < $uchr) {
+                // Table lookup
+
+                if ($uchr !== $j = $compatMap[$uchr] ?? ($decompMap[$uchr] ?? $uchr)) {
+                    $uchr = $j;
+
+                    $j = \strlen($uchr);
+                    $ulen = $uchr[0] < "\x80" ? 1 : $ulenMask[$uchr[0] & "\xF0"];
+
+                    if ($ulen != $j) {
+                        // Put trailing chars in $s
+
+                        $j -= $ulen;
+                        $i -= $j;
+
+                        if (0 > $i) {
+                            $s = str_repeat(' ', -$i).$s;
+                            $len -= $i;
+                            $i = 0;
+                        }
+
+                        while ($j--) {
+                            $s[$i + $j] = $uchr[$ulen + $j];
+                        }
+
+                        $uchr = substr($uchr, 0, $ulen);
+                    }
+                }
+                if (isset($combClass[$uchr])) {
+                    // Combining chars, for sorting
+
+                    if (!isset($c[$combClass[$uchr]])) {
+                        $c[$combClass[$uchr]] = '';
+                    }
+                    $c[$combClass[$uchr]] .= $uchr;
+                    continue;
+                }
+            } else {
+                // Hangul chars
+
+                $uchr = unpack('C*', $uchr);
+                $j = (($uchr[1] - 224) << 12) + (($uchr[2] - 128) << 6) + $uchr[3] - 0xAC80;
+
+                $uchr = "\xE1\x84".\chr(0x80 + (int) ($j / 588))
+                       ."\xE1\x85".\chr(0xA1 + (int) (($j % 588) / 28));
+
+                if ($j %= 28) {
+                    $uchr .= $j < 25
+                        ? ("\xE1\x86".\chr(0xA7 + $j))
+                        : ("\xE1\x87".\chr(0x67 + $j));
+                }
+            }
+            if ($c) {
+                ksort($c);
+                $result .= implode('', $c);
+                $c = [];
+            }
+
+            $result .= $uchr;
+        }
+
+        if ($c) {
+            ksort($c);
+            $result .= implode('', $c);
+        }
+
+        return $result;
+    }
+
+    private static function getData($file)
+    {
+        if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
+            return require $file;
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/symfony/polyfill-intl-normalizer/README.md b/vendor/symfony/polyfill-intl-normalizer/README.md
new file mode 100644
index 000000000..15060c5f1
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-normalizer/README.md
@@ -0,0 +1,14 @@
+Symfony Polyfill / Intl: Normalizer
+===================================
+
+This component provides a fallback implementation for the
+[`Normalizer`](https://php.net/Normalizer) class provided
+by the [Intl](https://php.net/intl) extension.
+
+More information can be found in the
+[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
+
+License
+=======
+
+This library is released under the [MIT license](LICENSE).
diff --git a/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php b/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php
new file mode 100644
index 000000000..0fdfc890a
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php
@@ -0,0 +1,17 @@
+ 'À',
+  'Á' => 'Á',
+  'Â' => 'Â',
+  'Ã' => 'Ã',
+  'Ä' => 'Ä',
+  'Å' => 'Å',
+  'Ç' => 'Ç',
+  'È' => 'È',
+  'É' => 'É',
+  'Ê' => 'Ê',
+  'Ë' => 'Ë',
+  'Ì' => 'Ì',
+  'Í' => 'Í',
+  'Î' => 'Î',
+  'Ï' => 'Ï',
+  'Ñ' => 'Ñ',
+  'Ò' => 'Ò',
+  'Ó' => 'Ó',
+  'Ô' => 'Ô',
+  'Õ' => 'Õ',
+  'Ö' => 'Ö',
+  'Ù' => 'Ù',
+  'Ú' => 'Ú',
+  'Û' => 'Û',
+  'Ü' => 'Ü',
+  'Ý' => 'Ý',
+  'à' => 'à',
+  'á' => 'á',
+  'â' => 'â',
+  'ã' => 'ã',
+  'ä' => 'ä',
+  'å' => 'å',
+  'ç' => 'ç',
+  'è' => 'è',
+  'é' => 'é',
+  'ê' => 'ê',
+  'ë' => 'ë',
+  'ì' => 'ì',
+  'í' => 'í',
+  'î' => 'î',
+  'ï' => 'ï',
+  'ñ' => 'ñ',
+  'ò' => 'ò',
+  'ó' => 'ó',
+  'ô' => 'ô',
+  'õ' => 'õ',
+  'ö' => 'ö',
+  'ù' => 'ù',
+  'ú' => 'ú',
+  'û' => 'û',
+  'ü' => 'ü',
+  'ý' => 'ý',
+  'ÿ' => 'ÿ',
+  'Ā' => 'Ā',
+  'ā' => 'ā',
+  'Ă' => 'Ă',
+  'ă' => 'ă',
+  'Ą' => 'Ą',
+  'ą' => 'ą',
+  'Ć' => 'Ć',
+  'ć' => 'ć',
+  'Ĉ' => 'Ĉ',
+  'ĉ' => 'ĉ',
+  'Ċ' => 'Ċ',
+  'ċ' => 'ċ',
+  'Č' => 'Č',
+  'č' => 'č',
+  'Ď' => 'Ď',
+  'ď' => 'ď',
+  'Ē' => 'Ē',
+  'ē' => 'ē',
+  'Ĕ' => 'Ĕ',
+  'ĕ' => 'ĕ',
+  'Ė' => 'Ė',
+  'ė' => 'ė',
+  'Ę' => 'Ę',
+  'ę' => 'ę',
+  'Ě' => 'Ě',
+  'ě' => 'ě',
+  'Ĝ' => 'Ĝ',
+  'ĝ' => 'ĝ',
+  'Ğ' => 'Ğ',
+  'ğ' => 'ğ',
+  'Ġ' => 'Ġ',
+  'ġ' => 'ġ',
+  'Ģ' => 'Ģ',
+  'ģ' => 'ģ',
+  'Ĥ' => 'Ĥ',
+  'ĥ' => 'ĥ',
+  'Ĩ' => 'Ĩ',
+  'ĩ' => 'ĩ',
+  'Ī' => 'Ī',
+  'ī' => 'ī',
+  'Ĭ' => 'Ĭ',
+  'ĭ' => 'ĭ',
+  'Į' => 'Į',
+  'į' => 'į',
+  'İ' => 'İ',
+  'Ĵ' => 'Ĵ',
+  'ĵ' => 'ĵ',
+  'Ķ' => 'Ķ',
+  'ķ' => 'ķ',
+  'Ĺ' => 'Ĺ',
+  'ĺ' => 'ĺ',
+  'Ļ' => 'Ļ',
+  'ļ' => 'ļ',
+  'Ľ' => 'Ľ',
+  'ľ' => 'ľ',
+  'Ń' => 'Ń',
+  'ń' => 'ń',
+  'Ņ' => 'Ņ',
+  'ņ' => 'ņ',
+  'Ň' => 'Ň',
+  'ň' => 'ň',
+  'Ō' => 'Ō',
+  'ō' => 'ō',
+  'Ŏ' => 'Ŏ',
+  'ŏ' => 'ŏ',
+  'Ő' => 'Ő',
+  'ő' => 'ő',
+  'Ŕ' => 'Ŕ',
+  'ŕ' => 'ŕ',
+  'Ŗ' => 'Ŗ',
+  'ŗ' => 'ŗ',
+  'Ř' => 'Ř',
+  'ř' => 'ř',
+  'Ś' => 'Ś',
+  'ś' => 'ś',
+  'Ŝ' => 'Ŝ',
+  'ŝ' => 'ŝ',
+  'Ş' => 'Ş',
+  'ş' => 'ş',
+  'Š' => 'Š',
+  'š' => 'š',
+  'Ţ' => 'Ţ',
+  'ţ' => 'ţ',
+  'Ť' => 'Ť',
+  'ť' => 'ť',
+  'Ũ' => 'Ũ',
+  'ũ' => 'ũ',
+  'Ū' => 'Ū',
+  'ū' => 'ū',
+  'Ŭ' => 'Ŭ',
+  'ŭ' => 'ŭ',
+  'Ů' => 'Ů',
+  'ů' => 'ů',
+  'Ű' => 'Ű',
+  'ű' => 'ű',
+  'Ų' => 'Ų',
+  'ų' => 'ų',
+  'Ŵ' => 'Ŵ',
+  'ŵ' => 'ŵ',
+  'Ŷ' => 'Ŷ',
+  'ŷ' => 'ŷ',
+  'Ÿ' => 'Ÿ',
+  'Ź' => 'Ź',
+  'ź' => 'ź',
+  'Ż' => 'Ż',
+  'ż' => 'ż',
+  'Ž' => 'Ž',
+  'ž' => 'ž',
+  'Ơ' => 'Ơ',
+  'ơ' => 'ơ',
+  'Ư' => 'Ư',
+  'ư' => 'ư',
+  'Ǎ' => 'Ǎ',
+  'ǎ' => 'ǎ',
+  'Ǐ' => 'Ǐ',
+  'ǐ' => 'ǐ',
+  'Ǒ' => 'Ǒ',
+  'ǒ' => 'ǒ',
+  'Ǔ' => 'Ǔ',
+  'ǔ' => 'ǔ',
+  'Ǖ' => 'Ǖ',
+  'ǖ' => 'ǖ',
+  'Ǘ' => 'Ǘ',
+  'ǘ' => 'ǘ',
+  'Ǚ' => 'Ǚ',
+  'ǚ' => 'ǚ',
+  'Ǜ' => 'Ǜ',
+  'ǜ' => 'ǜ',
+  'Ǟ' => 'Ǟ',
+  'ǟ' => 'ǟ',
+  'Ǡ' => 'Ǡ',
+  'ǡ' => 'ǡ',
+  'Ǣ' => 'Ǣ',
+  'ǣ' => 'ǣ',
+  'Ǧ' => 'Ǧ',
+  'ǧ' => 'ǧ',
+  'Ǩ' => 'Ǩ',
+  'ǩ' => 'ǩ',
+  'Ǫ' => 'Ǫ',
+  'ǫ' => 'ǫ',
+  'Ǭ' => 'Ǭ',
+  'ǭ' => 'ǭ',
+  'Ǯ' => 'Ǯ',
+  'ǯ' => 'ǯ',
+  'ǰ' => 'ǰ',
+  'Ǵ' => 'Ǵ',
+  'ǵ' => 'ǵ',
+  'Ǹ' => 'Ǹ',
+  'ǹ' => 'ǹ',
+  'Ǻ' => 'Ǻ',
+  'ǻ' => 'ǻ',
+  'Ǽ' => 'Ǽ',
+  'ǽ' => 'ǽ',
+  'Ǿ' => 'Ǿ',
+  'ǿ' => 'ǿ',
+  'Ȁ' => 'Ȁ',
+  'ȁ' => 'ȁ',
+  'Ȃ' => 'Ȃ',
+  'ȃ' => 'ȃ',
+  'Ȅ' => 'Ȅ',
+  'ȅ' => 'ȅ',
+  'Ȇ' => 'Ȇ',
+  'ȇ' => 'ȇ',
+  'Ȉ' => 'Ȉ',
+  'ȉ' => 'ȉ',
+  'Ȋ' => 'Ȋ',
+  'ȋ' => 'ȋ',
+  'Ȍ' => 'Ȍ',
+  'ȍ' => 'ȍ',
+  'Ȏ' => 'Ȏ',
+  'ȏ' => 'ȏ',
+  'Ȑ' => 'Ȑ',
+  'ȑ' => 'ȑ',
+  'Ȓ' => 'Ȓ',
+  'ȓ' => 'ȓ',
+  'Ȕ' => 'Ȕ',
+  'ȕ' => 'ȕ',
+  'Ȗ' => 'Ȗ',
+  'ȗ' => 'ȗ',
+  'Ș' => 'Ș',
+  'ș' => 'ș',
+  'Ț' => 'Ț',
+  'ț' => 'ț',
+  'Ȟ' => 'Ȟ',
+  'ȟ' => 'ȟ',
+  'Ȧ' => 'Ȧ',
+  'ȧ' => 'ȧ',
+  'Ȩ' => 'Ȩ',
+  'ȩ' => 'ȩ',
+  'Ȫ' => 'Ȫ',
+  'ȫ' => 'ȫ',
+  'Ȭ' => 'Ȭ',
+  'ȭ' => 'ȭ',
+  'Ȯ' => 'Ȯ',
+  'ȯ' => 'ȯ',
+  'Ȱ' => 'Ȱ',
+  'ȱ' => 'ȱ',
+  'Ȳ' => 'Ȳ',
+  'ȳ' => 'ȳ',
+  '΅' => '΅',
+  'Ά' => 'Ά',
+  'Έ' => 'Έ',
+  'Ή' => 'Ή',
+  'Ί' => 'Ί',
+  'Ό' => 'Ό',
+  'Ύ' => 'Ύ',
+  'Ώ' => 'Ώ',
+  'ΐ' => 'ΐ',
+  'Ϊ' => 'Ϊ',
+  'Ϋ' => 'Ϋ',
+  'ά' => 'ά',
+  'έ' => 'έ',
+  'ή' => 'ή',
+  'ί' => 'ί',
+  'ΰ' => 'ΰ',
+  'ϊ' => 'ϊ',
+  'ϋ' => 'ϋ',
+  'ό' => 'ό',
+  'ύ' => 'ύ',
+  'ώ' => 'ώ',
+  'ϓ' => 'ϓ',
+  'ϔ' => 'ϔ',
+  'Ѐ' => 'Ѐ',
+  'Ё' => 'Ё',
+  'Ѓ' => 'Ѓ',
+  'Ї' => 'Ї',
+  'Ќ' => 'Ќ',
+  'Ѝ' => 'Ѝ',
+  'Ў' => 'Ў',
+  'Й' => 'Й',
+  'й' => 'й',
+  'ѐ' => 'ѐ',
+  'ё' => 'ё',
+  'ѓ' => 'ѓ',
+  'ї' => 'ї',
+  'ќ' => 'ќ',
+  'ѝ' => 'ѝ',
+  'ў' => 'ў',
+  'Ѷ' => 'Ѷ',
+  'ѷ' => 'ѷ',
+  'Ӂ' => 'Ӂ',
+  'ӂ' => 'ӂ',
+  'Ӑ' => 'Ӑ',
+  'ӑ' => 'ӑ',
+  'Ӓ' => 'Ӓ',
+  'ӓ' => 'ӓ',
+  'Ӗ' => 'Ӗ',
+  'ӗ' => 'ӗ',
+  'Ӛ' => 'Ӛ',
+  'ӛ' => 'ӛ',
+  'Ӝ' => 'Ӝ',
+  'ӝ' => 'ӝ',
+  'Ӟ' => 'Ӟ',
+  'ӟ' => 'ӟ',
+  'Ӣ' => 'Ӣ',
+  'ӣ' => 'ӣ',
+  'Ӥ' => 'Ӥ',
+  'ӥ' => 'ӥ',
+  'Ӧ' => 'Ӧ',
+  'ӧ' => 'ӧ',
+  'Ӫ' => 'Ӫ',
+  'ӫ' => 'ӫ',
+  'Ӭ' => 'Ӭ',
+  'ӭ' => 'ӭ',
+  'Ӯ' => 'Ӯ',
+  'ӯ' => 'ӯ',
+  'Ӱ' => 'Ӱ',
+  'ӱ' => 'ӱ',
+  'Ӳ' => 'Ӳ',
+  'ӳ' => 'ӳ',
+  'Ӵ' => 'Ӵ',
+  'ӵ' => 'ӵ',
+  'Ӹ' => 'Ӹ',
+  'ӹ' => 'ӹ',
+  'آ' => 'آ',
+  'أ' => 'أ',
+  'ؤ' => 'ؤ',
+  'إ' => 'إ',
+  'ئ' => 'ئ',
+  'ۀ' => 'ۀ',
+  'ۂ' => 'ۂ',
+  'ۓ' => 'ۓ',
+  'ऩ' => 'ऩ',
+  'ऱ' => 'ऱ',
+  'ऴ' => 'ऴ',
+  'ো' => 'ো',
+  'ৌ' => 'ৌ',
+  'ୈ' => 'ୈ',
+  'ୋ' => 'ୋ',
+  'ୌ' => 'ୌ',
+  'ஔ' => 'ஔ',
+  'ொ' => 'ொ',
+  'ோ' => 'ோ',
+  'ௌ' => 'ௌ',
+  'ై' => 'ై',
+  'ೀ' => 'ೀ',
+  'ೇ' => 'ೇ',
+  'ೈ' => 'ೈ',
+  'ೊ' => 'ೊ',
+  'ೋ' => 'ೋ',
+  'ൊ' => 'ൊ',
+  'ോ' => 'ോ',
+  'ൌ' => 'ൌ',
+  'ේ' => 'ේ',
+  'ො' => 'ො',
+  'ෝ' => 'ෝ',
+  'ෞ' => 'ෞ',
+  'ဦ' => 'ဦ',
+  'ᬆ' => 'ᬆ',
+  'ᬈ' => 'ᬈ',
+  'ᬊ' => 'ᬊ',
+  'ᬌ' => 'ᬌ',
+  'ᬎ' => 'ᬎ',
+  'ᬒ' => 'ᬒ',
+  'ᬻ' => 'ᬻ',
+  'ᬽ' => 'ᬽ',
+  'ᭀ' => 'ᭀ',
+  'ᭁ' => 'ᭁ',
+  'ᭃ' => 'ᭃ',
+  'Ḁ' => 'Ḁ',
+  'ḁ' => 'ḁ',
+  'Ḃ' => 'Ḃ',
+  'ḃ' => 'ḃ',
+  'Ḅ' => 'Ḅ',
+  'ḅ' => 'ḅ',
+  'Ḇ' => 'Ḇ',
+  'ḇ' => 'ḇ',
+  'Ḉ' => 'Ḉ',
+  'ḉ' => 'ḉ',
+  'Ḋ' => 'Ḋ',
+  'ḋ' => 'ḋ',
+  'Ḍ' => 'Ḍ',
+  'ḍ' => 'ḍ',
+  'Ḏ' => 'Ḏ',
+  'ḏ' => 'ḏ',
+  'Ḑ' => 'Ḑ',
+  'ḑ' => 'ḑ',
+  'Ḓ' => 'Ḓ',
+  'ḓ' => 'ḓ',
+  'Ḕ' => 'Ḕ',
+  'ḕ' => 'ḕ',
+  'Ḗ' => 'Ḗ',
+  'ḗ' => 'ḗ',
+  'Ḙ' => 'Ḙ',
+  'ḙ' => 'ḙ',
+  'Ḛ' => 'Ḛ',
+  'ḛ' => 'ḛ',
+  'Ḝ' => 'Ḝ',
+  'ḝ' => 'ḝ',
+  'Ḟ' => 'Ḟ',
+  'ḟ' => 'ḟ',
+  'Ḡ' => 'Ḡ',
+  'ḡ' => 'ḡ',
+  'Ḣ' => 'Ḣ',
+  'ḣ' => 'ḣ',
+  'Ḥ' => 'Ḥ',
+  'ḥ' => 'ḥ',
+  'Ḧ' => 'Ḧ',
+  'ḧ' => 'ḧ',
+  'Ḩ' => 'Ḩ',
+  'ḩ' => 'ḩ',
+  'Ḫ' => 'Ḫ',
+  'ḫ' => 'ḫ',
+  'Ḭ' => 'Ḭ',
+  'ḭ' => 'ḭ',
+  'Ḯ' => 'Ḯ',
+  'ḯ' => 'ḯ',
+  'Ḱ' => 'Ḱ',
+  'ḱ' => 'ḱ',
+  'Ḳ' => 'Ḳ',
+  'ḳ' => 'ḳ',
+  'Ḵ' => 'Ḵ',
+  'ḵ' => 'ḵ',
+  'Ḷ' => 'Ḷ',
+  'ḷ' => 'ḷ',
+  'Ḹ' => 'Ḹ',
+  'ḹ' => 'ḹ',
+  'Ḻ' => 'Ḻ',
+  'ḻ' => 'ḻ',
+  'Ḽ' => 'Ḽ',
+  'ḽ' => 'ḽ',
+  'Ḿ' => 'Ḿ',
+  'ḿ' => 'ḿ',
+  'Ṁ' => 'Ṁ',
+  'ṁ' => 'ṁ',
+  'Ṃ' => 'Ṃ',
+  'ṃ' => 'ṃ',
+  'Ṅ' => 'Ṅ',
+  'ṅ' => 'ṅ',
+  'Ṇ' => 'Ṇ',
+  'ṇ' => 'ṇ',
+  'Ṉ' => 'Ṉ',
+  'ṉ' => 'ṉ',
+  'Ṋ' => 'Ṋ',
+  'ṋ' => 'ṋ',
+  'Ṍ' => 'Ṍ',
+  'ṍ' => 'ṍ',
+  'Ṏ' => 'Ṏ',
+  'ṏ' => 'ṏ',
+  'Ṑ' => 'Ṑ',
+  'ṑ' => 'ṑ',
+  'Ṓ' => 'Ṓ',
+  'ṓ' => 'ṓ',
+  'Ṕ' => 'Ṕ',
+  'ṕ' => 'ṕ',
+  'Ṗ' => 'Ṗ',
+  'ṗ' => 'ṗ',
+  'Ṙ' => 'Ṙ',
+  'ṙ' => 'ṙ',
+  'Ṛ' => 'Ṛ',
+  'ṛ' => 'ṛ',
+  'Ṝ' => 'Ṝ',
+  'ṝ' => 'ṝ',
+  'Ṟ' => 'Ṟ',
+  'ṟ' => 'ṟ',
+  'Ṡ' => 'Ṡ',
+  'ṡ' => 'ṡ',
+  'Ṣ' => 'Ṣ',
+  'ṣ' => 'ṣ',
+  'Ṥ' => 'Ṥ',
+  'ṥ' => 'ṥ',
+  'Ṧ' => 'Ṧ',
+  'ṧ' => 'ṧ',
+  'Ṩ' => 'Ṩ',
+  'ṩ' => 'ṩ',
+  'Ṫ' => 'Ṫ',
+  'ṫ' => 'ṫ',
+  'Ṭ' => 'Ṭ',
+  'ṭ' => 'ṭ',
+  'Ṯ' => 'Ṯ',
+  'ṯ' => 'ṯ',
+  'Ṱ' => 'Ṱ',
+  'ṱ' => 'ṱ',
+  'Ṳ' => 'Ṳ',
+  'ṳ' => 'ṳ',
+  'Ṵ' => 'Ṵ',
+  'ṵ' => 'ṵ',
+  'Ṷ' => 'Ṷ',
+  'ṷ' => 'ṷ',
+  'Ṹ' => 'Ṹ',
+  'ṹ' => 'ṹ',
+  'Ṻ' => 'Ṻ',
+  'ṻ' => 'ṻ',
+  'Ṽ' => 'Ṽ',
+  'ṽ' => 'ṽ',
+  'Ṿ' => 'Ṿ',
+  'ṿ' => 'ṿ',
+  'Ẁ' => 'Ẁ',
+  'ẁ' => 'ẁ',
+  'Ẃ' => 'Ẃ',
+  'ẃ' => 'ẃ',
+  'Ẅ' => 'Ẅ',
+  'ẅ' => 'ẅ',
+  'Ẇ' => 'Ẇ',
+  'ẇ' => 'ẇ',
+  'Ẉ' => 'Ẉ',
+  'ẉ' => 'ẉ',
+  'Ẋ' => 'Ẋ',
+  'ẋ' => 'ẋ',
+  'Ẍ' => 'Ẍ',
+  'ẍ' => 'ẍ',
+  'Ẏ' => 'Ẏ',
+  'ẏ' => 'ẏ',
+  'Ẑ' => 'Ẑ',
+  'ẑ' => 'ẑ',
+  'Ẓ' => 'Ẓ',
+  'ẓ' => 'ẓ',
+  'Ẕ' => 'Ẕ',
+  'ẕ' => 'ẕ',
+  'ẖ' => 'ẖ',
+  'ẗ' => 'ẗ',
+  'ẘ' => 'ẘ',
+  'ẙ' => 'ẙ',
+  'ẛ' => 'ẛ',
+  'Ạ' => 'Ạ',
+  'ạ' => 'ạ',
+  'Ả' => 'Ả',
+  'ả' => 'ả',
+  'Ấ' => 'Ấ',
+  'ấ' => 'ấ',
+  'Ầ' => 'Ầ',
+  'ầ' => 'ầ',
+  'Ẩ' => 'Ẩ',
+  'ẩ' => 'ẩ',
+  'Ẫ' => 'Ẫ',
+  'ẫ' => 'ẫ',
+  'Ậ' => 'Ậ',
+  'ậ' => 'ậ',
+  'Ắ' => 'Ắ',
+  'ắ' => 'ắ',
+  'Ằ' => 'Ằ',
+  'ằ' => 'ằ',
+  'Ẳ' => 'Ẳ',
+  'ẳ' => 'ẳ',
+  'Ẵ' => 'Ẵ',
+  'ẵ' => 'ẵ',
+  'Ặ' => 'Ặ',
+  'ặ' => 'ặ',
+  'Ẹ' => 'Ẹ',
+  'ẹ' => 'ẹ',
+  'Ẻ' => 'Ẻ',
+  'ẻ' => 'ẻ',
+  'Ẽ' => 'Ẽ',
+  'ẽ' => 'ẽ',
+  'Ế' => 'Ế',
+  'ế' => 'ế',
+  'Ề' => 'Ề',
+  'ề' => 'ề',
+  'Ể' => 'Ể',
+  'ể' => 'ể',
+  'Ễ' => 'Ễ',
+  'ễ' => 'ễ',
+  'Ệ' => 'Ệ',
+  'ệ' => 'ệ',
+  'Ỉ' => 'Ỉ',
+  'ỉ' => 'ỉ',
+  'Ị' => 'Ị',
+  'ị' => 'ị',
+  'Ọ' => 'Ọ',
+  'ọ' => 'ọ',
+  'Ỏ' => 'Ỏ',
+  'ỏ' => 'ỏ',
+  'Ố' => 'Ố',
+  'ố' => 'ố',
+  'Ồ' => 'Ồ',
+  'ồ' => 'ồ',
+  'Ổ' => 'Ổ',
+  'ổ' => 'ổ',
+  'Ỗ' => 'Ỗ',
+  'ỗ' => 'ỗ',
+  'Ộ' => 'Ộ',
+  'ộ' => 'ộ',
+  'Ớ' => 'Ớ',
+  'ớ' => 'ớ',
+  'Ờ' => 'Ờ',
+  'ờ' => 'ờ',
+  'Ở' => 'Ở',
+  'ở' => 'ở',
+  'Ỡ' => 'Ỡ',
+  'ỡ' => 'ỡ',
+  'Ợ' => 'Ợ',
+  'ợ' => 'ợ',
+  'Ụ' => 'Ụ',
+  'ụ' => 'ụ',
+  'Ủ' => 'Ủ',
+  'ủ' => 'ủ',
+  'Ứ' => 'Ứ',
+  'ứ' => 'ứ',
+  'Ừ' => 'Ừ',
+  'ừ' => 'ừ',
+  'Ử' => 'Ử',
+  'ử' => 'ử',
+  'Ữ' => 'Ữ',
+  'ữ' => 'ữ',
+  'Ự' => 'Ự',
+  'ự' => 'ự',
+  'Ỳ' => 'Ỳ',
+  'ỳ' => 'ỳ',
+  'Ỵ' => 'Ỵ',
+  'ỵ' => 'ỵ',
+  'Ỷ' => 'Ỷ',
+  'ỷ' => 'ỷ',
+  'Ỹ' => 'Ỹ',
+  'ỹ' => 'ỹ',
+  'ἀ' => 'ἀ',
+  'ἁ' => 'ἁ',
+  'ἂ' => 'ἂ',
+  'ἃ' => 'ἃ',
+  'ἄ' => 'ἄ',
+  'ἅ' => 'ἅ',
+  'ἆ' => 'ἆ',
+  'ἇ' => 'ἇ',
+  'Ἀ' => 'Ἀ',
+  'Ἁ' => 'Ἁ',
+  'Ἂ' => 'Ἂ',
+  'Ἃ' => 'Ἃ',
+  'Ἄ' => 'Ἄ',
+  'Ἅ' => 'Ἅ',
+  'Ἆ' => 'Ἆ',
+  'Ἇ' => 'Ἇ',
+  'ἐ' => 'ἐ',
+  'ἑ' => 'ἑ',
+  'ἒ' => 'ἒ',
+  'ἓ' => 'ἓ',
+  'ἔ' => 'ἔ',
+  'ἕ' => 'ἕ',
+  'Ἐ' => 'Ἐ',
+  'Ἑ' => 'Ἑ',
+  'Ἒ' => 'Ἒ',
+  'Ἓ' => 'Ἓ',
+  'Ἔ' => 'Ἔ',
+  'Ἕ' => 'Ἕ',
+  'ἠ' => 'ἠ',
+  'ἡ' => 'ἡ',
+  'ἢ' => 'ἢ',
+  'ἣ' => 'ἣ',
+  'ἤ' => 'ἤ',
+  'ἥ' => 'ἥ',
+  'ἦ' => 'ἦ',
+  'ἧ' => 'ἧ',
+  'Ἠ' => 'Ἠ',
+  'Ἡ' => 'Ἡ',
+  'Ἢ' => 'Ἢ',
+  'Ἣ' => 'Ἣ',
+  'Ἤ' => 'Ἤ',
+  'Ἥ' => 'Ἥ',
+  'Ἦ' => 'Ἦ',
+  'Ἧ' => 'Ἧ',
+  'ἰ' => 'ἰ',
+  'ἱ' => 'ἱ',
+  'ἲ' => 'ἲ',
+  'ἳ' => 'ἳ',
+  'ἴ' => 'ἴ',
+  'ἵ' => 'ἵ',
+  'ἶ' => 'ἶ',
+  'ἷ' => 'ἷ',
+  'Ἰ' => 'Ἰ',
+  'Ἱ' => 'Ἱ',
+  'Ἲ' => 'Ἲ',
+  'Ἳ' => 'Ἳ',
+  'Ἴ' => 'Ἴ',
+  'Ἵ' => 'Ἵ',
+  'Ἶ' => 'Ἶ',
+  'Ἷ' => 'Ἷ',
+  'ὀ' => 'ὀ',
+  'ὁ' => 'ὁ',
+  'ὂ' => 'ὂ',
+  'ὃ' => 'ὃ',
+  'ὄ' => 'ὄ',
+  'ὅ' => 'ὅ',
+  'Ὀ' => 'Ὀ',
+  'Ὁ' => 'Ὁ',
+  'Ὂ' => 'Ὂ',
+  'Ὃ' => 'Ὃ',
+  'Ὄ' => 'Ὄ',
+  'Ὅ' => 'Ὅ',
+  'ὐ' => 'ὐ',
+  'ὑ' => 'ὑ',
+  'ὒ' => 'ὒ',
+  'ὓ' => 'ὓ',
+  'ὔ' => 'ὔ',
+  'ὕ' => 'ὕ',
+  'ὖ' => 'ὖ',
+  'ὗ' => 'ὗ',
+  'Ὑ' => 'Ὑ',
+  'Ὓ' => 'Ὓ',
+  'Ὕ' => 'Ὕ',
+  'Ὗ' => 'Ὗ',
+  'ὠ' => 'ὠ',
+  'ὡ' => 'ὡ',
+  'ὢ' => 'ὢ',
+  'ὣ' => 'ὣ',
+  'ὤ' => 'ὤ',
+  'ὥ' => 'ὥ',
+  'ὦ' => 'ὦ',
+  'ὧ' => 'ὧ',
+  'Ὠ' => 'Ὠ',
+  'Ὡ' => 'Ὡ',
+  'Ὢ' => 'Ὢ',
+  'Ὣ' => 'Ὣ',
+  'Ὤ' => 'Ὤ',
+  'Ὥ' => 'Ὥ',
+  'Ὦ' => 'Ὦ',
+  'Ὧ' => 'Ὧ',
+  'ὰ' => 'ὰ',
+  'ὲ' => 'ὲ',
+  'ὴ' => 'ὴ',
+  'ὶ' => 'ὶ',
+  'ὸ' => 'ὸ',
+  'ὺ' => 'ὺ',
+  'ὼ' => 'ὼ',
+  'ᾀ' => 'ᾀ',
+  'ᾁ' => 'ᾁ',
+  'ᾂ' => 'ᾂ',
+  'ᾃ' => 'ᾃ',
+  'ᾄ' => 'ᾄ',
+  'ᾅ' => 'ᾅ',
+  'ᾆ' => 'ᾆ',
+  'ᾇ' => 'ᾇ',
+  'ᾈ' => 'ᾈ',
+  'ᾉ' => 'ᾉ',
+  'ᾊ' => 'ᾊ',
+  'ᾋ' => 'ᾋ',
+  'ᾌ' => 'ᾌ',
+  'ᾍ' => 'ᾍ',
+  'ᾎ' => 'ᾎ',
+  'ᾏ' => 'ᾏ',
+  'ᾐ' => 'ᾐ',
+  'ᾑ' => 'ᾑ',
+  'ᾒ' => 'ᾒ',
+  'ᾓ' => 'ᾓ',
+  'ᾔ' => 'ᾔ',
+  'ᾕ' => 'ᾕ',
+  'ᾖ' => 'ᾖ',
+  'ᾗ' => 'ᾗ',
+  'ᾘ' => 'ᾘ',
+  'ᾙ' => 'ᾙ',
+  'ᾚ' => 'ᾚ',
+  'ᾛ' => 'ᾛ',
+  'ᾜ' => 'ᾜ',
+  'ᾝ' => 'ᾝ',
+  'ᾞ' => 'ᾞ',
+  'ᾟ' => 'ᾟ',
+  'ᾠ' => 'ᾠ',
+  'ᾡ' => 'ᾡ',
+  'ᾢ' => 'ᾢ',
+  'ᾣ' => 'ᾣ',
+  'ᾤ' => 'ᾤ',
+  'ᾥ' => 'ᾥ',
+  'ᾦ' => 'ᾦ',
+  'ᾧ' => 'ᾧ',
+  'ᾨ' => 'ᾨ',
+  'ᾩ' => 'ᾩ',
+  'ᾪ' => 'ᾪ',
+  'ᾫ' => 'ᾫ',
+  'ᾬ' => 'ᾬ',
+  'ᾭ' => 'ᾭ',
+  'ᾮ' => 'ᾮ',
+  'ᾯ' => 'ᾯ',
+  'ᾰ' => 'ᾰ',
+  'ᾱ' => 'ᾱ',
+  'ᾲ' => 'ᾲ',
+  'ᾳ' => 'ᾳ',
+  'ᾴ' => 'ᾴ',
+  'ᾶ' => 'ᾶ',
+  'ᾷ' => 'ᾷ',
+  'Ᾰ' => 'Ᾰ',
+  'Ᾱ' => 'Ᾱ',
+  'Ὰ' => 'Ὰ',
+  'ᾼ' => 'ᾼ',
+  '῁' => '῁',
+  'ῂ' => 'ῂ',
+  'ῃ' => 'ῃ',
+  'ῄ' => 'ῄ',
+  'ῆ' => 'ῆ',
+  'ῇ' => 'ῇ',
+  'Ὲ' => 'Ὲ',
+  'Ὴ' => 'Ὴ',
+  'ῌ' => 'ῌ',
+  '῍' => '῍',
+  '῎' => '῎',
+  '῏' => '῏',
+  'ῐ' => 'ῐ',
+  'ῑ' => 'ῑ',
+  'ῒ' => 'ῒ',
+  'ῖ' => 'ῖ',
+  'ῗ' => 'ῗ',
+  'Ῐ' => 'Ῐ',
+  'Ῑ' => 'Ῑ',
+  'Ὶ' => 'Ὶ',
+  '῝' => '῝',
+  '῞' => '῞',
+  '῟' => '῟',
+  'ῠ' => 'ῠ',
+  'ῡ' => 'ῡ',
+  'ῢ' => 'ῢ',
+  'ῤ' => 'ῤ',
+  'ῥ' => 'ῥ',
+  'ῦ' => 'ῦ',
+  'ῧ' => 'ῧ',
+  'Ῠ' => 'Ῠ',
+  'Ῡ' => 'Ῡ',
+  'Ὺ' => 'Ὺ',
+  'Ῥ' => 'Ῥ',
+  '῭' => '῭',
+  'ῲ' => 'ῲ',
+  'ῳ' => 'ῳ',
+  'ῴ' => 'ῴ',
+  'ῶ' => 'ῶ',
+  'ῷ' => 'ῷ',
+  'Ὸ' => 'Ὸ',
+  'Ὼ' => 'Ὼ',
+  'ῼ' => 'ῼ',
+  '↚' => '↚',
+  '↛' => '↛',
+  '↮' => '↮',
+  '⇍' => '⇍',
+  '⇎' => '⇎',
+  '⇏' => '⇏',
+  '∄' => '∄',
+  '∉' => '∉',
+  '∌' => '∌',
+  '∤' => '∤',
+  '∦' => '∦',
+  '≁' => '≁',
+  '≄' => '≄',
+  '≇' => '≇',
+  '≉' => '≉',
+  '≠' => '≠',
+  '≢' => '≢',
+  '≭' => '≭',
+  '≮' => '≮',
+  '≯' => '≯',
+  '≰' => '≰',
+  '≱' => '≱',
+  '≴' => '≴',
+  '≵' => '≵',
+  '≸' => '≸',
+  '≹' => '≹',
+  '⊀' => '⊀',
+  '⊁' => '⊁',
+  '⊄' => '⊄',
+  '⊅' => '⊅',
+  '⊈' => '⊈',
+  '⊉' => '⊉',
+  '⊬' => '⊬',
+  '⊭' => '⊭',
+  '⊮' => '⊮',
+  '⊯' => '⊯',
+  '⋠' => '⋠',
+  '⋡' => '⋡',
+  '⋢' => '⋢',
+  '⋣' => '⋣',
+  '⋪' => '⋪',
+  '⋫' => '⋫',
+  '⋬' => '⋬',
+  '⋭' => '⋭',
+  'が' => 'が',
+  'ぎ' => 'ぎ',
+  'ぐ' => 'ぐ',
+  'げ' => 'げ',
+  'ご' => 'ご',
+  'ざ' => 'ざ',
+  'じ' => 'じ',
+  'ず' => 'ず',
+  'ぜ' => 'ぜ',
+  'ぞ' => 'ぞ',
+  'だ' => 'だ',
+  'ぢ' => 'ぢ',
+  'づ' => 'づ',
+  'で' => 'で',
+  'ど' => 'ど',
+  'ば' => 'ば',
+  'ぱ' => 'ぱ',
+  'び' => 'び',
+  'ぴ' => 'ぴ',
+  'ぶ' => 'ぶ',
+  'ぷ' => 'ぷ',
+  'べ' => 'べ',
+  'ぺ' => 'ぺ',
+  'ぼ' => 'ぼ',
+  'ぽ' => 'ぽ',
+  'ゔ' => 'ゔ',
+  'ゞ' => 'ゞ',
+  'ガ' => 'ガ',
+  'ギ' => 'ギ',
+  'グ' => 'グ',
+  'ゲ' => 'ゲ',
+  'ゴ' => 'ゴ',
+  'ザ' => 'ザ',
+  'ジ' => 'ジ',
+  'ズ' => 'ズ',
+  'ゼ' => 'ゼ',
+  'ゾ' => 'ゾ',
+  'ダ' => 'ダ',
+  'ヂ' => 'ヂ',
+  'ヅ' => 'ヅ',
+  'デ' => 'デ',
+  'ド' => 'ド',
+  'バ' => 'バ',
+  'パ' => 'パ',
+  'ビ' => 'ビ',
+  'ピ' => 'ピ',
+  'ブ' => 'ブ',
+  'プ' => 'プ',
+  'ベ' => 'ベ',
+  'ペ' => 'ペ',
+  'ボ' => 'ボ',
+  'ポ' => 'ポ',
+  'ヴ' => 'ヴ',
+  'ヷ' => 'ヷ',
+  'ヸ' => 'ヸ',
+  'ヹ' => 'ヹ',
+  'ヺ' => 'ヺ',
+  'ヾ' => 'ヾ',
+  '𑂚' => '𑂚',
+  '𑂜' => '𑂜',
+  '𑂫' => '𑂫',
+  '𑄮' => '𑄮',
+  '𑄯' => '𑄯',
+  '𑍋' => '𑍋',
+  '𑍌' => '𑍌',
+  '𑒻' => '𑒻',
+  '𑒼' => '𑒼',
+  '𑒾' => '𑒾',
+  '𑖺' => '𑖺',
+  '𑖻' => '𑖻',
+  '𑤸' => '𑤸',
+);
diff --git a/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php
new file mode 100644
index 000000000..5a3e8e096
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php
@@ -0,0 +1,2065 @@
+ 'À',
+  'Á' => 'Á',
+  'Â' => 'Â',
+  'Ã' => 'Ã',
+  'Ä' => 'Ä',
+  'Å' => 'Å',
+  'Ç' => 'Ç',
+  'È' => 'È',
+  'É' => 'É',
+  'Ê' => 'Ê',
+  'Ë' => 'Ë',
+  'Ì' => 'Ì',
+  'Í' => 'Í',
+  'Î' => 'Î',
+  'Ï' => 'Ï',
+  'Ñ' => 'Ñ',
+  'Ò' => 'Ò',
+  'Ó' => 'Ó',
+  'Ô' => 'Ô',
+  'Õ' => 'Õ',
+  'Ö' => 'Ö',
+  'Ù' => 'Ù',
+  'Ú' => 'Ú',
+  'Û' => 'Û',
+  'Ü' => 'Ü',
+  'Ý' => 'Ý',
+  'à' => 'à',
+  'á' => 'á',
+  'â' => 'â',
+  'ã' => 'ã',
+  'ä' => 'ä',
+  'å' => 'å',
+  'ç' => 'ç',
+  'è' => 'è',
+  'é' => 'é',
+  'ê' => 'ê',
+  'ë' => 'ë',
+  'ì' => 'ì',
+  'í' => 'í',
+  'î' => 'î',
+  'ï' => 'ï',
+  'ñ' => 'ñ',
+  'ò' => 'ò',
+  'ó' => 'ó',
+  'ô' => 'ô',
+  'õ' => 'õ',
+  'ö' => 'ö',
+  'ù' => 'ù',
+  'ú' => 'ú',
+  'û' => 'û',
+  'ü' => 'ü',
+  'ý' => 'ý',
+  'ÿ' => 'ÿ',
+  'Ā' => 'Ā',
+  'ā' => 'ā',
+  'Ă' => 'Ă',
+  'ă' => 'ă',
+  'Ą' => 'Ą',
+  'ą' => 'ą',
+  'Ć' => 'Ć',
+  'ć' => 'ć',
+  'Ĉ' => 'Ĉ',
+  'ĉ' => 'ĉ',
+  'Ċ' => 'Ċ',
+  'ċ' => 'ċ',
+  'Č' => 'Č',
+  'č' => 'č',
+  'Ď' => 'Ď',
+  'ď' => 'ď',
+  'Ē' => 'Ē',
+  'ē' => 'ē',
+  'Ĕ' => 'Ĕ',
+  'ĕ' => 'ĕ',
+  'Ė' => 'Ė',
+  'ė' => 'ė',
+  'Ę' => 'Ę',
+  'ę' => 'ę',
+  'Ě' => 'Ě',
+  'ě' => 'ě',
+  'Ĝ' => 'Ĝ',
+  'ĝ' => 'ĝ',
+  'Ğ' => 'Ğ',
+  'ğ' => 'ğ',
+  'Ġ' => 'Ġ',
+  'ġ' => 'ġ',
+  'Ģ' => 'Ģ',
+  'ģ' => 'ģ',
+  'Ĥ' => 'Ĥ',
+  'ĥ' => 'ĥ',
+  'Ĩ' => 'Ĩ',
+  'ĩ' => 'ĩ',
+  'Ī' => 'Ī',
+  'ī' => 'ī',
+  'Ĭ' => 'Ĭ',
+  'ĭ' => 'ĭ',
+  'Į' => 'Į',
+  'į' => 'į',
+  'İ' => 'İ',
+  'Ĵ' => 'Ĵ',
+  'ĵ' => 'ĵ',
+  'Ķ' => 'Ķ',
+  'ķ' => 'ķ',
+  'Ĺ' => 'Ĺ',
+  'ĺ' => 'ĺ',
+  'Ļ' => 'Ļ',
+  'ļ' => 'ļ',
+  'Ľ' => 'Ľ',
+  'ľ' => 'ľ',
+  'Ń' => 'Ń',
+  'ń' => 'ń',
+  'Ņ' => 'Ņ',
+  'ņ' => 'ņ',
+  'Ň' => 'Ň',
+  'ň' => 'ň',
+  'Ō' => 'Ō',
+  'ō' => 'ō',
+  'Ŏ' => 'Ŏ',
+  'ŏ' => 'ŏ',
+  'Ő' => 'Ő',
+  'ő' => 'ő',
+  'Ŕ' => 'Ŕ',
+  'ŕ' => 'ŕ',
+  'Ŗ' => 'Ŗ',
+  'ŗ' => 'ŗ',
+  'Ř' => 'Ř',
+  'ř' => 'ř',
+  'Ś' => 'Ś',
+  'ś' => 'ś',
+  'Ŝ' => 'Ŝ',
+  'ŝ' => 'ŝ',
+  'Ş' => 'Ş',
+  'ş' => 'ş',
+  'Š' => 'Š',
+  'š' => 'š',
+  'Ţ' => 'Ţ',
+  'ţ' => 'ţ',
+  'Ť' => 'Ť',
+  'ť' => 'ť',
+  'Ũ' => 'Ũ',
+  'ũ' => 'ũ',
+  'Ū' => 'Ū',
+  'ū' => 'ū',
+  'Ŭ' => 'Ŭ',
+  'ŭ' => 'ŭ',
+  'Ů' => 'Ů',
+  'ů' => 'ů',
+  'Ű' => 'Ű',
+  'ű' => 'ű',
+  'Ų' => 'Ų',
+  'ų' => 'ų',
+  'Ŵ' => 'Ŵ',
+  'ŵ' => 'ŵ',
+  'Ŷ' => 'Ŷ',
+  'ŷ' => 'ŷ',
+  'Ÿ' => 'Ÿ',
+  'Ź' => 'Ź',
+  'ź' => 'ź',
+  'Ż' => 'Ż',
+  'ż' => 'ż',
+  'Ž' => 'Ž',
+  'ž' => 'ž',
+  'Ơ' => 'Ơ',
+  'ơ' => 'ơ',
+  'Ư' => 'Ư',
+  'ư' => 'ư',
+  'Ǎ' => 'Ǎ',
+  'ǎ' => 'ǎ',
+  'Ǐ' => 'Ǐ',
+  'ǐ' => 'ǐ',
+  'Ǒ' => 'Ǒ',
+  'ǒ' => 'ǒ',
+  'Ǔ' => 'Ǔ',
+  'ǔ' => 'ǔ',
+  'Ǖ' => 'Ǖ',
+  'ǖ' => 'ǖ',
+  'Ǘ' => 'Ǘ',
+  'ǘ' => 'ǘ',
+  'Ǚ' => 'Ǚ',
+  'ǚ' => 'ǚ',
+  'Ǜ' => 'Ǜ',
+  'ǜ' => 'ǜ',
+  'Ǟ' => 'Ǟ',
+  'ǟ' => 'ǟ',
+  'Ǡ' => 'Ǡ',
+  'ǡ' => 'ǡ',
+  'Ǣ' => 'Ǣ',
+  'ǣ' => 'ǣ',
+  'Ǧ' => 'Ǧ',
+  'ǧ' => 'ǧ',
+  'Ǩ' => 'Ǩ',
+  'ǩ' => 'ǩ',
+  'Ǫ' => 'Ǫ',
+  'ǫ' => 'ǫ',
+  'Ǭ' => 'Ǭ',
+  'ǭ' => 'ǭ',
+  'Ǯ' => 'Ǯ',
+  'ǯ' => 'ǯ',
+  'ǰ' => 'ǰ',
+  'Ǵ' => 'Ǵ',
+  'ǵ' => 'ǵ',
+  'Ǹ' => 'Ǹ',
+  'ǹ' => 'ǹ',
+  'Ǻ' => 'Ǻ',
+  'ǻ' => 'ǻ',
+  'Ǽ' => 'Ǽ',
+  'ǽ' => 'ǽ',
+  'Ǿ' => 'Ǿ',
+  'ǿ' => 'ǿ',
+  'Ȁ' => 'Ȁ',
+  'ȁ' => 'ȁ',
+  'Ȃ' => 'Ȃ',
+  'ȃ' => 'ȃ',
+  'Ȅ' => 'Ȅ',
+  'ȅ' => 'ȅ',
+  'Ȇ' => 'Ȇ',
+  'ȇ' => 'ȇ',
+  'Ȉ' => 'Ȉ',
+  'ȉ' => 'ȉ',
+  'Ȋ' => 'Ȋ',
+  'ȋ' => 'ȋ',
+  'Ȍ' => 'Ȍ',
+  'ȍ' => 'ȍ',
+  'Ȏ' => 'Ȏ',
+  'ȏ' => 'ȏ',
+  'Ȑ' => 'Ȑ',
+  'ȑ' => 'ȑ',
+  'Ȓ' => 'Ȓ',
+  'ȓ' => 'ȓ',
+  'Ȕ' => 'Ȕ',
+  'ȕ' => 'ȕ',
+  'Ȗ' => 'Ȗ',
+  'ȗ' => 'ȗ',
+  'Ș' => 'Ș',
+  'ș' => 'ș',
+  'Ț' => 'Ț',
+  'ț' => 'ț',
+  'Ȟ' => 'Ȟ',
+  'ȟ' => 'ȟ',
+  'Ȧ' => 'Ȧ',
+  'ȧ' => 'ȧ',
+  'Ȩ' => 'Ȩ',
+  'ȩ' => 'ȩ',
+  'Ȫ' => 'Ȫ',
+  'ȫ' => 'ȫ',
+  'Ȭ' => 'Ȭ',
+  'ȭ' => 'ȭ',
+  'Ȯ' => 'Ȯ',
+  'ȯ' => 'ȯ',
+  'Ȱ' => 'Ȱ',
+  'ȱ' => 'ȱ',
+  'Ȳ' => 'Ȳ',
+  'ȳ' => 'ȳ',
+  '̀' => '̀',
+  '́' => '́',
+  '̓' => '̓',
+  '̈́' => '̈́',
+  'ʹ' => 'ʹ',
+  ';' => ';',
+  '΅' => '΅',
+  'Ά' => 'Ά',
+  '·' => '·',
+  'Έ' => 'Έ',
+  'Ή' => 'Ή',
+  'Ί' => 'Ί',
+  'Ό' => 'Ό',
+  'Ύ' => 'Ύ',
+  'Ώ' => 'Ώ',
+  'ΐ' => 'ΐ',
+  'Ϊ' => 'Ϊ',
+  'Ϋ' => 'Ϋ',
+  'ά' => 'ά',
+  'έ' => 'έ',
+  'ή' => 'ή',
+  'ί' => 'ί',
+  'ΰ' => 'ΰ',
+  'ϊ' => 'ϊ',
+  'ϋ' => 'ϋ',
+  'ό' => 'ό',
+  'ύ' => 'ύ',
+  'ώ' => 'ώ',
+  'ϓ' => 'ϓ',
+  'ϔ' => 'ϔ',
+  'Ѐ' => 'Ѐ',
+  'Ё' => 'Ё',
+  'Ѓ' => 'Ѓ',
+  'Ї' => 'Ї',
+  'Ќ' => 'Ќ',
+  'Ѝ' => 'Ѝ',
+  'Ў' => 'Ў',
+  'Й' => 'Й',
+  'й' => 'й',
+  'ѐ' => 'ѐ',
+  'ё' => 'ё',
+  'ѓ' => 'ѓ',
+  'ї' => 'ї',
+  'ќ' => 'ќ',
+  'ѝ' => 'ѝ',
+  'ў' => 'ў',
+  'Ѷ' => 'Ѷ',
+  'ѷ' => 'ѷ',
+  'Ӂ' => 'Ӂ',
+  'ӂ' => 'ӂ',
+  'Ӑ' => 'Ӑ',
+  'ӑ' => 'ӑ',
+  'Ӓ' => 'Ӓ',
+  'ӓ' => 'ӓ',
+  'Ӗ' => 'Ӗ',
+  'ӗ' => 'ӗ',
+  'Ӛ' => 'Ӛ',
+  'ӛ' => 'ӛ',
+  'Ӝ' => 'Ӝ',
+  'ӝ' => 'ӝ',
+  'Ӟ' => 'Ӟ',
+  'ӟ' => 'ӟ',
+  'Ӣ' => 'Ӣ',
+  'ӣ' => 'ӣ',
+  'Ӥ' => 'Ӥ',
+  'ӥ' => 'ӥ',
+  'Ӧ' => 'Ӧ',
+  'ӧ' => 'ӧ',
+  'Ӫ' => 'Ӫ',
+  'ӫ' => 'ӫ',
+  'Ӭ' => 'Ӭ',
+  'ӭ' => 'ӭ',
+  'Ӯ' => 'Ӯ',
+  'ӯ' => 'ӯ',
+  'Ӱ' => 'Ӱ',
+  'ӱ' => 'ӱ',
+  'Ӳ' => 'Ӳ',
+  'ӳ' => 'ӳ',
+  'Ӵ' => 'Ӵ',
+  'ӵ' => 'ӵ',
+  'Ӹ' => 'Ӹ',
+  'ӹ' => 'ӹ',
+  'آ' => 'آ',
+  'أ' => 'أ',
+  'ؤ' => 'ؤ',
+  'إ' => 'إ',
+  'ئ' => 'ئ',
+  'ۀ' => 'ۀ',
+  'ۂ' => 'ۂ',
+  'ۓ' => 'ۓ',
+  'ऩ' => 'ऩ',
+  'ऱ' => 'ऱ',
+  'ऴ' => 'ऴ',
+  'क़' => 'क़',
+  'ख़' => 'ख़',
+  'ग़' => 'ग़',
+  'ज़' => 'ज़',
+  'ड़' => 'ड़',
+  'ढ़' => 'ढ़',
+  'फ़' => 'फ़',
+  'य़' => 'य़',
+  'ো' => 'ো',
+  'ৌ' => 'ৌ',
+  'ড়' => 'ড়',
+  'ঢ়' => 'ঢ়',
+  'য়' => 'য়',
+  'ਲ਼' => 'ਲ਼',
+  'ਸ਼' => 'ਸ਼',
+  'ਖ਼' => 'ਖ਼',
+  'ਗ਼' => 'ਗ਼',
+  'ਜ਼' => 'ਜ਼',
+  'ਫ਼' => 'ਫ਼',
+  'ୈ' => 'ୈ',
+  'ୋ' => 'ୋ',
+  'ୌ' => 'ୌ',
+  'ଡ଼' => 'ଡ଼',
+  'ଢ଼' => 'ଢ଼',
+  'ஔ' => 'ஔ',
+  'ொ' => 'ொ',
+  'ோ' => 'ோ',
+  'ௌ' => 'ௌ',
+  'ై' => 'ై',
+  'ೀ' => 'ೀ',
+  'ೇ' => 'ೇ',
+  'ೈ' => 'ೈ',
+  'ೊ' => 'ೊ',
+  'ೋ' => 'ೋ',
+  'ൊ' => 'ൊ',
+  'ോ' => 'ോ',
+  'ൌ' => 'ൌ',
+  'ේ' => 'ේ',
+  'ො' => 'ො',
+  'ෝ' => 'ෝ',
+  'ෞ' => 'ෞ',
+  'གྷ' => 'གྷ',
+  'ཌྷ' => 'ཌྷ',
+  'དྷ' => 'དྷ',
+  'བྷ' => 'བྷ',
+  'ཛྷ' => 'ཛྷ',
+  'ཀྵ' => 'ཀྵ',
+  'ཱི' => 'ཱི',
+  'ཱུ' => 'ཱུ',
+  'ྲྀ' => 'ྲྀ',
+  'ླྀ' => 'ླྀ',
+  'ཱྀ' => 'ཱྀ',
+  'ྒྷ' => 'ྒྷ',
+  'ྜྷ' => 'ྜྷ',
+  'ྡྷ' => 'ྡྷ',
+  'ྦྷ' => 'ྦྷ',
+  'ྫྷ' => 'ྫྷ',
+  'ྐྵ' => 'ྐྵ',
+  'ဦ' => 'ဦ',
+  'ᬆ' => 'ᬆ',
+  'ᬈ' => 'ᬈ',
+  'ᬊ' => 'ᬊ',
+  'ᬌ' => 'ᬌ',
+  'ᬎ' => 'ᬎ',
+  'ᬒ' => 'ᬒ',
+  'ᬻ' => 'ᬻ',
+  'ᬽ' => 'ᬽ',
+  'ᭀ' => 'ᭀ',
+  'ᭁ' => 'ᭁ',
+  'ᭃ' => 'ᭃ',
+  'Ḁ' => 'Ḁ',
+  'ḁ' => 'ḁ',
+  'Ḃ' => 'Ḃ',
+  'ḃ' => 'ḃ',
+  'Ḅ' => 'Ḅ',
+  'ḅ' => 'ḅ',
+  'Ḇ' => 'Ḇ',
+  'ḇ' => 'ḇ',
+  'Ḉ' => 'Ḉ',
+  'ḉ' => 'ḉ',
+  'Ḋ' => 'Ḋ',
+  'ḋ' => 'ḋ',
+  'Ḍ' => 'Ḍ',
+  'ḍ' => 'ḍ',
+  'Ḏ' => 'Ḏ',
+  'ḏ' => 'ḏ',
+  'Ḑ' => 'Ḑ',
+  'ḑ' => 'ḑ',
+  'Ḓ' => 'Ḓ',
+  'ḓ' => 'ḓ',
+  'Ḕ' => 'Ḕ',
+  'ḕ' => 'ḕ',
+  'Ḗ' => 'Ḗ',
+  'ḗ' => 'ḗ',
+  'Ḙ' => 'Ḙ',
+  'ḙ' => 'ḙ',
+  'Ḛ' => 'Ḛ',
+  'ḛ' => 'ḛ',
+  'Ḝ' => 'Ḝ',
+  'ḝ' => 'ḝ',
+  'Ḟ' => 'Ḟ',
+  'ḟ' => 'ḟ',
+  'Ḡ' => 'Ḡ',
+  'ḡ' => 'ḡ',
+  'Ḣ' => 'Ḣ',
+  'ḣ' => 'ḣ',
+  'Ḥ' => 'Ḥ',
+  'ḥ' => 'ḥ',
+  'Ḧ' => 'Ḧ',
+  'ḧ' => 'ḧ',
+  'Ḩ' => 'Ḩ',
+  'ḩ' => 'ḩ',
+  'Ḫ' => 'Ḫ',
+  'ḫ' => 'ḫ',
+  'Ḭ' => 'Ḭ',
+  'ḭ' => 'ḭ',
+  'Ḯ' => 'Ḯ',
+  'ḯ' => 'ḯ',
+  'Ḱ' => 'Ḱ',
+  'ḱ' => 'ḱ',
+  'Ḳ' => 'Ḳ',
+  'ḳ' => 'ḳ',
+  'Ḵ' => 'Ḵ',
+  'ḵ' => 'ḵ',
+  'Ḷ' => 'Ḷ',
+  'ḷ' => 'ḷ',
+  'Ḹ' => 'Ḹ',
+  'ḹ' => 'ḹ',
+  'Ḻ' => 'Ḻ',
+  'ḻ' => 'ḻ',
+  'Ḽ' => 'Ḽ',
+  'ḽ' => 'ḽ',
+  'Ḿ' => 'Ḿ',
+  'ḿ' => 'ḿ',
+  'Ṁ' => 'Ṁ',
+  'ṁ' => 'ṁ',
+  'Ṃ' => 'Ṃ',
+  'ṃ' => 'ṃ',
+  'Ṅ' => 'Ṅ',
+  'ṅ' => 'ṅ',
+  'Ṇ' => 'Ṇ',
+  'ṇ' => 'ṇ',
+  'Ṉ' => 'Ṉ',
+  'ṉ' => 'ṉ',
+  'Ṋ' => 'Ṋ',
+  'ṋ' => 'ṋ',
+  'Ṍ' => 'Ṍ',
+  'ṍ' => 'ṍ',
+  'Ṏ' => 'Ṏ',
+  'ṏ' => 'ṏ',
+  'Ṑ' => 'Ṑ',
+  'ṑ' => 'ṑ',
+  'Ṓ' => 'Ṓ',
+  'ṓ' => 'ṓ',
+  'Ṕ' => 'Ṕ',
+  'ṕ' => 'ṕ',
+  'Ṗ' => 'Ṗ',
+  'ṗ' => 'ṗ',
+  'Ṙ' => 'Ṙ',
+  'ṙ' => 'ṙ',
+  'Ṛ' => 'Ṛ',
+  'ṛ' => 'ṛ',
+  'Ṝ' => 'Ṝ',
+  'ṝ' => 'ṝ',
+  'Ṟ' => 'Ṟ',
+  'ṟ' => 'ṟ',
+  'Ṡ' => 'Ṡ',
+  'ṡ' => 'ṡ',
+  'Ṣ' => 'Ṣ',
+  'ṣ' => 'ṣ',
+  'Ṥ' => 'Ṥ',
+  'ṥ' => 'ṥ',
+  'Ṧ' => 'Ṧ',
+  'ṧ' => 'ṧ',
+  'Ṩ' => 'Ṩ',
+  'ṩ' => 'ṩ',
+  'Ṫ' => 'Ṫ',
+  'ṫ' => 'ṫ',
+  'Ṭ' => 'Ṭ',
+  'ṭ' => 'ṭ',
+  'Ṯ' => 'Ṯ',
+  'ṯ' => 'ṯ',
+  'Ṱ' => 'Ṱ',
+  'ṱ' => 'ṱ',
+  'Ṳ' => 'Ṳ',
+  'ṳ' => 'ṳ',
+  'Ṵ' => 'Ṵ',
+  'ṵ' => 'ṵ',
+  'Ṷ' => 'Ṷ',
+  'ṷ' => 'ṷ',
+  'Ṹ' => 'Ṹ',
+  'ṹ' => 'ṹ',
+  'Ṻ' => 'Ṻ',
+  'ṻ' => 'ṻ',
+  'Ṽ' => 'Ṽ',
+  'ṽ' => 'ṽ',
+  'Ṿ' => 'Ṿ',
+  'ṿ' => 'ṿ',
+  'Ẁ' => 'Ẁ',
+  'ẁ' => 'ẁ',
+  'Ẃ' => 'Ẃ',
+  'ẃ' => 'ẃ',
+  'Ẅ' => 'Ẅ',
+  'ẅ' => 'ẅ',
+  'Ẇ' => 'Ẇ',
+  'ẇ' => 'ẇ',
+  'Ẉ' => 'Ẉ',
+  'ẉ' => 'ẉ',
+  'Ẋ' => 'Ẋ',
+  'ẋ' => 'ẋ',
+  'Ẍ' => 'Ẍ',
+  'ẍ' => 'ẍ',
+  'Ẏ' => 'Ẏ',
+  'ẏ' => 'ẏ',
+  'Ẑ' => 'Ẑ',
+  'ẑ' => 'ẑ',
+  'Ẓ' => 'Ẓ',
+  'ẓ' => 'ẓ',
+  'Ẕ' => 'Ẕ',
+  'ẕ' => 'ẕ',
+  'ẖ' => 'ẖ',
+  'ẗ' => 'ẗ',
+  'ẘ' => 'ẘ',
+  'ẙ' => 'ẙ',
+  'ẛ' => 'ẛ',
+  'Ạ' => 'Ạ',
+  'ạ' => 'ạ',
+  'Ả' => 'Ả',
+  'ả' => 'ả',
+  'Ấ' => 'Ấ',
+  'ấ' => 'ấ',
+  'Ầ' => 'Ầ',
+  'ầ' => 'ầ',
+  'Ẩ' => 'Ẩ',
+  'ẩ' => 'ẩ',
+  'Ẫ' => 'Ẫ',
+  'ẫ' => 'ẫ',
+  'Ậ' => 'Ậ',
+  'ậ' => 'ậ',
+  'Ắ' => 'Ắ',
+  'ắ' => 'ắ',
+  'Ằ' => 'Ằ',
+  'ằ' => 'ằ',
+  'Ẳ' => 'Ẳ',
+  'ẳ' => 'ẳ',
+  'Ẵ' => 'Ẵ',
+  'ẵ' => 'ẵ',
+  'Ặ' => 'Ặ',
+  'ặ' => 'ặ',
+  'Ẹ' => 'Ẹ',
+  'ẹ' => 'ẹ',
+  'Ẻ' => 'Ẻ',
+  'ẻ' => 'ẻ',
+  'Ẽ' => 'Ẽ',
+  'ẽ' => 'ẽ',
+  'Ế' => 'Ế',
+  'ế' => 'ế',
+  'Ề' => 'Ề',
+  'ề' => 'ề',
+  'Ể' => 'Ể',
+  'ể' => 'ể',
+  'Ễ' => 'Ễ',
+  'ễ' => 'ễ',
+  'Ệ' => 'Ệ',
+  'ệ' => 'ệ',
+  'Ỉ' => 'Ỉ',
+  'ỉ' => 'ỉ',
+  'Ị' => 'Ị',
+  'ị' => 'ị',
+  'Ọ' => 'Ọ',
+  'ọ' => 'ọ',
+  'Ỏ' => 'Ỏ',
+  'ỏ' => 'ỏ',
+  'Ố' => 'Ố',
+  'ố' => 'ố',
+  'Ồ' => 'Ồ',
+  'ồ' => 'ồ',
+  'Ổ' => 'Ổ',
+  'ổ' => 'ổ',
+  'Ỗ' => 'Ỗ',
+  'ỗ' => 'ỗ',
+  'Ộ' => 'Ộ',
+  'ộ' => 'ộ',
+  'Ớ' => 'Ớ',
+  'ớ' => 'ớ',
+  'Ờ' => 'Ờ',
+  'ờ' => 'ờ',
+  'Ở' => 'Ở',
+  'ở' => 'ở',
+  'Ỡ' => 'Ỡ',
+  'ỡ' => 'ỡ',
+  'Ợ' => 'Ợ',
+  'ợ' => 'ợ',
+  'Ụ' => 'Ụ',
+  'ụ' => 'ụ',
+  'Ủ' => 'Ủ',
+  'ủ' => 'ủ',
+  'Ứ' => 'Ứ',
+  'ứ' => 'ứ',
+  'Ừ' => 'Ừ',
+  'ừ' => 'ừ',
+  'Ử' => 'Ử',
+  'ử' => 'ử',
+  'Ữ' => 'Ữ',
+  'ữ' => 'ữ',
+  'Ự' => 'Ự',
+  'ự' => 'ự',
+  'Ỳ' => 'Ỳ',
+  'ỳ' => 'ỳ',
+  'Ỵ' => 'Ỵ',
+  'ỵ' => 'ỵ',
+  'Ỷ' => 'Ỷ',
+  'ỷ' => 'ỷ',
+  'Ỹ' => 'Ỹ',
+  'ỹ' => 'ỹ',
+  'ἀ' => 'ἀ',
+  'ἁ' => 'ἁ',
+  'ἂ' => 'ἂ',
+  'ἃ' => 'ἃ',
+  'ἄ' => 'ἄ',
+  'ἅ' => 'ἅ',
+  'ἆ' => 'ἆ',
+  'ἇ' => 'ἇ',
+  'Ἀ' => 'Ἀ',
+  'Ἁ' => 'Ἁ',
+  'Ἂ' => 'Ἂ',
+  'Ἃ' => 'Ἃ',
+  'Ἄ' => 'Ἄ',
+  'Ἅ' => 'Ἅ',
+  'Ἆ' => 'Ἆ',
+  'Ἇ' => 'Ἇ',
+  'ἐ' => 'ἐ',
+  'ἑ' => 'ἑ',
+  'ἒ' => 'ἒ',
+  'ἓ' => 'ἓ',
+  'ἔ' => 'ἔ',
+  'ἕ' => 'ἕ',
+  'Ἐ' => 'Ἐ',
+  'Ἑ' => 'Ἑ',
+  'Ἒ' => 'Ἒ',
+  'Ἓ' => 'Ἓ',
+  'Ἔ' => 'Ἔ',
+  'Ἕ' => 'Ἕ',
+  'ἠ' => 'ἠ',
+  'ἡ' => 'ἡ',
+  'ἢ' => 'ἢ',
+  'ἣ' => 'ἣ',
+  'ἤ' => 'ἤ',
+  'ἥ' => 'ἥ',
+  'ἦ' => 'ἦ',
+  'ἧ' => 'ἧ',
+  'Ἠ' => 'Ἠ',
+  'Ἡ' => 'Ἡ',
+  'Ἢ' => 'Ἢ',
+  'Ἣ' => 'Ἣ',
+  'Ἤ' => 'Ἤ',
+  'Ἥ' => 'Ἥ',
+  'Ἦ' => 'Ἦ',
+  'Ἧ' => 'Ἧ',
+  'ἰ' => 'ἰ',
+  'ἱ' => 'ἱ',
+  'ἲ' => 'ἲ',
+  'ἳ' => 'ἳ',
+  'ἴ' => 'ἴ',
+  'ἵ' => 'ἵ',
+  'ἶ' => 'ἶ',
+  'ἷ' => 'ἷ',
+  'Ἰ' => 'Ἰ',
+  'Ἱ' => 'Ἱ',
+  'Ἲ' => 'Ἲ',
+  'Ἳ' => 'Ἳ',
+  'Ἴ' => 'Ἴ',
+  'Ἵ' => 'Ἵ',
+  'Ἶ' => 'Ἶ',
+  'Ἷ' => 'Ἷ',
+  'ὀ' => 'ὀ',
+  'ὁ' => 'ὁ',
+  'ὂ' => 'ὂ',
+  'ὃ' => 'ὃ',
+  'ὄ' => 'ὄ',
+  'ὅ' => 'ὅ',
+  'Ὀ' => 'Ὀ',
+  'Ὁ' => 'Ὁ',
+  'Ὂ' => 'Ὂ',
+  'Ὃ' => 'Ὃ',
+  'Ὄ' => 'Ὄ',
+  'Ὅ' => 'Ὅ',
+  'ὐ' => 'ὐ',
+  'ὑ' => 'ὑ',
+  'ὒ' => 'ὒ',
+  'ὓ' => 'ὓ',
+  'ὔ' => 'ὔ',
+  'ὕ' => 'ὕ',
+  'ὖ' => 'ὖ',
+  'ὗ' => 'ὗ',
+  'Ὑ' => 'Ὑ',
+  'Ὓ' => 'Ὓ',
+  'Ὕ' => 'Ὕ',
+  'Ὗ' => 'Ὗ',
+  'ὠ' => 'ὠ',
+  'ὡ' => 'ὡ',
+  'ὢ' => 'ὢ',
+  'ὣ' => 'ὣ',
+  'ὤ' => 'ὤ',
+  'ὥ' => 'ὥ',
+  'ὦ' => 'ὦ',
+  'ὧ' => 'ὧ',
+  'Ὠ' => 'Ὠ',
+  'Ὡ' => 'Ὡ',
+  'Ὢ' => 'Ὢ',
+  'Ὣ' => 'Ὣ',
+  'Ὤ' => 'Ὤ',
+  'Ὥ' => 'Ὥ',
+  'Ὦ' => 'Ὦ',
+  'Ὧ' => 'Ὧ',
+  'ὰ' => 'ὰ',
+  'ά' => 'ά',
+  'ὲ' => 'ὲ',
+  'έ' => 'έ',
+  'ὴ' => 'ὴ',
+  'ή' => 'ή',
+  'ὶ' => 'ὶ',
+  'ί' => 'ί',
+  'ὸ' => 'ὸ',
+  'ό' => 'ό',
+  'ὺ' => 'ὺ',
+  'ύ' => 'ύ',
+  'ὼ' => 'ὼ',
+  'ώ' => 'ώ',
+  'ᾀ' => 'ᾀ',
+  'ᾁ' => 'ᾁ',
+  'ᾂ' => 'ᾂ',
+  'ᾃ' => 'ᾃ',
+  'ᾄ' => 'ᾄ',
+  'ᾅ' => 'ᾅ',
+  'ᾆ' => 'ᾆ',
+  'ᾇ' => 'ᾇ',
+  'ᾈ' => 'ᾈ',
+  'ᾉ' => 'ᾉ',
+  'ᾊ' => 'ᾊ',
+  'ᾋ' => 'ᾋ',
+  'ᾌ' => 'ᾌ',
+  'ᾍ' => 'ᾍ',
+  'ᾎ' => 'ᾎ',
+  'ᾏ' => 'ᾏ',
+  'ᾐ' => 'ᾐ',
+  'ᾑ' => 'ᾑ',
+  'ᾒ' => 'ᾒ',
+  'ᾓ' => 'ᾓ',
+  'ᾔ' => 'ᾔ',
+  'ᾕ' => 'ᾕ',
+  'ᾖ' => 'ᾖ',
+  'ᾗ' => 'ᾗ',
+  'ᾘ' => 'ᾘ',
+  'ᾙ' => 'ᾙ',
+  'ᾚ' => 'ᾚ',
+  'ᾛ' => 'ᾛ',
+  'ᾜ' => 'ᾜ',
+  'ᾝ' => 'ᾝ',
+  'ᾞ' => 'ᾞ',
+  'ᾟ' => 'ᾟ',
+  'ᾠ' => 'ᾠ',
+  'ᾡ' => 'ᾡ',
+  'ᾢ' => 'ᾢ',
+  'ᾣ' => 'ᾣ',
+  'ᾤ' => 'ᾤ',
+  'ᾥ' => 'ᾥ',
+  'ᾦ' => 'ᾦ',
+  'ᾧ' => 'ᾧ',
+  'ᾨ' => 'ᾨ',
+  'ᾩ' => 'ᾩ',
+  'ᾪ' => 'ᾪ',
+  'ᾫ' => 'ᾫ',
+  'ᾬ' => 'ᾬ',
+  'ᾭ' => 'ᾭ',
+  'ᾮ' => 'ᾮ',
+  'ᾯ' => 'ᾯ',
+  'ᾰ' => 'ᾰ',
+  'ᾱ' => 'ᾱ',
+  'ᾲ' => 'ᾲ',
+  'ᾳ' => 'ᾳ',
+  'ᾴ' => 'ᾴ',
+  'ᾶ' => 'ᾶ',
+  'ᾷ' => 'ᾷ',
+  'Ᾰ' => 'Ᾰ',
+  'Ᾱ' => 'Ᾱ',
+  'Ὰ' => 'Ὰ',
+  'Ά' => 'Ά',
+  'ᾼ' => 'ᾼ',
+  'ι' => 'ι',
+  '῁' => '῁',
+  'ῂ' => 'ῂ',
+  'ῃ' => 'ῃ',
+  'ῄ' => 'ῄ',
+  'ῆ' => 'ῆ',
+  'ῇ' => 'ῇ',
+  'Ὲ' => 'Ὲ',
+  'Έ' => 'Έ',
+  'Ὴ' => 'Ὴ',
+  'Ή' => 'Ή',
+  'ῌ' => 'ῌ',
+  '῍' => '῍',
+  '῎' => '῎',
+  '῏' => '῏',
+  'ῐ' => 'ῐ',
+  'ῑ' => 'ῑ',
+  'ῒ' => 'ῒ',
+  'ΐ' => 'ΐ',
+  'ῖ' => 'ῖ',
+  'ῗ' => 'ῗ',
+  'Ῐ' => 'Ῐ',
+  'Ῑ' => 'Ῑ',
+  'Ὶ' => 'Ὶ',
+  'Ί' => 'Ί',
+  '῝' => '῝',
+  '῞' => '῞',
+  '῟' => '῟',
+  'ῠ' => 'ῠ',
+  'ῡ' => 'ῡ',
+  'ῢ' => 'ῢ',
+  'ΰ' => 'ΰ',
+  'ῤ' => 'ῤ',
+  'ῥ' => 'ῥ',
+  'ῦ' => 'ῦ',
+  'ῧ' => 'ῧ',
+  'Ῠ' => 'Ῠ',
+  'Ῡ' => 'Ῡ',
+  'Ὺ' => 'Ὺ',
+  'Ύ' => 'Ύ',
+  'Ῥ' => 'Ῥ',
+  '῭' => '῭',
+  '΅' => '΅',
+  '`' => '`',
+  'ῲ' => 'ῲ',
+  'ῳ' => 'ῳ',
+  'ῴ' => 'ῴ',
+  'ῶ' => 'ῶ',
+  'ῷ' => 'ῷ',
+  'Ὸ' => 'Ὸ',
+  'Ό' => 'Ό',
+  'Ὼ' => 'Ὼ',
+  'Ώ' => 'Ώ',
+  'ῼ' => 'ῼ',
+  '´' => '´',
+  ' ' => ' ',
+  ' ' => ' ',
+  'Ω' => 'Ω',
+  'K' => 'K',
+  'Å' => 'Å',
+  '↚' => '↚',
+  '↛' => '↛',
+  '↮' => '↮',
+  '⇍' => '⇍',
+  '⇎' => '⇎',
+  '⇏' => '⇏',
+  '∄' => '∄',
+  '∉' => '∉',
+  '∌' => '∌',
+  '∤' => '∤',
+  '∦' => '∦',
+  '≁' => '≁',
+  '≄' => '≄',
+  '≇' => '≇',
+  '≉' => '≉',
+  '≠' => '≠',
+  '≢' => '≢',
+  '≭' => '≭',
+  '≮' => '≮',
+  '≯' => '≯',
+  '≰' => '≰',
+  '≱' => '≱',
+  '≴' => '≴',
+  '≵' => '≵',
+  '≸' => '≸',
+  '≹' => '≹',
+  '⊀' => '⊀',
+  '⊁' => '⊁',
+  '⊄' => '⊄',
+  '⊅' => '⊅',
+  '⊈' => '⊈',
+  '⊉' => '⊉',
+  '⊬' => '⊬',
+  '⊭' => '⊭',
+  '⊮' => '⊮',
+  '⊯' => '⊯',
+  '⋠' => '⋠',
+  '⋡' => '⋡',
+  '⋢' => '⋢',
+  '⋣' => '⋣',
+  '⋪' => '⋪',
+  '⋫' => '⋫',
+  '⋬' => '⋬',
+  '⋭' => '⋭',
+  '〈' => '〈',
+  '〉' => '〉',
+  '⫝̸' => '⫝̸',
+  'が' => 'が',
+  'ぎ' => 'ぎ',
+  'ぐ' => 'ぐ',
+  'げ' => 'げ',
+  'ご' => 'ご',
+  'ざ' => 'ざ',
+  'じ' => 'じ',
+  'ず' => 'ず',
+  'ぜ' => 'ぜ',
+  'ぞ' => 'ぞ',
+  'だ' => 'だ',
+  'ぢ' => 'ぢ',
+  'づ' => 'づ',
+  'で' => 'で',
+  'ど' => 'ど',
+  'ば' => 'ば',
+  'ぱ' => 'ぱ',
+  'び' => 'び',
+  'ぴ' => 'ぴ',
+  'ぶ' => 'ぶ',
+  'ぷ' => 'ぷ',
+  'べ' => 'べ',
+  'ぺ' => 'ぺ',
+  'ぼ' => 'ぼ',
+  'ぽ' => 'ぽ',
+  'ゔ' => 'ゔ',
+  'ゞ' => 'ゞ',
+  'ガ' => 'ガ',
+  'ギ' => 'ギ',
+  'グ' => 'グ',
+  'ゲ' => 'ゲ',
+  'ゴ' => 'ゴ',
+  'ザ' => 'ザ',
+  'ジ' => 'ジ',
+  'ズ' => 'ズ',
+  'ゼ' => 'ゼ',
+  'ゾ' => 'ゾ',
+  'ダ' => 'ダ',
+  'ヂ' => 'ヂ',
+  'ヅ' => 'ヅ',
+  'デ' => 'デ',
+  'ド' => 'ド',
+  'バ' => 'バ',
+  'パ' => 'パ',
+  'ビ' => 'ビ',
+  'ピ' => 'ピ',
+  'ブ' => 'ブ',
+  'プ' => 'プ',
+  'ベ' => 'ベ',
+  'ペ' => 'ペ',
+  'ボ' => 'ボ',
+  'ポ' => 'ポ',
+  'ヴ' => 'ヴ',
+  'ヷ' => 'ヷ',
+  'ヸ' => 'ヸ',
+  'ヹ' => 'ヹ',
+  'ヺ' => 'ヺ',
+  'ヾ' => 'ヾ',
+  '豈' => '豈',
+  '更' => '更',
+  '車' => '車',
+  '賈' => '賈',
+  '滑' => '滑',
+  '串' => '串',
+  '句' => '句',
+  '龜' => '龜',
+  '龜' => '龜',
+  '契' => '契',
+  '金' => '金',
+  '喇' => '喇',
+  '奈' => '奈',
+  '懶' => '懶',
+  '癩' => '癩',
+  '羅' => '羅',
+  '蘿' => '蘿',
+  '螺' => '螺',
+  '裸' => '裸',
+  '邏' => '邏',
+  '樂' => '樂',
+  '洛' => '洛',
+  '烙' => '烙',
+  '珞' => '珞',
+  '落' => '落',
+  '酪' => '酪',
+  '駱' => '駱',
+  '亂' => '亂',
+  '卵' => '卵',
+  '欄' => '欄',
+  '爛' => '爛',
+  '蘭' => '蘭',
+  '鸞' => '鸞',
+  '嵐' => '嵐',
+  '濫' => '濫',
+  '藍' => '藍',
+  '襤' => '襤',
+  '拉' => '拉',
+  '臘' => '臘',
+  '蠟' => '蠟',
+  '廊' => '廊',
+  '朗' => '朗',
+  '浪' => '浪',
+  '狼' => '狼',
+  '郎' => '郎',
+  '來' => '來',
+  '冷' => '冷',
+  '勞' => '勞',
+  '擄' => '擄',
+  '櫓' => '櫓',
+  '爐' => '爐',
+  '盧' => '盧',
+  '老' => '老',
+  '蘆' => '蘆',
+  '虜' => '虜',
+  '路' => '路',
+  '露' => '露',
+  '魯' => '魯',
+  '鷺' => '鷺',
+  '碌' => '碌',
+  '祿' => '祿',
+  '綠' => '綠',
+  '菉' => '菉',
+  '錄' => '錄',
+  '鹿' => '鹿',
+  '論' => '論',
+  '壟' => '壟',
+  '弄' => '弄',
+  '籠' => '籠',
+  '聾' => '聾',
+  '牢' => '牢',
+  '磊' => '磊',
+  '賂' => '賂',
+  '雷' => '雷',
+  '壘' => '壘',
+  '屢' => '屢',
+  '樓' => '樓',
+  '淚' => '淚',
+  '漏' => '漏',
+  '累' => '累',
+  '縷' => '縷',
+  '陋' => '陋',
+  '勒' => '勒',
+  '肋' => '肋',
+  '凜' => '凜',
+  '凌' => '凌',
+  '稜' => '稜',
+  '綾' => '綾',
+  '菱' => '菱',
+  '陵' => '陵',
+  '讀' => '讀',
+  '拏' => '拏',
+  '樂' => '樂',
+  '諾' => '諾',
+  '丹' => '丹',
+  '寧' => '寧',
+  '怒' => '怒',
+  '率' => '率',
+  '異' => '異',
+  '北' => '北',
+  '磻' => '磻',
+  '便' => '便',
+  '復' => '復',
+  '不' => '不',
+  '泌' => '泌',
+  '數' => '數',
+  '索' => '索',
+  '參' => '參',
+  '塞' => '塞',
+  '省' => '省',
+  '葉' => '葉',
+  '說' => '說',
+  '殺' => '殺',
+  '辰' => '辰',
+  '沈' => '沈',
+  '拾' => '拾',
+  '若' => '若',
+  '掠' => '掠',
+  '略' => '略',
+  '亮' => '亮',
+  '兩' => '兩',
+  '凉' => '凉',
+  '梁' => '梁',
+  '糧' => '糧',
+  '良' => '良',
+  '諒' => '諒',
+  '量' => '量',
+  '勵' => '勵',
+  '呂' => '呂',
+  '女' => '女',
+  '廬' => '廬',
+  '旅' => '旅',
+  '濾' => '濾',
+  '礪' => '礪',
+  '閭' => '閭',
+  '驪' => '驪',
+  '麗' => '麗',
+  '黎' => '黎',
+  '力' => '力',
+  '曆' => '曆',
+  '歷' => '歷',
+  '轢' => '轢',
+  '年' => '年',
+  '憐' => '憐',
+  '戀' => '戀',
+  '撚' => '撚',
+  '漣' => '漣',
+  '煉' => '煉',
+  '璉' => '璉',
+  '秊' => '秊',
+  '練' => '練',
+  '聯' => '聯',
+  '輦' => '輦',
+  '蓮' => '蓮',
+  '連' => '連',
+  '鍊' => '鍊',
+  '列' => '列',
+  '劣' => '劣',
+  '咽' => '咽',
+  '烈' => '烈',
+  '裂' => '裂',
+  '說' => '說',
+  '廉' => '廉',
+  '念' => '念',
+  '捻' => '捻',
+  '殮' => '殮',
+  '簾' => '簾',
+  '獵' => '獵',
+  '令' => '令',
+  '囹' => '囹',
+  '寧' => '寧',
+  '嶺' => '嶺',
+  '怜' => '怜',
+  '玲' => '玲',
+  '瑩' => '瑩',
+  '羚' => '羚',
+  '聆' => '聆',
+  '鈴' => '鈴',
+  '零' => '零',
+  '靈' => '靈',
+  '領' => '領',
+  '例' => '例',
+  '禮' => '禮',
+  '醴' => '醴',
+  '隸' => '隸',
+  '惡' => '惡',
+  '了' => '了',
+  '僚' => '僚',
+  '寮' => '寮',
+  '尿' => '尿',
+  '料' => '料',
+  '樂' => '樂',
+  '燎' => '燎',
+  '療' => '療',
+  '蓼' => '蓼',
+  '遼' => '遼',
+  '龍' => '龍',
+  '暈' => '暈',
+  '阮' => '阮',
+  '劉' => '劉',
+  '杻' => '杻',
+  '柳' => '柳',
+  '流' => '流',
+  '溜' => '溜',
+  '琉' => '琉',
+  '留' => '留',
+  '硫' => '硫',
+  '紐' => '紐',
+  '類' => '類',
+  '六' => '六',
+  '戮' => '戮',
+  '陸' => '陸',
+  '倫' => '倫',
+  '崙' => '崙',
+  '淪' => '淪',
+  '輪' => '輪',
+  '律' => '律',
+  '慄' => '慄',
+  '栗' => '栗',
+  '率' => '率',
+  '隆' => '隆',
+  '利' => '利',
+  '吏' => '吏',
+  '履' => '履',
+  '易' => '易',
+  '李' => '李',
+  '梨' => '梨',
+  '泥' => '泥',
+  '理' => '理',
+  '痢' => '痢',
+  '罹' => '罹',
+  '裏' => '裏',
+  '裡' => '裡',
+  '里' => '里',
+  '離' => '離',
+  '匿' => '匿',
+  '溺' => '溺',
+  '吝' => '吝',
+  '燐' => '燐',
+  '璘' => '璘',
+  '藺' => '藺',
+  '隣' => '隣',
+  '鱗' => '鱗',
+  '麟' => '麟',
+  '林' => '林',
+  '淋' => '淋',
+  '臨' => '臨',
+  '立' => '立',
+  '笠' => '笠',
+  '粒' => '粒',
+  '狀' => '狀',
+  '炙' => '炙',
+  '識' => '識',
+  '什' => '什',
+  '茶' => '茶',
+  '刺' => '刺',
+  '切' => '切',
+  '度' => '度',
+  '拓' => '拓',
+  '糖' => '糖',
+  '宅' => '宅',
+  '洞' => '洞',
+  '暴' => '暴',
+  '輻' => '輻',
+  '行' => '行',
+  '降' => '降',
+  '見' => '見',
+  '廓' => '廓',
+  '兀' => '兀',
+  '嗀' => '嗀',
+  '塚' => '塚',
+  '晴' => '晴',
+  '凞' => '凞',
+  '猪' => '猪',
+  '益' => '益',
+  '礼' => '礼',
+  '神' => '神',
+  '祥' => '祥',
+  '福' => '福',
+  '靖' => '靖',
+  '精' => '精',
+  '羽' => '羽',
+  '蘒' => '蘒',
+  '諸' => '諸',
+  '逸' => '逸',
+  '都' => '都',
+  '飯' => '飯',
+  '飼' => '飼',
+  '館' => '館',
+  '鶴' => '鶴',
+  '郞' => '郞',
+  '隷' => '隷',
+  '侮' => '侮',
+  '僧' => '僧',
+  '免' => '免',
+  '勉' => '勉',
+  '勤' => '勤',
+  '卑' => '卑',
+  '喝' => '喝',
+  '嘆' => '嘆',
+  '器' => '器',
+  '塀' => '塀',
+  '墨' => '墨',
+  '層' => '層',
+  '屮' => '屮',
+  '悔' => '悔',
+  '慨' => '慨',
+  '憎' => '憎',
+  '懲' => '懲',
+  '敏' => '敏',
+  '既' => '既',
+  '暑' => '暑',
+  '梅' => '梅',
+  '海' => '海',
+  '渚' => '渚',
+  '漢' => '漢',
+  '煮' => '煮',
+  '爫' => '爫',
+  '琢' => '琢',
+  '碑' => '碑',
+  '社' => '社',
+  '祉' => '祉',
+  '祈' => '祈',
+  '祐' => '祐',
+  '祖' => '祖',
+  '祝' => '祝',
+  '禍' => '禍',
+  '禎' => '禎',
+  '穀' => '穀',
+  '突' => '突',
+  '節' => '節',
+  '練' => '練',
+  '縉' => '縉',
+  '繁' => '繁',
+  '署' => '署',
+  '者' => '者',
+  '臭' => '臭',
+  '艹' => '艹',
+  '艹' => '艹',
+  '著' => '著',
+  '褐' => '褐',
+  '視' => '視',
+  '謁' => '謁',
+  '謹' => '謹',
+  '賓' => '賓',
+  '贈' => '贈',
+  '辶' => '辶',
+  '逸' => '逸',
+  '難' => '難',
+  '響' => '響',
+  '頻' => '頻',
+  '恵' => '恵',
+  '𤋮' => '𤋮',
+  '舘' => '舘',
+  '並' => '並',
+  '况' => '况',
+  '全' => '全',
+  '侀' => '侀',
+  '充' => '充',
+  '冀' => '冀',
+  '勇' => '勇',
+  '勺' => '勺',
+  '喝' => '喝',
+  '啕' => '啕',
+  '喙' => '喙',
+  '嗢' => '嗢',
+  '塚' => '塚',
+  '墳' => '墳',
+  '奄' => '奄',
+  '奔' => '奔',
+  '婢' => '婢',
+  '嬨' => '嬨',
+  '廒' => '廒',
+  '廙' => '廙',
+  '彩' => '彩',
+  '徭' => '徭',
+  '惘' => '惘',
+  '慎' => '慎',
+  '愈' => '愈',
+  '憎' => '憎',
+  '慠' => '慠',
+  '懲' => '懲',
+  '戴' => '戴',
+  '揄' => '揄',
+  '搜' => '搜',
+  '摒' => '摒',
+  '敖' => '敖',
+  '晴' => '晴',
+  '朗' => '朗',
+  '望' => '望',
+  '杖' => '杖',
+  '歹' => '歹',
+  '殺' => '殺',
+  '流' => '流',
+  '滛' => '滛',
+  '滋' => '滋',
+  '漢' => '漢',
+  '瀞' => '瀞',
+  '煮' => '煮',
+  '瞧' => '瞧',
+  '爵' => '爵',
+  '犯' => '犯',
+  '猪' => '猪',
+  '瑱' => '瑱',
+  '甆' => '甆',
+  '画' => '画',
+  '瘝' => '瘝',
+  '瘟' => '瘟',
+  '益' => '益',
+  '盛' => '盛',
+  '直' => '直',
+  '睊' => '睊',
+  '着' => '着',
+  '磌' => '磌',
+  '窱' => '窱',
+  '節' => '節',
+  '类' => '类',
+  '絛' => '絛',
+  '練' => '練',
+  '缾' => '缾',
+  '者' => '者',
+  '荒' => '荒',
+  '華' => '華',
+  '蝹' => '蝹',
+  '襁' => '襁',
+  '覆' => '覆',
+  '視' => '視',
+  '調' => '調',
+  '諸' => '諸',
+  '請' => '請',
+  '謁' => '謁',
+  '諾' => '諾',
+  '諭' => '諭',
+  '謹' => '謹',
+  '變' => '變',
+  '贈' => '贈',
+  '輸' => '輸',
+  '遲' => '遲',
+  '醙' => '醙',
+  '鉶' => '鉶',
+  '陼' => '陼',
+  '難' => '難',
+  '靖' => '靖',
+  '韛' => '韛',
+  '響' => '響',
+  '頋' => '頋',
+  '頻' => '頻',
+  '鬒' => '鬒',
+  '龜' => '龜',
+  '𢡊' => '𢡊',
+  '𢡄' => '𢡄',
+  '𣏕' => '𣏕',
+  '㮝' => '㮝',
+  '䀘' => '䀘',
+  '䀹' => '䀹',
+  '𥉉' => '𥉉',
+  '𥳐' => '𥳐',
+  '𧻓' => '𧻓',
+  '齃' => '齃',
+  '龎' => '龎',
+  'יִ' => 'יִ',
+  'ײַ' => 'ײַ',
+  'שׁ' => 'שׁ',
+  'שׂ' => 'שׂ',
+  'שּׁ' => 'שּׁ',
+  'שּׂ' => 'שּׂ',
+  'אַ' => 'אַ',
+  'אָ' => 'אָ',
+  'אּ' => 'אּ',
+  'בּ' => 'בּ',
+  'גּ' => 'גּ',
+  'דּ' => 'דּ',
+  'הּ' => 'הּ',
+  'וּ' => 'וּ',
+  'זּ' => 'זּ',
+  'טּ' => 'טּ',
+  'יּ' => 'יּ',
+  'ךּ' => 'ךּ',
+  'כּ' => 'כּ',
+  'לּ' => 'לּ',
+  'מּ' => 'מּ',
+  'נּ' => 'נּ',
+  'סּ' => 'סּ',
+  'ףּ' => 'ףּ',
+  'פּ' => 'פּ',
+  'צּ' => 'צּ',
+  'קּ' => 'קּ',
+  'רּ' => 'רּ',
+  'שּ' => 'שּ',
+  'תּ' => 'תּ',
+  'וֹ' => 'וֹ',
+  'בֿ' => 'בֿ',
+  'כֿ' => 'כֿ',
+  'פֿ' => 'פֿ',
+  '𑂚' => '𑂚',
+  '𑂜' => '𑂜',
+  '𑂫' => '𑂫',
+  '𑄮' => '𑄮',
+  '𑄯' => '𑄯',
+  '𑍋' => '𑍋',
+  '𑍌' => '𑍌',
+  '𑒻' => '𑒻',
+  '𑒼' => '𑒼',
+  '𑒾' => '𑒾',
+  '𑖺' => '𑖺',
+  '𑖻' => '𑖻',
+  '𑤸' => '𑤸',
+  '𝅗𝅥' => '𝅗𝅥',
+  '𝅘𝅥' => '𝅘𝅥',
+  '𝅘𝅥𝅮' => '𝅘𝅥𝅮',
+  '𝅘𝅥𝅯' => '𝅘𝅥𝅯',
+  '𝅘𝅥𝅰' => '𝅘𝅥𝅰',
+  '𝅘𝅥𝅱' => '𝅘𝅥𝅱',
+  '𝅘𝅥𝅲' => '𝅘𝅥𝅲',
+  '𝆹𝅥' => '𝆹𝅥',
+  '𝆺𝅥' => '𝆺𝅥',
+  '𝆹𝅥𝅮' => '𝆹𝅥𝅮',
+  '𝆺𝅥𝅮' => '𝆺𝅥𝅮',
+  '𝆹𝅥𝅯' => '𝆹𝅥𝅯',
+  '𝆺𝅥𝅯' => '𝆺𝅥𝅯',
+  '丽' => '丽',
+  '丸' => '丸',
+  '乁' => '乁',
+  '𠄢' => '𠄢',
+  '你' => '你',
+  '侮' => '侮',
+  '侻' => '侻',
+  '倂' => '倂',
+  '偺' => '偺',
+  '備' => '備',
+  '僧' => '僧',
+  '像' => '像',
+  '㒞' => '㒞',
+  '𠘺' => '𠘺',
+  '免' => '免',
+  '兔' => '兔',
+  '兤' => '兤',
+  '具' => '具',
+  '𠔜' => '𠔜',
+  '㒹' => '㒹',
+  '內' => '內',
+  '再' => '再',
+  '𠕋' => '𠕋',
+  '冗' => '冗',
+  '冤' => '冤',
+  '仌' => '仌',
+  '冬' => '冬',
+  '况' => '况',
+  '𩇟' => '𩇟',
+  '凵' => '凵',
+  '刃' => '刃',
+  '㓟' => '㓟',
+  '刻' => '刻',
+  '剆' => '剆',
+  '割' => '割',
+  '剷' => '剷',
+  '㔕' => '㔕',
+  '勇' => '勇',
+  '勉' => '勉',
+  '勤' => '勤',
+  '勺' => '勺',
+  '包' => '包',
+  '匆' => '匆',
+  '北' => '北',
+  '卉' => '卉',
+  '卑' => '卑',
+  '博' => '博',
+  '即' => '即',
+  '卽' => '卽',
+  '卿' => '卿',
+  '卿' => '卿',
+  '卿' => '卿',
+  '𠨬' => '𠨬',
+  '灰' => '灰',
+  '及' => '及',
+  '叟' => '叟',
+  '𠭣' => '𠭣',
+  '叫' => '叫',
+  '叱' => '叱',
+  '吆' => '吆',
+  '咞' => '咞',
+  '吸' => '吸',
+  '呈' => '呈',
+  '周' => '周',
+  '咢' => '咢',
+  '哶' => '哶',
+  '唐' => '唐',
+  '啓' => '啓',
+  '啣' => '啣',
+  '善' => '善',
+  '善' => '善',
+  '喙' => '喙',
+  '喫' => '喫',
+  '喳' => '喳',
+  '嗂' => '嗂',
+  '圖' => '圖',
+  '嘆' => '嘆',
+  '圗' => '圗',
+  '噑' => '噑',
+  '噴' => '噴',
+  '切' => '切',
+  '壮' => '壮',
+  '城' => '城',
+  '埴' => '埴',
+  '堍' => '堍',
+  '型' => '型',
+  '堲' => '堲',
+  '報' => '報',
+  '墬' => '墬',
+  '𡓤' => '𡓤',
+  '売' => '売',
+  '壷' => '壷',
+  '夆' => '夆',
+  '多' => '多',
+  '夢' => '夢',
+  '奢' => '奢',
+  '𡚨' => '𡚨',
+  '𡛪' => '𡛪',
+  '姬' => '姬',
+  '娛' => '娛',
+  '娧' => '娧',
+  '姘' => '姘',
+  '婦' => '婦',
+  '㛮' => '㛮',
+  '㛼' => '㛼',
+  '嬈' => '嬈',
+  '嬾' => '嬾',
+  '嬾' => '嬾',
+  '𡧈' => '𡧈',
+  '寃' => '寃',
+  '寘' => '寘',
+  '寧' => '寧',
+  '寳' => '寳',
+  '𡬘' => '𡬘',
+  '寿' => '寿',
+  '将' => '将',
+  '当' => '当',
+  '尢' => '尢',
+  '㞁' => '㞁',
+  '屠' => '屠',
+  '屮' => '屮',
+  '峀' => '峀',
+  '岍' => '岍',
+  '𡷤' => '𡷤',
+  '嵃' => '嵃',
+  '𡷦' => '𡷦',
+  '嵮' => '嵮',
+  '嵫' => '嵫',
+  '嵼' => '嵼',
+  '巡' => '巡',
+  '巢' => '巢',
+  '㠯' => '㠯',
+  '巽' => '巽',
+  '帨' => '帨',
+  '帽' => '帽',
+  '幩' => '幩',
+  '㡢' => '㡢',
+  '𢆃' => '𢆃',
+  '㡼' => '㡼',
+  '庰' => '庰',
+  '庳' => '庳',
+  '庶' => '庶',
+  '廊' => '廊',
+  '𪎒' => '𪎒',
+  '廾' => '廾',
+  '𢌱' => '𢌱',
+  '𢌱' => '𢌱',
+  '舁' => '舁',
+  '弢' => '弢',
+  '弢' => '弢',
+  '㣇' => '㣇',
+  '𣊸' => '𣊸',
+  '𦇚' => '𦇚',
+  '形' => '形',
+  '彫' => '彫',
+  '㣣' => '㣣',
+  '徚' => '徚',
+  '忍' => '忍',
+  '志' => '志',
+  '忹' => '忹',
+  '悁' => '悁',
+  '㤺' => '㤺',
+  '㤜' => '㤜',
+  '悔' => '悔',
+  '𢛔' => '𢛔',
+  '惇' => '惇',
+  '慈' => '慈',
+  '慌' => '慌',
+  '慎' => '慎',
+  '慌' => '慌',
+  '慺' => '慺',
+  '憎' => '憎',
+  '憲' => '憲',
+  '憤' => '憤',
+  '憯' => '憯',
+  '懞' => '懞',
+  '懲' => '懲',
+  '懶' => '懶',
+  '成' => '成',
+  '戛' => '戛',
+  '扝' => '扝',
+  '抱' => '抱',
+  '拔' => '拔',
+  '捐' => '捐',
+  '𢬌' => '𢬌',
+  '挽' => '挽',
+  '拼' => '拼',
+  '捨' => '捨',
+  '掃' => '掃',
+  '揤' => '揤',
+  '𢯱' => '𢯱',
+  '搢' => '搢',
+  '揅' => '揅',
+  '掩' => '掩',
+  '㨮' => '㨮',
+  '摩' => '摩',
+  '摾' => '摾',
+  '撝' => '撝',
+  '摷' => '摷',
+  '㩬' => '㩬',
+  '敏' => '敏',
+  '敬' => '敬',
+  '𣀊' => '𣀊',
+  '旣' => '旣',
+  '書' => '書',
+  '晉' => '晉',
+  '㬙' => '㬙',
+  '暑' => '暑',
+  '㬈' => '㬈',
+  '㫤' => '㫤',
+  '冒' => '冒',
+  '冕' => '冕',
+  '最' => '最',
+  '暜' => '暜',
+  '肭' => '肭',
+  '䏙' => '䏙',
+  '朗' => '朗',
+  '望' => '望',
+  '朡' => '朡',
+  '杞' => '杞',
+  '杓' => '杓',
+  '𣏃' => '𣏃',
+  '㭉' => '㭉',
+  '柺' => '柺',
+  '枅' => '枅',
+  '桒' => '桒',
+  '梅' => '梅',
+  '𣑭' => '𣑭',
+  '梎' => '梎',
+  '栟' => '栟',
+  '椔' => '椔',
+  '㮝' => '㮝',
+  '楂' => '楂',
+  '榣' => '榣',
+  '槪' => '槪',
+  '檨' => '檨',
+  '𣚣' => '𣚣',
+  '櫛' => '櫛',
+  '㰘' => '㰘',
+  '次' => '次',
+  '𣢧' => '𣢧',
+  '歔' => '歔',
+  '㱎' => '㱎',
+  '歲' => '歲',
+  '殟' => '殟',
+  '殺' => '殺',
+  '殻' => '殻',
+  '𣪍' => '𣪍',
+  '𡴋' => '𡴋',
+  '𣫺' => '𣫺',
+  '汎' => '汎',
+  '𣲼' => '𣲼',
+  '沿' => '沿',
+  '泍' => '泍',
+  '汧' => '汧',
+  '洖' => '洖',
+  '派' => '派',
+  '海' => '海',
+  '流' => '流',
+  '浩' => '浩',
+  '浸' => '浸',
+  '涅' => '涅',
+  '𣴞' => '𣴞',
+  '洴' => '洴',
+  '港' => '港',
+  '湮' => '湮',
+  '㴳' => '㴳',
+  '滋' => '滋',
+  '滇' => '滇',
+  '𣻑' => '𣻑',
+  '淹' => '淹',
+  '潮' => '潮',
+  '𣽞' => '𣽞',
+  '𣾎' => '𣾎',
+  '濆' => '濆',
+  '瀹' => '瀹',
+  '瀞' => '瀞',
+  '瀛' => '瀛',
+  '㶖' => '㶖',
+  '灊' => '灊',
+  '災' => '災',
+  '灷' => '灷',
+  '炭' => '炭',
+  '𠔥' => '𠔥',
+  '煅' => '煅',
+  '𤉣' => '𤉣',
+  '熜' => '熜',
+  '𤎫' => '𤎫',
+  '爨' => '爨',
+  '爵' => '爵',
+  '牐' => '牐',
+  '𤘈' => '𤘈',
+  '犀' => '犀',
+  '犕' => '犕',
+  '𤜵' => '𤜵',
+  '𤠔' => '𤠔',
+  '獺' => '獺',
+  '王' => '王',
+  '㺬' => '㺬',
+  '玥' => '玥',
+  '㺸' => '㺸',
+  '㺸' => '㺸',
+  '瑇' => '瑇',
+  '瑜' => '瑜',
+  '瑱' => '瑱',
+  '璅' => '璅',
+  '瓊' => '瓊',
+  '㼛' => '㼛',
+  '甤' => '甤',
+  '𤰶' => '𤰶',
+  '甾' => '甾',
+  '𤲒' => '𤲒',
+  '異' => '異',
+  '𢆟' => '𢆟',
+  '瘐' => '瘐',
+  '𤾡' => '𤾡',
+  '𤾸' => '𤾸',
+  '𥁄' => '𥁄',
+  '㿼' => '㿼',
+  '䀈' => '䀈',
+  '直' => '直',
+  '𥃳' => '𥃳',
+  '𥃲' => '𥃲',
+  '𥄙' => '𥄙',
+  '𥄳' => '𥄳',
+  '眞' => '眞',
+  '真' => '真',
+  '真' => '真',
+  '睊' => '睊',
+  '䀹' => '䀹',
+  '瞋' => '瞋',
+  '䁆' => '䁆',
+  '䂖' => '䂖',
+  '𥐝' => '𥐝',
+  '硎' => '硎',
+  '碌' => '碌',
+  '磌' => '磌',
+  '䃣' => '䃣',
+  '𥘦' => '𥘦',
+  '祖' => '祖',
+  '𥚚' => '𥚚',
+  '𥛅' => '𥛅',
+  '福' => '福',
+  '秫' => '秫',
+  '䄯' => '䄯',
+  '穀' => '穀',
+  '穊' => '穊',
+  '穏' => '穏',
+  '𥥼' => '𥥼',
+  '𥪧' => '𥪧',
+  '𥪧' => '𥪧',
+  '竮' => '竮',
+  '䈂' => '䈂',
+  '𥮫' => '𥮫',
+  '篆' => '篆',
+  '築' => '築',
+  '䈧' => '䈧',
+  '𥲀' => '𥲀',
+  '糒' => '糒',
+  '䊠' => '䊠',
+  '糨' => '糨',
+  '糣' => '糣',
+  '紀' => '紀',
+  '𥾆' => '𥾆',
+  '絣' => '絣',
+  '䌁' => '䌁',
+  '緇' => '緇',
+  '縂' => '縂',
+  '繅' => '繅',
+  '䌴' => '䌴',
+  '𦈨' => '𦈨',
+  '𦉇' => '𦉇',
+  '䍙' => '䍙',
+  '𦋙' => '𦋙',
+  '罺' => '罺',
+  '𦌾' => '𦌾',
+  '羕' => '羕',
+  '翺' => '翺',
+  '者' => '者',
+  '𦓚' => '𦓚',
+  '𦔣' => '𦔣',
+  '聠' => '聠',
+  '𦖨' => '𦖨',
+  '聰' => '聰',
+  '𣍟' => '𣍟',
+  '䏕' => '䏕',
+  '育' => '育',
+  '脃' => '脃',
+  '䐋' => '䐋',
+  '脾' => '脾',
+  '媵' => '媵',
+  '𦞧' => '𦞧',
+  '𦞵' => '𦞵',
+  '𣎓' => '𣎓',
+  '𣎜' => '𣎜',
+  '舁' => '舁',
+  '舄' => '舄',
+  '辞' => '辞',
+  '䑫' => '䑫',
+  '芑' => '芑',
+  '芋' => '芋',
+  '芝' => '芝',
+  '劳' => '劳',
+  '花' => '花',
+  '芳' => '芳',
+  '芽' => '芽',
+  '苦' => '苦',
+  '𦬼' => '𦬼',
+  '若' => '若',
+  '茝' => '茝',
+  '荣' => '荣',
+  '莭' => '莭',
+  '茣' => '茣',
+  '莽' => '莽',
+  '菧' => '菧',
+  '著' => '著',
+  '荓' => '荓',
+  '菊' => '菊',
+  '菌' => '菌',
+  '菜' => '菜',
+  '𦰶' => '𦰶',
+  '𦵫' => '𦵫',
+  '𦳕' => '𦳕',
+  '䔫' => '䔫',
+  '蓱' => '蓱',
+  '蓳' => '蓳',
+  '蔖' => '蔖',
+  '𧏊' => '𧏊',
+  '蕤' => '蕤',
+  '𦼬' => '𦼬',
+  '䕝' => '䕝',
+  '䕡' => '䕡',
+  '𦾱' => '𦾱',
+  '𧃒' => '𧃒',
+  '䕫' => '䕫',
+  '虐' => '虐',
+  '虜' => '虜',
+  '虧' => '虧',
+  '虩' => '虩',
+  '蚩' => '蚩',
+  '蚈' => '蚈',
+  '蜎' => '蜎',
+  '蛢' => '蛢',
+  '蝹' => '蝹',
+  '蜨' => '蜨',
+  '蝫' => '蝫',
+  '螆' => '螆',
+  '䗗' => '䗗',
+  '蟡' => '蟡',
+  '蠁' => '蠁',
+  '䗹' => '䗹',
+  '衠' => '衠',
+  '衣' => '衣',
+  '𧙧' => '𧙧',
+  '裗' => '裗',
+  '裞' => '裞',
+  '䘵' => '䘵',
+  '裺' => '裺',
+  '㒻' => '㒻',
+  '𧢮' => '𧢮',
+  '𧥦' => '𧥦',
+  '䚾' => '䚾',
+  '䛇' => '䛇',
+  '誠' => '誠',
+  '諭' => '諭',
+  '變' => '變',
+  '豕' => '豕',
+  '𧲨' => '𧲨',
+  '貫' => '貫',
+  '賁' => '賁',
+  '贛' => '贛',
+  '起' => '起',
+  '𧼯' => '𧼯',
+  '𠠄' => '𠠄',
+  '跋' => '跋',
+  '趼' => '趼',
+  '跰' => '跰',
+  '𠣞' => '𠣞',
+  '軔' => '軔',
+  '輸' => '輸',
+  '𨗒' => '𨗒',
+  '𨗭' => '𨗭',
+  '邔' => '邔',
+  '郱' => '郱',
+  '鄑' => '鄑',
+  '𨜮' => '𨜮',
+  '鄛' => '鄛',
+  '鈸' => '鈸',
+  '鋗' => '鋗',
+  '鋘' => '鋘',
+  '鉼' => '鉼',
+  '鏹' => '鏹',
+  '鐕' => '鐕',
+  '𨯺' => '𨯺',
+  '開' => '開',
+  '䦕' => '䦕',
+  '閷' => '閷',
+  '𨵷' => '𨵷',
+  '䧦' => '䧦',
+  '雃' => '雃',
+  '嶲' => '嶲',
+  '霣' => '霣',
+  '𩅅' => '𩅅',
+  '𩈚' => '𩈚',
+  '䩮' => '䩮',
+  '䩶' => '䩶',
+  '韠' => '韠',
+  '𩐊' => '𩐊',
+  '䪲' => '䪲',
+  '𩒖' => '𩒖',
+  '頋' => '頋',
+  '頋' => '頋',
+  '頩' => '頩',
+  '𩖶' => '𩖶',
+  '飢' => '飢',
+  '䬳' => '䬳',
+  '餩' => '餩',
+  '馧' => '馧',
+  '駂' => '駂',
+  '駾' => '駾',
+  '䯎' => '䯎',
+  '𩬰' => '𩬰',
+  '鬒' => '鬒',
+  '鱀' => '鱀',
+  '鳽' => '鳽',
+  '䳎' => '䳎',
+  '䳭' => '䳭',
+  '鵧' => '鵧',
+  '𪃎' => '𪃎',
+  '䳸' => '䳸',
+  '𪄅' => '𪄅',
+  '𪈎' => '𪈎',
+  '𪊑' => '𪊑',
+  '麻' => '麻',
+  '䵖' => '䵖',
+  '黹' => '黹',
+  '黾' => '黾',
+  '鼅' => '鼅',
+  '鼏' => '鼏',
+  '鼖' => '鼖',
+  '鼻' => '鼻',
+  '𪘀' => '𪘀',
+);
diff --git a/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php
new file mode 100644
index 000000000..ec90f36eb
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php
@@ -0,0 +1,876 @@
+ 230,
+  '́' => 230,
+  '̂' => 230,
+  '̃' => 230,
+  '̄' => 230,
+  '̅' => 230,
+  '̆' => 230,
+  '̇' => 230,
+  '̈' => 230,
+  '̉' => 230,
+  '̊' => 230,
+  '̋' => 230,
+  '̌' => 230,
+  '̍' => 230,
+  '̎' => 230,
+  '̏' => 230,
+  '̐' => 230,
+  '̑' => 230,
+  '̒' => 230,
+  '̓' => 230,
+  '̔' => 230,
+  '̕' => 232,
+  '̖' => 220,
+  '̗' => 220,
+  '̘' => 220,
+  '̙' => 220,
+  '̚' => 232,
+  '̛' => 216,
+  '̜' => 220,
+  '̝' => 220,
+  '̞' => 220,
+  '̟' => 220,
+  '̠' => 220,
+  '̡' => 202,
+  '̢' => 202,
+  '̣' => 220,
+  '̤' => 220,
+  '̥' => 220,
+  '̦' => 220,
+  '̧' => 202,
+  '̨' => 202,
+  '̩' => 220,
+  '̪' => 220,
+  '̫' => 220,
+  '̬' => 220,
+  '̭' => 220,
+  '̮' => 220,
+  '̯' => 220,
+  '̰' => 220,
+  '̱' => 220,
+  '̲' => 220,
+  '̳' => 220,
+  '̴' => 1,
+  '̵' => 1,
+  '̶' => 1,
+  '̷' => 1,
+  '̸' => 1,
+  '̹' => 220,
+  '̺' => 220,
+  '̻' => 220,
+  '̼' => 220,
+  '̽' => 230,
+  '̾' => 230,
+  '̿' => 230,
+  '̀' => 230,
+  '́' => 230,
+  '͂' => 230,
+  '̓' => 230,
+  '̈́' => 230,
+  'ͅ' => 240,
+  '͆' => 230,
+  '͇' => 220,
+  '͈' => 220,
+  '͉' => 220,
+  '͊' => 230,
+  '͋' => 230,
+  '͌' => 230,
+  '͍' => 220,
+  '͎' => 220,
+  '͐' => 230,
+  '͑' => 230,
+  '͒' => 230,
+  '͓' => 220,
+  '͔' => 220,
+  '͕' => 220,
+  '͖' => 220,
+  '͗' => 230,
+  '͘' => 232,
+  '͙' => 220,
+  '͚' => 220,
+  '͛' => 230,
+  '͜' => 233,
+  '͝' => 234,
+  '͞' => 234,
+  '͟' => 233,
+  '͠' => 234,
+  '͡' => 234,
+  '͢' => 233,
+  'ͣ' => 230,
+  'ͤ' => 230,
+  'ͥ' => 230,
+  'ͦ' => 230,
+  'ͧ' => 230,
+  'ͨ' => 230,
+  'ͩ' => 230,
+  'ͪ' => 230,
+  'ͫ' => 230,
+  'ͬ' => 230,
+  'ͭ' => 230,
+  'ͮ' => 230,
+  'ͯ' => 230,
+  '҃' => 230,
+  '҄' => 230,
+  '҅' => 230,
+  '҆' => 230,
+  '҇' => 230,
+  '֑' => 220,
+  '֒' => 230,
+  '֓' => 230,
+  '֔' => 230,
+  '֕' => 230,
+  '֖' => 220,
+  '֗' => 230,
+  '֘' => 230,
+  '֙' => 230,
+  '֚' => 222,
+  '֛' => 220,
+  '֜' => 230,
+  '֝' => 230,
+  '֞' => 230,
+  '֟' => 230,
+  '֠' => 230,
+  '֡' => 230,
+  '֢' => 220,
+  '֣' => 220,
+  '֤' => 220,
+  '֥' => 220,
+  '֦' => 220,
+  '֧' => 220,
+  '֨' => 230,
+  '֩' => 230,
+  '֪' => 220,
+  '֫' => 230,
+  '֬' => 230,
+  '֭' => 222,
+  '֮' => 228,
+  '֯' => 230,
+  'ְ' => 10,
+  'ֱ' => 11,
+  'ֲ' => 12,
+  'ֳ' => 13,
+  'ִ' => 14,
+  'ֵ' => 15,
+  'ֶ' => 16,
+  'ַ' => 17,
+  'ָ' => 18,
+  'ֹ' => 19,
+  'ֺ' => 19,
+  'ֻ' => 20,
+  'ּ' => 21,
+  'ֽ' => 22,
+  'ֿ' => 23,
+  'ׁ' => 24,
+  'ׂ' => 25,
+  'ׄ' => 230,
+  'ׅ' => 220,
+  'ׇ' => 18,
+  'ؐ' => 230,
+  'ؑ' => 230,
+  'ؒ' => 230,
+  'ؓ' => 230,
+  'ؔ' => 230,
+  'ؕ' => 230,
+  'ؖ' => 230,
+  'ؗ' => 230,
+  'ؘ' => 30,
+  'ؙ' => 31,
+  'ؚ' => 32,
+  'ً' => 27,
+  'ٌ' => 28,
+  'ٍ' => 29,
+  'َ' => 30,
+  'ُ' => 31,
+  'ِ' => 32,
+  'ّ' => 33,
+  'ْ' => 34,
+  'ٓ' => 230,
+  'ٔ' => 230,
+  'ٕ' => 220,
+  'ٖ' => 220,
+  'ٗ' => 230,
+  '٘' => 230,
+  'ٙ' => 230,
+  'ٚ' => 230,
+  'ٛ' => 230,
+  'ٜ' => 220,
+  'ٝ' => 230,
+  'ٞ' => 230,
+  'ٟ' => 220,
+  'ٰ' => 35,
+  'ۖ' => 230,
+  'ۗ' => 230,
+  'ۘ' => 230,
+  'ۙ' => 230,
+  'ۚ' => 230,
+  'ۛ' => 230,
+  'ۜ' => 230,
+  '۟' => 230,
+  '۠' => 230,
+  'ۡ' => 230,
+  'ۢ' => 230,
+  'ۣ' => 220,
+  'ۤ' => 230,
+  'ۧ' => 230,
+  'ۨ' => 230,
+  '۪' => 220,
+  '۫' => 230,
+  '۬' => 230,
+  'ۭ' => 220,
+  'ܑ' => 36,
+  'ܰ' => 230,
+  'ܱ' => 220,
+  'ܲ' => 230,
+  'ܳ' => 230,
+  'ܴ' => 220,
+  'ܵ' => 230,
+  'ܶ' => 230,
+  'ܷ' => 220,
+  'ܸ' => 220,
+  'ܹ' => 220,
+  'ܺ' => 230,
+  'ܻ' => 220,
+  'ܼ' => 220,
+  'ܽ' => 230,
+  'ܾ' => 220,
+  'ܿ' => 230,
+  '݀' => 230,
+  '݁' => 230,
+  '݂' => 220,
+  '݃' => 230,
+  '݄' => 220,
+  '݅' => 230,
+  '݆' => 220,
+  '݇' => 230,
+  '݈' => 220,
+  '݉' => 230,
+  '݊' => 230,
+  '߫' => 230,
+  '߬' => 230,
+  '߭' => 230,
+  '߮' => 230,
+  '߯' => 230,
+  '߰' => 230,
+  '߱' => 230,
+  '߲' => 220,
+  '߳' => 230,
+  '߽' => 220,
+  'ࠖ' => 230,
+  'ࠗ' => 230,
+  '࠘' => 230,
+  '࠙' => 230,
+  'ࠛ' => 230,
+  'ࠜ' => 230,
+  'ࠝ' => 230,
+  'ࠞ' => 230,
+  'ࠟ' => 230,
+  'ࠠ' => 230,
+  'ࠡ' => 230,
+  'ࠢ' => 230,
+  'ࠣ' => 230,
+  'ࠥ' => 230,
+  'ࠦ' => 230,
+  'ࠧ' => 230,
+  'ࠩ' => 230,
+  'ࠪ' => 230,
+  'ࠫ' => 230,
+  'ࠬ' => 230,
+  '࠭' => 230,
+  '࡙' => 220,
+  '࡚' => 220,
+  '࡛' => 220,
+  '࣓' => 220,
+  'ࣔ' => 230,
+  'ࣕ' => 230,
+  'ࣖ' => 230,
+  'ࣗ' => 230,
+  'ࣘ' => 230,
+  'ࣙ' => 230,
+  'ࣚ' => 230,
+  'ࣛ' => 230,
+  'ࣜ' => 230,
+  'ࣝ' => 230,
+  'ࣞ' => 230,
+  'ࣟ' => 230,
+  '࣠' => 230,
+  '࣡' => 230,
+  'ࣣ' => 220,
+  'ࣤ' => 230,
+  'ࣥ' => 230,
+  'ࣦ' => 220,
+  'ࣧ' => 230,
+  'ࣨ' => 230,
+  'ࣩ' => 220,
+  '࣪' => 230,
+  '࣫' => 230,
+  '࣬' => 230,
+  '࣭' => 220,
+  '࣮' => 220,
+  '࣯' => 220,
+  'ࣰ' => 27,
+  'ࣱ' => 28,
+  'ࣲ' => 29,
+  'ࣳ' => 230,
+  'ࣴ' => 230,
+  'ࣵ' => 230,
+  'ࣶ' => 220,
+  'ࣷ' => 230,
+  'ࣸ' => 230,
+  'ࣹ' => 220,
+  'ࣺ' => 220,
+  'ࣻ' => 230,
+  'ࣼ' => 230,
+  'ࣽ' => 230,
+  'ࣾ' => 230,
+  'ࣿ' => 230,
+  '़' => 7,
+  '्' => 9,
+  '॑' => 230,
+  '॒' => 220,
+  '॓' => 230,
+  '॔' => 230,
+  '়' => 7,
+  '্' => 9,
+  '৾' => 230,
+  '਼' => 7,
+  '੍' => 9,
+  '઼' => 7,
+  '્' => 9,
+  '଼' => 7,
+  '୍' => 9,
+  '்' => 9,
+  '్' => 9,
+  'ౕ' => 84,
+  'ౖ' => 91,
+  '಼' => 7,
+  '್' => 9,
+  '഻' => 9,
+  '഼' => 9,
+  '്' => 9,
+  '්' => 9,
+  'ุ' => 103,
+  'ู' => 103,
+  'ฺ' => 9,
+  '่' => 107,
+  '้' => 107,
+  '๊' => 107,
+  '๋' => 107,
+  'ຸ' => 118,
+  'ູ' => 118,
+  '຺' => 9,
+  '່' => 122,
+  '້' => 122,
+  '໊' => 122,
+  '໋' => 122,
+  '༘' => 220,
+  '༙' => 220,
+  '༵' => 220,
+  '༷' => 220,
+  '༹' => 216,
+  'ཱ' => 129,
+  'ི' => 130,
+  'ུ' => 132,
+  'ེ' => 130,
+  'ཻ' => 130,
+  'ོ' => 130,
+  'ཽ' => 130,
+  'ྀ' => 130,
+  'ྂ' => 230,
+  'ྃ' => 230,
+  '྄' => 9,
+  '྆' => 230,
+  '྇' => 230,
+  '࿆' => 220,
+  '့' => 7,
+  '္' => 9,
+  '်' => 9,
+  'ႍ' => 220,
+  '፝' => 230,
+  '፞' => 230,
+  '፟' => 230,
+  '᜔' => 9,
+  '᜴' => 9,
+  '្' => 9,
+  '៝' => 230,
+  'ᢩ' => 228,
+  '᤹' => 222,
+  '᤺' => 230,
+  '᤻' => 220,
+  'ᨗ' => 230,
+  'ᨘ' => 220,
+  '᩠' => 9,
+  '᩵' => 230,
+  '᩶' => 230,
+  '᩷' => 230,
+  '᩸' => 230,
+  '᩹' => 230,
+  '᩺' => 230,
+  '᩻' => 230,
+  '᩼' => 230,
+  '᩿' => 220,
+  '᪰' => 230,
+  '᪱' => 230,
+  '᪲' => 230,
+  '᪳' => 230,
+  '᪴' => 230,
+  '᪵' => 220,
+  '᪶' => 220,
+  '᪷' => 220,
+  '᪸' => 220,
+  '᪹' => 220,
+  '᪺' => 220,
+  '᪻' => 230,
+  '᪼' => 230,
+  '᪽' => 220,
+  'ᪿ' => 220,
+  'ᫀ' => 220,
+  '᬴' => 7,
+  '᭄' => 9,
+  '᭫' => 230,
+  '᭬' => 220,
+  '᭭' => 230,
+  '᭮' => 230,
+  '᭯' => 230,
+  '᭰' => 230,
+  '᭱' => 230,
+  '᭲' => 230,
+  '᭳' => 230,
+  '᮪' => 9,
+  '᮫' => 9,
+  '᯦' => 7,
+  '᯲' => 9,
+  '᯳' => 9,
+  '᰷' => 7,
+  '᳐' => 230,
+  '᳑' => 230,
+  '᳒' => 230,
+  '᳔' => 1,
+  '᳕' => 220,
+  '᳖' => 220,
+  '᳗' => 220,
+  '᳘' => 220,
+  '᳙' => 220,
+  '᳚' => 230,
+  '᳛' => 230,
+  '᳜' => 220,
+  '᳝' => 220,
+  '᳞' => 220,
+  '᳟' => 220,
+  '᳠' => 230,
+  '᳢' => 1,
+  '᳣' => 1,
+  '᳤' => 1,
+  '᳥' => 1,
+  '᳦' => 1,
+  '᳧' => 1,
+  '᳨' => 1,
+  '᳭' => 220,
+  '᳴' => 230,
+  '᳸' => 230,
+  '᳹' => 230,
+  '᷀' => 230,
+  '᷁' => 230,
+  '᷂' => 220,
+  '᷃' => 230,
+  '᷄' => 230,
+  '᷅' => 230,
+  '᷆' => 230,
+  '᷇' => 230,
+  '᷈' => 230,
+  '᷉' => 230,
+  '᷊' => 220,
+  '᷋' => 230,
+  '᷌' => 230,
+  '᷍' => 234,
+  '᷎' => 214,
+  '᷏' => 220,
+  '᷐' => 202,
+  '᷑' => 230,
+  '᷒' => 230,
+  'ᷓ' => 230,
+  'ᷔ' => 230,
+  'ᷕ' => 230,
+  'ᷖ' => 230,
+  'ᷗ' => 230,
+  'ᷘ' => 230,
+  'ᷙ' => 230,
+  'ᷚ' => 230,
+  'ᷛ' => 230,
+  'ᷜ' => 230,
+  'ᷝ' => 230,
+  'ᷞ' => 230,
+  'ᷟ' => 230,
+  'ᷠ' => 230,
+  'ᷡ' => 230,
+  'ᷢ' => 230,
+  'ᷣ' => 230,
+  'ᷤ' => 230,
+  'ᷥ' => 230,
+  'ᷦ' => 230,
+  'ᷧ' => 230,
+  'ᷨ' => 230,
+  'ᷩ' => 230,
+  'ᷪ' => 230,
+  'ᷫ' => 230,
+  'ᷬ' => 230,
+  'ᷭ' => 230,
+  'ᷮ' => 230,
+  'ᷯ' => 230,
+  'ᷰ' => 230,
+  'ᷱ' => 230,
+  'ᷲ' => 230,
+  'ᷳ' => 230,
+  'ᷴ' => 230,
+  '᷵' => 230,
+  '᷶' => 232,
+  '᷷' => 228,
+  '᷸' => 228,
+  '᷹' => 220,
+  '᷻' => 230,
+  '᷼' => 233,
+  '᷽' => 220,
+  '᷾' => 230,
+  '᷿' => 220,
+  '⃐' => 230,
+  '⃑' => 230,
+  '⃒' => 1,
+  '⃓' => 1,
+  '⃔' => 230,
+  '⃕' => 230,
+  '⃖' => 230,
+  '⃗' => 230,
+  '⃘' => 1,
+  '⃙' => 1,
+  '⃚' => 1,
+  '⃛' => 230,
+  '⃜' => 230,
+  '⃡' => 230,
+  '⃥' => 1,
+  '⃦' => 1,
+  '⃧' => 230,
+  '⃨' => 220,
+  '⃩' => 230,
+  '⃪' => 1,
+  '⃫' => 1,
+  '⃬' => 220,
+  '⃭' => 220,
+  '⃮' => 220,
+  '⃯' => 220,
+  '⃰' => 230,
+  '⳯' => 230,
+  '⳰' => 230,
+  '⳱' => 230,
+  '⵿' => 9,
+  'ⷠ' => 230,
+  'ⷡ' => 230,
+  'ⷢ' => 230,
+  'ⷣ' => 230,
+  'ⷤ' => 230,
+  'ⷥ' => 230,
+  'ⷦ' => 230,
+  'ⷧ' => 230,
+  'ⷨ' => 230,
+  'ⷩ' => 230,
+  'ⷪ' => 230,
+  'ⷫ' => 230,
+  'ⷬ' => 230,
+  'ⷭ' => 230,
+  'ⷮ' => 230,
+  'ⷯ' => 230,
+  'ⷰ' => 230,
+  'ⷱ' => 230,
+  'ⷲ' => 230,
+  'ⷳ' => 230,
+  'ⷴ' => 230,
+  'ⷵ' => 230,
+  'ⷶ' => 230,
+  'ⷷ' => 230,
+  'ⷸ' => 230,
+  'ⷹ' => 230,
+  'ⷺ' => 230,
+  'ⷻ' => 230,
+  'ⷼ' => 230,
+  'ⷽ' => 230,
+  'ⷾ' => 230,
+  'ⷿ' => 230,
+  '〪' => 218,
+  '〫' => 228,
+  '〬' => 232,
+  '〭' => 222,
+  '〮' => 224,
+  '〯' => 224,
+  '゙' => 8,
+  '゚' => 8,
+  '꙯' => 230,
+  'ꙴ' => 230,
+  'ꙵ' => 230,
+  'ꙶ' => 230,
+  'ꙷ' => 230,
+  'ꙸ' => 230,
+  'ꙹ' => 230,
+  'ꙺ' => 230,
+  'ꙻ' => 230,
+  '꙼' => 230,
+  '꙽' => 230,
+  'ꚞ' => 230,
+  'ꚟ' => 230,
+  '꛰' => 230,
+  '꛱' => 230,
+  '꠆' => 9,
+  '꠬' => 9,
+  '꣄' => 9,
+  '꣠' => 230,
+  '꣡' => 230,
+  '꣢' => 230,
+  '꣣' => 230,
+  '꣤' => 230,
+  '꣥' => 230,
+  '꣦' => 230,
+  '꣧' => 230,
+  '꣨' => 230,
+  '꣩' => 230,
+  '꣪' => 230,
+  '꣫' => 230,
+  '꣬' => 230,
+  '꣭' => 230,
+  '꣮' => 230,
+  '꣯' => 230,
+  '꣰' => 230,
+  '꣱' => 230,
+  '꤫' => 220,
+  '꤬' => 220,
+  '꤭' => 220,
+  '꥓' => 9,
+  '꦳' => 7,
+  '꧀' => 9,
+  'ꪰ' => 230,
+  'ꪲ' => 230,
+  'ꪳ' => 230,
+  'ꪴ' => 220,
+  'ꪷ' => 230,
+  'ꪸ' => 230,
+  'ꪾ' => 230,
+  '꪿' => 230,
+  '꫁' => 230,
+  '꫶' => 9,
+  '꯭' => 9,
+  'ﬞ' => 26,
+  '︠' => 230,
+  '︡' => 230,
+  '︢' => 230,
+  '︣' => 230,
+  '︤' => 230,
+  '︥' => 230,
+  '︦' => 230,
+  '︧' => 220,
+  '︨' => 220,
+  '︩' => 220,
+  '︪' => 220,
+  '︫' => 220,
+  '︬' => 220,
+  '︭' => 220,
+  '︮' => 230,
+  '︯' => 230,
+  '𐇽' => 220,
+  '𐋠' => 220,
+  '𐍶' => 230,
+  '𐍷' => 230,
+  '𐍸' => 230,
+  '𐍹' => 230,
+  '𐍺' => 230,
+  '𐨍' => 220,
+  '𐨏' => 230,
+  '𐨸' => 230,
+  '𐨹' => 1,
+  '𐨺' => 220,
+  '𐨿' => 9,
+  '𐫥' => 230,
+  '𐫦' => 220,
+  '𐴤' => 230,
+  '𐴥' => 230,
+  '𐴦' => 230,
+  '𐴧' => 230,
+  '𐺫' => 230,
+  '𐺬' => 230,
+  '𐽆' => 220,
+  '𐽇' => 220,
+  '𐽈' => 230,
+  '𐽉' => 230,
+  '𐽊' => 230,
+  '𐽋' => 220,
+  '𐽌' => 230,
+  '𐽍' => 220,
+  '𐽎' => 220,
+  '𐽏' => 220,
+  '𐽐' => 220,
+  '𑁆' => 9,
+  '𑁿' => 9,
+  '𑂹' => 9,
+  '𑂺' => 7,
+  '𑄀' => 230,
+  '𑄁' => 230,
+  '𑄂' => 230,
+  '𑄳' => 9,
+  '𑄴' => 9,
+  '𑅳' => 7,
+  '𑇀' => 9,
+  '𑇊' => 7,
+  '𑈵' => 9,
+  '𑈶' => 7,
+  '𑋩' => 7,
+  '𑋪' => 9,
+  '𑌻' => 7,
+  '𑌼' => 7,
+  '𑍍' => 9,
+  '𑍦' => 230,
+  '𑍧' => 230,
+  '𑍨' => 230,
+  '𑍩' => 230,
+  '𑍪' => 230,
+  '𑍫' => 230,
+  '𑍬' => 230,
+  '𑍰' => 230,
+  '𑍱' => 230,
+  '𑍲' => 230,
+  '𑍳' => 230,
+  '𑍴' => 230,
+  '𑑂' => 9,
+  '𑑆' => 7,
+  '𑑞' => 230,
+  '𑓂' => 9,
+  '𑓃' => 7,
+  '𑖿' => 9,
+  '𑗀' => 7,
+  '𑘿' => 9,
+  '𑚶' => 9,
+  '𑚷' => 7,
+  '𑜫' => 9,
+  '𑠹' => 9,
+  '𑠺' => 7,
+  '𑤽' => 9,
+  '𑤾' => 9,
+  '𑥃' => 7,
+  '𑧠' => 9,
+  '𑨴' => 9,
+  '𑩇' => 9,
+  '𑪙' => 9,
+  '𑰿' => 9,
+  '𑵂' => 7,
+  '𑵄' => 9,
+  '𑵅' => 9,
+  '𑶗' => 9,
+  '𖫰' => 1,
+  '𖫱' => 1,
+  '𖫲' => 1,
+  '𖫳' => 1,
+  '𖫴' => 1,
+  '𖬰' => 230,
+  '𖬱' => 230,
+  '𖬲' => 230,
+  '𖬳' => 230,
+  '𖬴' => 230,
+  '𖬵' => 230,
+  '𖬶' => 230,
+  '𖿰' => 6,
+  '𖿱' => 6,
+  '𛲞' => 1,
+  '𝅥' => 216,
+  '𝅦' => 216,
+  '𝅧' => 1,
+  '𝅨' => 1,
+  '𝅩' => 1,
+  '𝅭' => 226,
+  '𝅮' => 216,
+  '𝅯' => 216,
+  '𝅰' => 216,
+  '𝅱' => 216,
+  '𝅲' => 216,
+  '𝅻' => 220,
+  '𝅼' => 220,
+  '𝅽' => 220,
+  '𝅾' => 220,
+  '𝅿' => 220,
+  '𝆀' => 220,
+  '𝆁' => 220,
+  '𝆂' => 220,
+  '𝆅' => 230,
+  '𝆆' => 230,
+  '𝆇' => 230,
+  '𝆈' => 230,
+  '𝆉' => 230,
+  '𝆊' => 220,
+  '𝆋' => 220,
+  '𝆪' => 230,
+  '𝆫' => 230,
+  '𝆬' => 230,
+  '𝆭' => 230,
+  '𝉂' => 230,
+  '𝉃' => 230,
+  '𝉄' => 230,
+  '𞀀' => 230,
+  '𞀁' => 230,
+  '𞀂' => 230,
+  '𞀃' => 230,
+  '𞀄' => 230,
+  '𞀅' => 230,
+  '𞀆' => 230,
+  '𞀈' => 230,
+  '𞀉' => 230,
+  '𞀊' => 230,
+  '𞀋' => 230,
+  '𞀌' => 230,
+  '𞀍' => 230,
+  '𞀎' => 230,
+  '𞀏' => 230,
+  '𞀐' => 230,
+  '𞀑' => 230,
+  '𞀒' => 230,
+  '𞀓' => 230,
+  '𞀔' => 230,
+  '𞀕' => 230,
+  '𞀖' => 230,
+  '𞀗' => 230,
+  '𞀘' => 230,
+  '𞀛' => 230,
+  '𞀜' => 230,
+  '𞀝' => 230,
+  '𞀞' => 230,
+  '𞀟' => 230,
+  '𞀠' => 230,
+  '𞀡' => 230,
+  '𞀣' => 230,
+  '𞀤' => 230,
+  '𞀦' => 230,
+  '𞀧' => 230,
+  '𞀨' => 230,
+  '𞀩' => 230,
+  '𞀪' => 230,
+  '𞄰' => 230,
+  '𞄱' => 230,
+  '𞄲' => 230,
+  '𞄳' => 230,
+  '𞄴' => 230,
+  '𞄵' => 230,
+  '𞄶' => 230,
+  '𞋬' => 230,
+  '𞋭' => 230,
+  '𞋮' => 230,
+  '𞋯' => 230,
+  '𞣐' => 220,
+  '𞣑' => 220,
+  '𞣒' => 220,
+  '𞣓' => 220,
+  '𞣔' => 220,
+  '𞣕' => 220,
+  '𞣖' => 220,
+  '𞥄' => 230,
+  '𞥅' => 230,
+  '𞥆' => 230,
+  '𞥇' => 230,
+  '𞥈' => 230,
+  '𞥉' => 230,
+  '𞥊' => 7,
+);
diff --git a/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php
new file mode 100644
index 000000000..157490289
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php
@@ -0,0 +1,3695 @@
+ ' ',
+  '¨' => ' ̈',
+  'ª' => 'a',
+  '¯' => ' ̄',
+  '²' => '2',
+  '³' => '3',
+  '´' => ' ́',
+  'µ' => 'μ',
+  '¸' => ' ̧',
+  '¹' => '1',
+  'º' => 'o',
+  '¼' => '1⁄4',
+  '½' => '1⁄2',
+  '¾' => '3⁄4',
+  'IJ' => 'IJ',
+  'ij' => 'ij',
+  'Ŀ' => 'L·',
+  'ŀ' => 'l·',
+  'ʼn' => 'ʼn',
+  'ſ' => 's',
+  'DŽ' => 'DŽ',
+  'Dž' => 'Dž',
+  'dž' => 'dž',
+  'LJ' => 'LJ',
+  'Lj' => 'Lj',
+  'lj' => 'lj',
+  'NJ' => 'NJ',
+  'Nj' => 'Nj',
+  'nj' => 'nj',
+  'DZ' => 'DZ',
+  'Dz' => 'Dz',
+  'dz' => 'dz',
+  'ʰ' => 'h',
+  'ʱ' => 'ɦ',
+  'ʲ' => 'j',
+  'ʳ' => 'r',
+  'ʴ' => 'ɹ',
+  'ʵ' => 'ɻ',
+  'ʶ' => 'ʁ',
+  'ʷ' => 'w',
+  'ʸ' => 'y',
+  '˘' => ' ̆',
+  '˙' => ' ̇',
+  '˚' => ' ̊',
+  '˛' => ' ̨',
+  '˜' => ' ̃',
+  '˝' => ' ̋',
+  'ˠ' => 'ɣ',
+  'ˡ' => 'l',
+  'ˢ' => 's',
+  'ˣ' => 'x',
+  'ˤ' => 'ʕ',
+  'ͺ' => ' ͅ',
+  '΄' => ' ́',
+  '΅' => ' ̈́',
+  'ϐ' => 'β',
+  'ϑ' => 'θ',
+  'ϒ' => 'Υ',
+  'ϓ' => 'Ύ',
+  'ϔ' => 'Ϋ',
+  'ϕ' => 'φ',
+  'ϖ' => 'π',
+  'ϰ' => 'κ',
+  'ϱ' => 'ρ',
+  'ϲ' => 'ς',
+  'ϴ' => 'Θ',
+  'ϵ' => 'ε',
+  'Ϲ' => 'Σ',
+  'և' => 'եւ',
+  'ٵ' => 'اٴ',
+  'ٶ' => 'وٴ',
+  'ٷ' => 'ۇٴ',
+  'ٸ' => 'يٴ',
+  'ำ' => 'ํา',
+  'ຳ' => 'ໍາ',
+  'ໜ' => 'ຫນ',
+  'ໝ' => 'ຫມ',
+  '༌' => '་',
+  'ཷ' => 'ྲཱྀ',
+  'ཹ' => 'ླཱྀ',
+  'ჼ' => 'ნ',
+  'ᴬ' => 'A',
+  'ᴭ' => 'Æ',
+  'ᴮ' => 'B',
+  'ᴰ' => 'D',
+  'ᴱ' => 'E',
+  'ᴲ' => 'Ǝ',
+  'ᴳ' => 'G',
+  'ᴴ' => 'H',
+  'ᴵ' => 'I',
+  'ᴶ' => 'J',
+  'ᴷ' => 'K',
+  'ᴸ' => 'L',
+  'ᴹ' => 'M',
+  'ᴺ' => 'N',
+  'ᴼ' => 'O',
+  'ᴽ' => 'Ȣ',
+  'ᴾ' => 'P',
+  'ᴿ' => 'R',
+  'ᵀ' => 'T',
+  'ᵁ' => 'U',
+  'ᵂ' => 'W',
+  'ᵃ' => 'a',
+  'ᵄ' => 'ɐ',
+  'ᵅ' => 'ɑ',
+  'ᵆ' => 'ᴂ',
+  'ᵇ' => 'b',
+  'ᵈ' => 'd',
+  'ᵉ' => 'e',
+  'ᵊ' => 'ə',
+  'ᵋ' => 'ɛ',
+  'ᵌ' => 'ɜ',
+  'ᵍ' => 'g',
+  'ᵏ' => 'k',
+  'ᵐ' => 'm',
+  'ᵑ' => 'ŋ',
+  'ᵒ' => 'o',
+  'ᵓ' => 'ɔ',
+  'ᵔ' => 'ᴖ',
+  'ᵕ' => 'ᴗ',
+  'ᵖ' => 'p',
+  'ᵗ' => 't',
+  'ᵘ' => 'u',
+  'ᵙ' => 'ᴝ',
+  'ᵚ' => 'ɯ',
+  'ᵛ' => 'v',
+  'ᵜ' => 'ᴥ',
+  'ᵝ' => 'β',
+  'ᵞ' => 'γ',
+  'ᵟ' => 'δ',
+  'ᵠ' => 'φ',
+  'ᵡ' => 'χ',
+  'ᵢ' => 'i',
+  'ᵣ' => 'r',
+  'ᵤ' => 'u',
+  'ᵥ' => 'v',
+  'ᵦ' => 'β',
+  'ᵧ' => 'γ',
+  'ᵨ' => 'ρ',
+  'ᵩ' => 'φ',
+  'ᵪ' => 'χ',
+  'ᵸ' => 'н',
+  'ᶛ' => 'ɒ',
+  'ᶜ' => 'c',
+  'ᶝ' => 'ɕ',
+  'ᶞ' => 'ð',
+  'ᶟ' => 'ɜ',
+  'ᶠ' => 'f',
+  'ᶡ' => 'ɟ',
+  'ᶢ' => 'ɡ',
+  'ᶣ' => 'ɥ',
+  'ᶤ' => 'ɨ',
+  'ᶥ' => 'ɩ',
+  'ᶦ' => 'ɪ',
+  'ᶧ' => 'ᵻ',
+  'ᶨ' => 'ʝ',
+  'ᶩ' => 'ɭ',
+  'ᶪ' => 'ᶅ',
+  'ᶫ' => 'ʟ',
+  'ᶬ' => 'ɱ',
+  'ᶭ' => 'ɰ',
+  'ᶮ' => 'ɲ',
+  'ᶯ' => 'ɳ',
+  'ᶰ' => 'ɴ',
+  'ᶱ' => 'ɵ',
+  'ᶲ' => 'ɸ',
+  'ᶳ' => 'ʂ',
+  'ᶴ' => 'ʃ',
+  'ᶵ' => 'ƫ',
+  'ᶶ' => 'ʉ',
+  'ᶷ' => 'ʊ',
+  'ᶸ' => 'ᴜ',
+  'ᶹ' => 'ʋ',
+  'ᶺ' => 'ʌ',
+  'ᶻ' => 'z',
+  'ᶼ' => 'ʐ',
+  'ᶽ' => 'ʑ',
+  'ᶾ' => 'ʒ',
+  'ᶿ' => 'θ',
+  'ẚ' => 'aʾ',
+  'ẛ' => 'ṡ',
+  '᾽' => ' ̓',
+  '᾿' => ' ̓',
+  '῀' => ' ͂',
+  '῁' => ' ̈͂',
+  '῍' => ' ̓̀',
+  '῎' => ' ̓́',
+  '῏' => ' ̓͂',
+  '῝' => ' ̔̀',
+  '῞' => ' ̔́',
+  '῟' => ' ̔͂',
+  '῭' => ' ̈̀',
+  '΅' => ' ̈́',
+  '´' => ' ́',
+  '῾' => ' ̔',
+  ' ' => ' ',
+  ' ' => ' ',
+  ' ' => ' ',
+  ' ' => ' ',
+  ' ' => ' ',
+  ' ' => ' ',
+  ' ' => ' ',
+  ' ' => ' ',
+  ' ' => ' ',
+  ' ' => ' ',
+  ' ' => ' ',
+  '‑' => '‐',
+  '‗' => ' ̳',
+  '․' => '.',
+  '‥' => '..',
+  '…' => '...',
+  ' ' => ' ',
+  '″' => '′′',
+  '‴' => '′′′',
+  '‶' => '‵‵',
+  '‷' => '‵‵‵',
+  '‼' => '!!',
+  '‾' => ' ̅',
+  '⁇' => '??',
+  '⁈' => '?!',
+  '⁉' => '!?',
+  '⁗' => '′′′′',
+  ' ' => ' ',
+  '⁰' => '0',
+  'ⁱ' => 'i',
+  '⁴' => '4',
+  '⁵' => '5',
+  '⁶' => '6',
+  '⁷' => '7',
+  '⁸' => '8',
+  '⁹' => '9',
+  '⁺' => '+',
+  '⁻' => '−',
+  '⁼' => '=',
+  '⁽' => '(',
+  '⁾' => ')',
+  'ⁿ' => 'n',
+  '₀' => '0',
+  '₁' => '1',
+  '₂' => '2',
+  '₃' => '3',
+  '₄' => '4',
+  '₅' => '5',
+  '₆' => '6',
+  '₇' => '7',
+  '₈' => '8',
+  '₉' => '9',
+  '₊' => '+',
+  '₋' => '−',
+  '₌' => '=',
+  '₍' => '(',
+  '₎' => ')',
+  'ₐ' => 'a',
+  'ₑ' => 'e',
+  'ₒ' => 'o',
+  'ₓ' => 'x',
+  'ₔ' => 'ə',
+  'ₕ' => 'h',
+  'ₖ' => 'k',
+  'ₗ' => 'l',
+  'ₘ' => 'm',
+  'ₙ' => 'n',
+  'ₚ' => 'p',
+  'ₛ' => 's',
+  'ₜ' => 't',
+  '₨' => 'Rs',
+  '℀' => 'a/c',
+  '℁' => 'a/s',
+  'ℂ' => 'C',
+  '℃' => '°C',
+  '℅' => 'c/o',
+  '℆' => 'c/u',
+  'ℇ' => 'Ɛ',
+  '℉' => '°F',
+  'ℊ' => 'g',
+  'ℋ' => 'H',
+  'ℌ' => 'H',
+  'ℍ' => 'H',
+  'ℎ' => 'h',
+  'ℏ' => 'ħ',
+  'ℐ' => 'I',
+  'ℑ' => 'I',
+  'ℒ' => 'L',
+  'ℓ' => 'l',
+  'ℕ' => 'N',
+  '№' => 'No',
+  'ℙ' => 'P',
+  'ℚ' => 'Q',
+  'ℛ' => 'R',
+  'ℜ' => 'R',
+  'ℝ' => 'R',
+  '℠' => 'SM',
+  '℡' => 'TEL',
+  '™' => 'TM',
+  'ℤ' => 'Z',
+  'ℨ' => 'Z',
+  'ℬ' => 'B',
+  'ℭ' => 'C',
+  'ℯ' => 'e',
+  'ℰ' => 'E',
+  'ℱ' => 'F',
+  'ℳ' => 'M',
+  'ℴ' => 'o',
+  'ℵ' => 'א',
+  'ℶ' => 'ב',
+  'ℷ' => 'ג',
+  'ℸ' => 'ד',
+  'ℹ' => 'i',
+  '℻' => 'FAX',
+  'ℼ' => 'π',
+  'ℽ' => 'γ',
+  'ℾ' => 'Γ',
+  'ℿ' => 'Π',
+  '⅀' => '∑',
+  'ⅅ' => 'D',
+  'ⅆ' => 'd',
+  'ⅇ' => 'e',
+  'ⅈ' => 'i',
+  'ⅉ' => 'j',
+  '⅐' => '1⁄7',
+  '⅑' => '1⁄9',
+  '⅒' => '1⁄10',
+  '⅓' => '1⁄3',
+  '⅔' => '2⁄3',
+  '⅕' => '1⁄5',
+  '⅖' => '2⁄5',
+  '⅗' => '3⁄5',
+  '⅘' => '4⁄5',
+  '⅙' => '1⁄6',
+  '⅚' => '5⁄6',
+  '⅛' => '1⁄8',
+  '⅜' => '3⁄8',
+  '⅝' => '5⁄8',
+  '⅞' => '7⁄8',
+  '⅟' => '1⁄',
+  'Ⅰ' => 'I',
+  'Ⅱ' => 'II',
+  'Ⅲ' => 'III',
+  'Ⅳ' => 'IV',
+  'Ⅴ' => 'V',
+  'Ⅵ' => 'VI',
+  'Ⅶ' => 'VII',
+  'Ⅷ' => 'VIII',
+  'Ⅸ' => 'IX',
+  'Ⅹ' => 'X',
+  'Ⅺ' => 'XI',
+  'Ⅻ' => 'XII',
+  'Ⅼ' => 'L',
+  'Ⅽ' => 'C',
+  'Ⅾ' => 'D',
+  'Ⅿ' => 'M',
+  'ⅰ' => 'i',
+  'ⅱ' => 'ii',
+  'ⅲ' => 'iii',
+  'ⅳ' => 'iv',
+  'ⅴ' => 'v',
+  'ⅵ' => 'vi',
+  'ⅶ' => 'vii',
+  'ⅷ' => 'viii',
+  'ⅸ' => 'ix',
+  'ⅹ' => 'x',
+  'ⅺ' => 'xi',
+  'ⅻ' => 'xii',
+  'ⅼ' => 'l',
+  'ⅽ' => 'c',
+  'ⅾ' => 'd',
+  'ⅿ' => 'm',
+  '↉' => '0⁄3',
+  '∬' => '∫∫',
+  '∭' => '∫∫∫',
+  '∯' => '∮∮',
+  '∰' => '∮∮∮',
+  '①' => '1',
+  '②' => '2',
+  '③' => '3',
+  '④' => '4',
+  '⑤' => '5',
+  '⑥' => '6',
+  '⑦' => '7',
+  '⑧' => '8',
+  '⑨' => '9',
+  '⑩' => '10',
+  '⑪' => '11',
+  '⑫' => '12',
+  '⑬' => '13',
+  '⑭' => '14',
+  '⑮' => '15',
+  '⑯' => '16',
+  '⑰' => '17',
+  '⑱' => '18',
+  '⑲' => '19',
+  '⑳' => '20',
+  '⑴' => '(1)',
+  '⑵' => '(2)',
+  '⑶' => '(3)',
+  '⑷' => '(4)',
+  '⑸' => '(5)',
+  '⑹' => '(6)',
+  '⑺' => '(7)',
+  '⑻' => '(8)',
+  '⑼' => '(9)',
+  '⑽' => '(10)',
+  '⑾' => '(11)',
+  '⑿' => '(12)',
+  '⒀' => '(13)',
+  '⒁' => '(14)',
+  '⒂' => '(15)',
+  '⒃' => '(16)',
+  '⒄' => '(17)',
+  '⒅' => '(18)',
+  '⒆' => '(19)',
+  '⒇' => '(20)',
+  '⒈' => '1.',
+  '⒉' => '2.',
+  '⒊' => '3.',
+  '⒋' => '4.',
+  '⒌' => '5.',
+  '⒍' => '6.',
+  '⒎' => '7.',
+  '⒏' => '8.',
+  '⒐' => '9.',
+  '⒑' => '10.',
+  '⒒' => '11.',
+  '⒓' => '12.',
+  '⒔' => '13.',
+  '⒕' => '14.',
+  '⒖' => '15.',
+  '⒗' => '16.',
+  '⒘' => '17.',
+  '⒙' => '18.',
+  '⒚' => '19.',
+  '⒛' => '20.',
+  '⒜' => '(a)',
+  '⒝' => '(b)',
+  '⒞' => '(c)',
+  '⒟' => '(d)',
+  '⒠' => '(e)',
+  '⒡' => '(f)',
+  '⒢' => '(g)',
+  '⒣' => '(h)',
+  '⒤' => '(i)',
+  '⒥' => '(j)',
+  '⒦' => '(k)',
+  '⒧' => '(l)',
+  '⒨' => '(m)',
+  '⒩' => '(n)',
+  '⒪' => '(o)',
+  '⒫' => '(p)',
+  '⒬' => '(q)',
+  '⒭' => '(r)',
+  '⒮' => '(s)',
+  '⒯' => '(t)',
+  '⒰' => '(u)',
+  '⒱' => '(v)',
+  '⒲' => '(w)',
+  '⒳' => '(x)',
+  '⒴' => '(y)',
+  '⒵' => '(z)',
+  'Ⓐ' => 'A',
+  'Ⓑ' => 'B',
+  'Ⓒ' => 'C',
+  'Ⓓ' => 'D',
+  'Ⓔ' => 'E',
+  'Ⓕ' => 'F',
+  'Ⓖ' => 'G',
+  'Ⓗ' => 'H',
+  'Ⓘ' => 'I',
+  'Ⓙ' => 'J',
+  'Ⓚ' => 'K',
+  'Ⓛ' => 'L',
+  'Ⓜ' => 'M',
+  'Ⓝ' => 'N',
+  'Ⓞ' => 'O',
+  'Ⓟ' => 'P',
+  'Ⓠ' => 'Q',
+  'Ⓡ' => 'R',
+  'Ⓢ' => 'S',
+  'Ⓣ' => 'T',
+  'Ⓤ' => 'U',
+  'Ⓥ' => 'V',
+  'Ⓦ' => 'W',
+  'Ⓧ' => 'X',
+  'Ⓨ' => 'Y',
+  'Ⓩ' => 'Z',
+  'ⓐ' => 'a',
+  'ⓑ' => 'b',
+  'ⓒ' => 'c',
+  'ⓓ' => 'd',
+  'ⓔ' => 'e',
+  'ⓕ' => 'f',
+  'ⓖ' => 'g',
+  'ⓗ' => 'h',
+  'ⓘ' => 'i',
+  'ⓙ' => 'j',
+  'ⓚ' => 'k',
+  'ⓛ' => 'l',
+  'ⓜ' => 'm',
+  'ⓝ' => 'n',
+  'ⓞ' => 'o',
+  'ⓟ' => 'p',
+  'ⓠ' => 'q',
+  'ⓡ' => 'r',
+  'ⓢ' => 's',
+  'ⓣ' => 't',
+  'ⓤ' => 'u',
+  'ⓥ' => 'v',
+  'ⓦ' => 'w',
+  'ⓧ' => 'x',
+  'ⓨ' => 'y',
+  'ⓩ' => 'z',
+  '⓪' => '0',
+  '⨌' => '∫∫∫∫',
+  '⩴' => '::=',
+  '⩵' => '==',
+  '⩶' => '===',
+  'ⱼ' => 'j',
+  'ⱽ' => 'V',
+  'ⵯ' => 'ⵡ',
+  '⺟' => '母',
+  '⻳' => '龟',
+  '⼀' => '一',
+  '⼁' => '丨',
+  '⼂' => '丶',
+  '⼃' => '丿',
+  '⼄' => '乙',
+  '⼅' => '亅',
+  '⼆' => '二',
+  '⼇' => '亠',
+  '⼈' => '人',
+  '⼉' => '儿',
+  '⼊' => '入',
+  '⼋' => '八',
+  '⼌' => '冂',
+  '⼍' => '冖',
+  '⼎' => '冫',
+  '⼏' => '几',
+  '⼐' => '凵',
+  '⼑' => '刀',
+  '⼒' => '力',
+  '⼓' => '勹',
+  '⼔' => '匕',
+  '⼕' => '匚',
+  '⼖' => '匸',
+  '⼗' => '十',
+  '⼘' => '卜',
+  '⼙' => '卩',
+  '⼚' => '厂',
+  '⼛' => '厶',
+  '⼜' => '又',
+  '⼝' => '口',
+  '⼞' => '囗',
+  '⼟' => '土',
+  '⼠' => '士',
+  '⼡' => '夂',
+  '⼢' => '夊',
+  '⼣' => '夕',
+  '⼤' => '大',
+  '⼥' => '女',
+  '⼦' => '子',
+  '⼧' => '宀',
+  '⼨' => '寸',
+  '⼩' => '小',
+  '⼪' => '尢',
+  '⼫' => '尸',
+  '⼬' => '屮',
+  '⼭' => '山',
+  '⼮' => '巛',
+  '⼯' => '工',
+  '⼰' => '己',
+  '⼱' => '巾',
+  '⼲' => '干',
+  '⼳' => '幺',
+  '⼴' => '广',
+  '⼵' => '廴',
+  '⼶' => '廾',
+  '⼷' => '弋',
+  '⼸' => '弓',
+  '⼹' => '彐',
+  '⼺' => '彡',
+  '⼻' => '彳',
+  '⼼' => '心',
+  '⼽' => '戈',
+  '⼾' => '戶',
+  '⼿' => '手',
+  '⽀' => '支',
+  '⽁' => '攴',
+  '⽂' => '文',
+  '⽃' => '斗',
+  '⽄' => '斤',
+  '⽅' => '方',
+  '⽆' => '无',
+  '⽇' => '日',
+  '⽈' => '曰',
+  '⽉' => '月',
+  '⽊' => '木',
+  '⽋' => '欠',
+  '⽌' => '止',
+  '⽍' => '歹',
+  '⽎' => '殳',
+  '⽏' => '毋',
+  '⽐' => '比',
+  '⽑' => '毛',
+  '⽒' => '氏',
+  '⽓' => '气',
+  '⽔' => '水',
+  '⽕' => '火',
+  '⽖' => '爪',
+  '⽗' => '父',
+  '⽘' => '爻',
+  '⽙' => '爿',
+  '⽚' => '片',
+  '⽛' => '牙',
+  '⽜' => '牛',
+  '⽝' => '犬',
+  '⽞' => '玄',
+  '⽟' => '玉',
+  '⽠' => '瓜',
+  '⽡' => '瓦',
+  '⽢' => '甘',
+  '⽣' => '生',
+  '⽤' => '用',
+  '⽥' => '田',
+  '⽦' => '疋',
+  '⽧' => '疒',
+  '⽨' => '癶',
+  '⽩' => '白',
+  '⽪' => '皮',
+  '⽫' => '皿',
+  '⽬' => '目',
+  '⽭' => '矛',
+  '⽮' => '矢',
+  '⽯' => '石',
+  '⽰' => '示',
+  '⽱' => '禸',
+  '⽲' => '禾',
+  '⽳' => '穴',
+  '⽴' => '立',
+  '⽵' => '竹',
+  '⽶' => '米',
+  '⽷' => '糸',
+  '⽸' => '缶',
+  '⽹' => '网',
+  '⽺' => '羊',
+  '⽻' => '羽',
+  '⽼' => '老',
+  '⽽' => '而',
+  '⽾' => '耒',
+  '⽿' => '耳',
+  '⾀' => '聿',
+  '⾁' => '肉',
+  '⾂' => '臣',
+  '⾃' => '自',
+  '⾄' => '至',
+  '⾅' => '臼',
+  '⾆' => '舌',
+  '⾇' => '舛',
+  '⾈' => '舟',
+  '⾉' => '艮',
+  '⾊' => '色',
+  '⾋' => '艸',
+  '⾌' => '虍',
+  '⾍' => '虫',
+  '⾎' => '血',
+  '⾏' => '行',
+  '⾐' => '衣',
+  '⾑' => '襾',
+  '⾒' => '見',
+  '⾓' => '角',
+  '⾔' => '言',
+  '⾕' => '谷',
+  '⾖' => '豆',
+  '⾗' => '豕',
+  '⾘' => '豸',
+  '⾙' => '貝',
+  '⾚' => '赤',
+  '⾛' => '走',
+  '⾜' => '足',
+  '⾝' => '身',
+  '⾞' => '車',
+  '⾟' => '辛',
+  '⾠' => '辰',
+  '⾡' => '辵',
+  '⾢' => '邑',
+  '⾣' => '酉',
+  '⾤' => '釆',
+  '⾥' => '里',
+  '⾦' => '金',
+  '⾧' => '長',
+  '⾨' => '門',
+  '⾩' => '阜',
+  '⾪' => '隶',
+  '⾫' => '隹',
+  '⾬' => '雨',
+  '⾭' => '靑',
+  '⾮' => '非',
+  '⾯' => '面',
+  '⾰' => '革',
+  '⾱' => '韋',
+  '⾲' => '韭',
+  '⾳' => '音',
+  '⾴' => '頁',
+  '⾵' => '風',
+  '⾶' => '飛',
+  '⾷' => '食',
+  '⾸' => '首',
+  '⾹' => '香',
+  '⾺' => '馬',
+  '⾻' => '骨',
+  '⾼' => '高',
+  '⾽' => '髟',
+  '⾾' => '鬥',
+  '⾿' => '鬯',
+  '⿀' => '鬲',
+  '⿁' => '鬼',
+  '⿂' => '魚',
+  '⿃' => '鳥',
+  '⿄' => '鹵',
+  '⿅' => '鹿',
+  '⿆' => '麥',
+  '⿇' => '麻',
+  '⿈' => '黃',
+  '⿉' => '黍',
+  '⿊' => '黑',
+  '⿋' => '黹',
+  '⿌' => '黽',
+  '⿍' => '鼎',
+  '⿎' => '鼓',
+  '⿏' => '鼠',
+  '⿐' => '鼻',
+  '⿑' => '齊',
+  '⿒' => '齒',
+  '⿓' => '龍',
+  '⿔' => '龜',
+  '⿕' => '龠',
+  ' ' => ' ',
+  '〶' => '〒',
+  '〸' => '十',
+  '〹' => '卄',
+  '〺' => '卅',
+  '゛' => ' ゙',
+  '゜' => ' ゚',
+  'ゟ' => 'より',
+  'ヿ' => 'コト',
+  'ㄱ' => 'ᄀ',
+  'ㄲ' => 'ᄁ',
+  'ㄳ' => 'ᆪ',
+  'ㄴ' => 'ᄂ',
+  'ㄵ' => 'ᆬ',
+  'ㄶ' => 'ᆭ',
+  'ㄷ' => 'ᄃ',
+  'ㄸ' => 'ᄄ',
+  'ㄹ' => 'ᄅ',
+  'ㄺ' => 'ᆰ',
+  'ㄻ' => 'ᆱ',
+  'ㄼ' => 'ᆲ',
+  'ㄽ' => 'ᆳ',
+  'ㄾ' => 'ᆴ',
+  'ㄿ' => 'ᆵ',
+  'ㅀ' => 'ᄚ',
+  'ㅁ' => 'ᄆ',
+  'ㅂ' => 'ᄇ',
+  'ㅃ' => 'ᄈ',
+  'ㅄ' => 'ᄡ',
+  'ㅅ' => 'ᄉ',
+  'ㅆ' => 'ᄊ',
+  'ㅇ' => 'ᄋ',
+  'ㅈ' => 'ᄌ',
+  'ㅉ' => 'ᄍ',
+  'ㅊ' => 'ᄎ',
+  'ㅋ' => 'ᄏ',
+  'ㅌ' => 'ᄐ',
+  'ㅍ' => 'ᄑ',
+  'ㅎ' => 'ᄒ',
+  'ㅏ' => 'ᅡ',
+  'ㅐ' => 'ᅢ',
+  'ㅑ' => 'ᅣ',
+  'ㅒ' => 'ᅤ',
+  'ㅓ' => 'ᅥ',
+  'ㅔ' => 'ᅦ',
+  'ㅕ' => 'ᅧ',
+  'ㅖ' => 'ᅨ',
+  'ㅗ' => 'ᅩ',
+  'ㅘ' => 'ᅪ',
+  'ㅙ' => 'ᅫ',
+  'ㅚ' => 'ᅬ',
+  'ㅛ' => 'ᅭ',
+  'ㅜ' => 'ᅮ',
+  'ㅝ' => 'ᅯ',
+  'ㅞ' => 'ᅰ',
+  'ㅟ' => 'ᅱ',
+  'ㅠ' => 'ᅲ',
+  'ㅡ' => 'ᅳ',
+  'ㅢ' => 'ᅴ',
+  'ㅣ' => 'ᅵ',
+  'ㅤ' => 'ᅠ',
+  'ㅥ' => 'ᄔ',
+  'ㅦ' => 'ᄕ',
+  'ㅧ' => 'ᇇ',
+  'ㅨ' => 'ᇈ',
+  'ㅩ' => 'ᇌ',
+  'ㅪ' => 'ᇎ',
+  'ㅫ' => 'ᇓ',
+  'ㅬ' => 'ᇗ',
+  'ㅭ' => 'ᇙ',
+  'ㅮ' => 'ᄜ',
+  'ㅯ' => 'ᇝ',
+  'ㅰ' => 'ᇟ',
+  'ㅱ' => 'ᄝ',
+  'ㅲ' => 'ᄞ',
+  'ㅳ' => 'ᄠ',
+  'ㅴ' => 'ᄢ',
+  'ㅵ' => 'ᄣ',
+  'ㅶ' => 'ᄧ',
+  'ㅷ' => 'ᄩ',
+  'ㅸ' => 'ᄫ',
+  'ㅹ' => 'ᄬ',
+  'ㅺ' => 'ᄭ',
+  'ㅻ' => 'ᄮ',
+  'ㅼ' => 'ᄯ',
+  'ㅽ' => 'ᄲ',
+  'ㅾ' => 'ᄶ',
+  'ㅿ' => 'ᅀ',
+  'ㆀ' => 'ᅇ',
+  'ㆁ' => 'ᅌ',
+  'ㆂ' => 'ᇱ',
+  'ㆃ' => 'ᇲ',
+  'ㆄ' => 'ᅗ',
+  'ㆅ' => 'ᅘ',
+  'ㆆ' => 'ᅙ',
+  'ㆇ' => 'ᆄ',
+  'ㆈ' => 'ᆅ',
+  'ㆉ' => 'ᆈ',
+  'ㆊ' => 'ᆑ',
+  'ㆋ' => 'ᆒ',
+  'ㆌ' => 'ᆔ',
+  'ㆍ' => 'ᆞ',
+  'ㆎ' => 'ᆡ',
+  '㆒' => '一',
+  '㆓' => '二',
+  '㆔' => '三',
+  '㆕' => '四',
+  '㆖' => '上',
+  '㆗' => '中',
+  '㆘' => '下',
+  '㆙' => '甲',
+  '㆚' => '乙',
+  '㆛' => '丙',
+  '㆜' => '丁',
+  '㆝' => '天',
+  '㆞' => '地',
+  '㆟' => '人',
+  '㈀' => '(ᄀ)',
+  '㈁' => '(ᄂ)',
+  '㈂' => '(ᄃ)',
+  '㈃' => '(ᄅ)',
+  '㈄' => '(ᄆ)',
+  '㈅' => '(ᄇ)',
+  '㈆' => '(ᄉ)',
+  '㈇' => '(ᄋ)',
+  '㈈' => '(ᄌ)',
+  '㈉' => '(ᄎ)',
+  '㈊' => '(ᄏ)',
+  '㈋' => '(ᄐ)',
+  '㈌' => '(ᄑ)',
+  '㈍' => '(ᄒ)',
+  '㈎' => '(가)',
+  '㈏' => '(나)',
+  '㈐' => '(다)',
+  '㈑' => '(라)',
+  '㈒' => '(마)',
+  '㈓' => '(바)',
+  '㈔' => '(사)',
+  '㈕' => '(아)',
+  '㈖' => '(자)',
+  '㈗' => '(차)',
+  '㈘' => '(카)',
+  '㈙' => '(타)',
+  '㈚' => '(파)',
+  '㈛' => '(하)',
+  '㈜' => '(주)',
+  '㈝' => '(오전)',
+  '㈞' => '(오후)',
+  '㈠' => '(一)',
+  '㈡' => '(二)',
+  '㈢' => '(三)',
+  '㈣' => '(四)',
+  '㈤' => '(五)',
+  '㈥' => '(六)',
+  '㈦' => '(七)',
+  '㈧' => '(八)',
+  '㈨' => '(九)',
+  '㈩' => '(十)',
+  '㈪' => '(月)',
+  '㈫' => '(火)',
+  '㈬' => '(水)',
+  '㈭' => '(木)',
+  '㈮' => '(金)',
+  '㈯' => '(土)',
+  '㈰' => '(日)',
+  '㈱' => '(株)',
+  '㈲' => '(有)',
+  '㈳' => '(社)',
+  '㈴' => '(名)',
+  '㈵' => '(特)',
+  '㈶' => '(財)',
+  '㈷' => '(祝)',
+  '㈸' => '(労)',
+  '㈹' => '(代)',
+  '㈺' => '(呼)',
+  '㈻' => '(学)',
+  '㈼' => '(監)',
+  '㈽' => '(企)',
+  '㈾' => '(資)',
+  '㈿' => '(協)',
+  '㉀' => '(祭)',
+  '㉁' => '(休)',
+  '㉂' => '(自)',
+  '㉃' => '(至)',
+  '㉄' => '問',
+  '㉅' => '幼',
+  '㉆' => '文',
+  '㉇' => '箏',
+  '㉐' => 'PTE',
+  '㉑' => '21',
+  '㉒' => '22',
+  '㉓' => '23',
+  '㉔' => '24',
+  '㉕' => '25',
+  '㉖' => '26',
+  '㉗' => '27',
+  '㉘' => '28',
+  '㉙' => '29',
+  '㉚' => '30',
+  '㉛' => '31',
+  '㉜' => '32',
+  '㉝' => '33',
+  '㉞' => '34',
+  '㉟' => '35',
+  '㉠' => 'ᄀ',
+  '㉡' => 'ᄂ',
+  '㉢' => 'ᄃ',
+  '㉣' => 'ᄅ',
+  '㉤' => 'ᄆ',
+  '㉥' => 'ᄇ',
+  '㉦' => 'ᄉ',
+  '㉧' => 'ᄋ',
+  '㉨' => 'ᄌ',
+  '㉩' => 'ᄎ',
+  '㉪' => 'ᄏ',
+  '㉫' => 'ᄐ',
+  '㉬' => 'ᄑ',
+  '㉭' => 'ᄒ',
+  '㉮' => '가',
+  '㉯' => '나',
+  '㉰' => '다',
+  '㉱' => '라',
+  '㉲' => '마',
+  '㉳' => '바',
+  '㉴' => '사',
+  '㉵' => '아',
+  '㉶' => '자',
+  '㉷' => '차',
+  '㉸' => '카',
+  '㉹' => '타',
+  '㉺' => '파',
+  '㉻' => '하',
+  '㉼' => '참고',
+  '㉽' => '주의',
+  '㉾' => '우',
+  '㊀' => '一',
+  '㊁' => '二',
+  '㊂' => '三',
+  '㊃' => '四',
+  '㊄' => '五',
+  '㊅' => '六',
+  '㊆' => '七',
+  '㊇' => '八',
+  '㊈' => '九',
+  '㊉' => '十',
+  '㊊' => '月',
+  '㊋' => '火',
+  '㊌' => '水',
+  '㊍' => '木',
+  '㊎' => '金',
+  '㊏' => '土',
+  '㊐' => '日',
+  '㊑' => '株',
+  '㊒' => '有',
+  '㊓' => '社',
+  '㊔' => '名',
+  '㊕' => '特',
+  '㊖' => '財',
+  '㊗' => '祝',
+  '㊘' => '労',
+  '㊙' => '秘',
+  '㊚' => '男',
+  '㊛' => '女',
+  '㊜' => '適',
+  '㊝' => '優',
+  '㊞' => '印',
+  '㊟' => '注',
+  '㊠' => '項',
+  '㊡' => '休',
+  '㊢' => '写',
+  '㊣' => '正',
+  '㊤' => '上',
+  '㊥' => '中',
+  '㊦' => '下',
+  '㊧' => '左',
+  '㊨' => '右',
+  '㊩' => '医',
+  '㊪' => '宗',
+  '㊫' => '学',
+  '㊬' => '監',
+  '㊭' => '企',
+  '㊮' => '資',
+  '㊯' => '協',
+  '㊰' => '夜',
+  '㊱' => '36',
+  '㊲' => '37',
+  '㊳' => '38',
+  '㊴' => '39',
+  '㊵' => '40',
+  '㊶' => '41',
+  '㊷' => '42',
+  '㊸' => '43',
+  '㊹' => '44',
+  '㊺' => '45',
+  '㊻' => '46',
+  '㊼' => '47',
+  '㊽' => '48',
+  '㊾' => '49',
+  '㊿' => '50',
+  '㋀' => '1月',
+  '㋁' => '2月',
+  '㋂' => '3月',
+  '㋃' => '4月',
+  '㋄' => '5月',
+  '㋅' => '6月',
+  '㋆' => '7月',
+  '㋇' => '8月',
+  '㋈' => '9月',
+  '㋉' => '10月',
+  '㋊' => '11月',
+  '㋋' => '12月',
+  '㋌' => 'Hg',
+  '㋍' => 'erg',
+  '㋎' => 'eV',
+  '㋏' => 'LTD',
+  '㋐' => 'ア',
+  '㋑' => 'イ',
+  '㋒' => 'ウ',
+  '㋓' => 'エ',
+  '㋔' => 'オ',
+  '㋕' => 'カ',
+  '㋖' => 'キ',
+  '㋗' => 'ク',
+  '㋘' => 'ケ',
+  '㋙' => 'コ',
+  '㋚' => 'サ',
+  '㋛' => 'シ',
+  '㋜' => 'ス',
+  '㋝' => 'セ',
+  '㋞' => 'ソ',
+  '㋟' => 'タ',
+  '㋠' => 'チ',
+  '㋡' => 'ツ',
+  '㋢' => 'テ',
+  '㋣' => 'ト',
+  '㋤' => 'ナ',
+  '㋥' => 'ニ',
+  '㋦' => 'ヌ',
+  '㋧' => 'ネ',
+  '㋨' => 'ノ',
+  '㋩' => 'ハ',
+  '㋪' => 'ヒ',
+  '㋫' => 'フ',
+  '㋬' => 'ヘ',
+  '㋭' => 'ホ',
+  '㋮' => 'マ',
+  '㋯' => 'ミ',
+  '㋰' => 'ム',
+  '㋱' => 'メ',
+  '㋲' => 'モ',
+  '㋳' => 'ヤ',
+  '㋴' => 'ユ',
+  '㋵' => 'ヨ',
+  '㋶' => 'ラ',
+  '㋷' => 'リ',
+  '㋸' => 'ル',
+  '㋹' => 'レ',
+  '㋺' => 'ロ',
+  '㋻' => 'ワ',
+  '㋼' => 'ヰ',
+  '㋽' => 'ヱ',
+  '㋾' => 'ヲ',
+  '㋿' => '令和',
+  '㌀' => 'アパート',
+  '㌁' => 'アルファ',
+  '㌂' => 'アンペア',
+  '㌃' => 'アール',
+  '㌄' => 'イニング',
+  '㌅' => 'インチ',
+  '㌆' => 'ウォン',
+  '㌇' => 'エスクード',
+  '㌈' => 'エーカー',
+  '㌉' => 'オンス',
+  '㌊' => 'オーム',
+  '㌋' => 'カイリ',
+  '㌌' => 'カラット',
+  '㌍' => 'カロリー',
+  '㌎' => 'ガロン',
+  '㌏' => 'ガンマ',
+  '㌐' => 'ギガ',
+  '㌑' => 'ギニー',
+  '㌒' => 'キュリー',
+  '㌓' => 'ギルダー',
+  '㌔' => 'キロ',
+  '㌕' => 'キログラム',
+  '㌖' => 'キロメートル',
+  '㌗' => 'キロワット',
+  '㌘' => 'グラム',
+  '㌙' => 'グラムトン',
+  '㌚' => 'クルゼイロ',
+  '㌛' => 'クローネ',
+  '㌜' => 'ケース',
+  '㌝' => 'コルナ',
+  '㌞' => 'コーポ',
+  '㌟' => 'サイクル',
+  '㌠' => 'サンチーム',
+  '㌡' => 'シリング',
+  '㌢' => 'センチ',
+  '㌣' => 'セント',
+  '㌤' => 'ダース',
+  '㌥' => 'デシ',
+  '㌦' => 'ドル',
+  '㌧' => 'トン',
+  '㌨' => 'ナノ',
+  '㌩' => 'ノット',
+  '㌪' => 'ハイツ',
+  '㌫' => 'パーセント',
+  '㌬' => 'パーツ',
+  '㌭' => 'バーレル',
+  '㌮' => 'ピアストル',
+  '㌯' => 'ピクル',
+  '㌰' => 'ピコ',
+  '㌱' => 'ビル',
+  '㌲' => 'ファラッド',
+  '㌳' => 'フィート',
+  '㌴' => 'ブッシェル',
+  '㌵' => 'フラン',
+  '㌶' => 'ヘクタール',
+  '㌷' => 'ペソ',
+  '㌸' => 'ペニヒ',
+  '㌹' => 'ヘルツ',
+  '㌺' => 'ペンス',
+  '㌻' => 'ページ',
+  '㌼' => 'ベータ',
+  '㌽' => 'ポイント',
+  '㌾' => 'ボルト',
+  '㌿' => 'ホン',
+  '㍀' => 'ポンド',
+  '㍁' => 'ホール',
+  '㍂' => 'ホーン',
+  '㍃' => 'マイクロ',
+  '㍄' => 'マイル',
+  '㍅' => 'マッハ',
+  '㍆' => 'マルク',
+  '㍇' => 'マンション',
+  '㍈' => 'ミクロン',
+  '㍉' => 'ミリ',
+  '㍊' => 'ミリバール',
+  '㍋' => 'メガ',
+  '㍌' => 'メガトン',
+  '㍍' => 'メートル',
+  '㍎' => 'ヤード',
+  '㍏' => 'ヤール',
+  '㍐' => 'ユアン',
+  '㍑' => 'リットル',
+  '㍒' => 'リラ',
+  '㍓' => 'ルピー',
+  '㍔' => 'ルーブル',
+  '㍕' => 'レム',
+  '㍖' => 'レントゲン',
+  '㍗' => 'ワット',
+  '㍘' => '0点',
+  '㍙' => '1点',
+  '㍚' => '2点',
+  '㍛' => '3点',
+  '㍜' => '4点',
+  '㍝' => '5点',
+  '㍞' => '6点',
+  '㍟' => '7点',
+  '㍠' => '8点',
+  '㍡' => '9点',
+  '㍢' => '10点',
+  '㍣' => '11点',
+  '㍤' => '12点',
+  '㍥' => '13点',
+  '㍦' => '14点',
+  '㍧' => '15点',
+  '㍨' => '16点',
+  '㍩' => '17点',
+  '㍪' => '18点',
+  '㍫' => '19点',
+  '㍬' => '20点',
+  '㍭' => '21点',
+  '㍮' => '22点',
+  '㍯' => '23点',
+  '㍰' => '24点',
+  '㍱' => 'hPa',
+  '㍲' => 'da',
+  '㍳' => 'AU',
+  '㍴' => 'bar',
+  '㍵' => 'oV',
+  '㍶' => 'pc',
+  '㍷' => 'dm',
+  '㍸' => 'dm2',
+  '㍹' => 'dm3',
+  '㍺' => 'IU',
+  '㍻' => '平成',
+  '㍼' => '昭和',
+  '㍽' => '大正',
+  '㍾' => '明治',
+  '㍿' => '株式会社',
+  '㎀' => 'pA',
+  '㎁' => 'nA',
+  '㎂' => 'μA',
+  '㎃' => 'mA',
+  '㎄' => 'kA',
+  '㎅' => 'KB',
+  '㎆' => 'MB',
+  '㎇' => 'GB',
+  '㎈' => 'cal',
+  '㎉' => 'kcal',
+  '㎊' => 'pF',
+  '㎋' => 'nF',
+  '㎌' => 'μF',
+  '㎍' => 'μg',
+  '㎎' => 'mg',
+  '㎏' => 'kg',
+  '㎐' => 'Hz',
+  '㎑' => 'kHz',
+  '㎒' => 'MHz',
+  '㎓' => 'GHz',
+  '㎔' => 'THz',
+  '㎕' => 'μl',
+  '㎖' => 'ml',
+  '㎗' => 'dl',
+  '㎘' => 'kl',
+  '㎙' => 'fm',
+  '㎚' => 'nm',
+  '㎛' => 'μm',
+  '㎜' => 'mm',
+  '㎝' => 'cm',
+  '㎞' => 'km',
+  '㎟' => 'mm2',
+  '㎠' => 'cm2',
+  '㎡' => 'm2',
+  '㎢' => 'km2',
+  '㎣' => 'mm3',
+  '㎤' => 'cm3',
+  '㎥' => 'm3',
+  '㎦' => 'km3',
+  '㎧' => 'm∕s',
+  '㎨' => 'm∕s2',
+  '㎩' => 'Pa',
+  '㎪' => 'kPa',
+  '㎫' => 'MPa',
+  '㎬' => 'GPa',
+  '㎭' => 'rad',
+  '㎮' => 'rad∕s',
+  '㎯' => 'rad∕s2',
+  '㎰' => 'ps',
+  '㎱' => 'ns',
+  '㎲' => 'μs',
+  '㎳' => 'ms',
+  '㎴' => 'pV',
+  '㎵' => 'nV',
+  '㎶' => 'μV',
+  '㎷' => 'mV',
+  '㎸' => 'kV',
+  '㎹' => 'MV',
+  '㎺' => 'pW',
+  '㎻' => 'nW',
+  '㎼' => 'μW',
+  '㎽' => 'mW',
+  '㎾' => 'kW',
+  '㎿' => 'MW',
+  '㏀' => 'kΩ',
+  '㏁' => 'MΩ',
+  '㏂' => 'a.m.',
+  '㏃' => 'Bq',
+  '㏄' => 'cc',
+  '㏅' => 'cd',
+  '㏆' => 'C∕kg',
+  '㏇' => 'Co.',
+  '㏈' => 'dB',
+  '㏉' => 'Gy',
+  '㏊' => 'ha',
+  '㏋' => 'HP',
+  '㏌' => 'in',
+  '㏍' => 'KK',
+  '㏎' => 'KM',
+  '㏏' => 'kt',
+  '㏐' => 'lm',
+  '㏑' => 'ln',
+  '㏒' => 'log',
+  '㏓' => 'lx',
+  '㏔' => 'mb',
+  '㏕' => 'mil',
+  '㏖' => 'mol',
+  '㏗' => 'PH',
+  '㏘' => 'p.m.',
+  '㏙' => 'PPM',
+  '㏚' => 'PR',
+  '㏛' => 'sr',
+  '㏜' => 'Sv',
+  '㏝' => 'Wb',
+  '㏞' => 'V∕m',
+  '㏟' => 'A∕m',
+  '㏠' => '1日',
+  '㏡' => '2日',
+  '㏢' => '3日',
+  '㏣' => '4日',
+  '㏤' => '5日',
+  '㏥' => '6日',
+  '㏦' => '7日',
+  '㏧' => '8日',
+  '㏨' => '9日',
+  '㏩' => '10日',
+  '㏪' => '11日',
+  '㏫' => '12日',
+  '㏬' => '13日',
+  '㏭' => '14日',
+  '㏮' => '15日',
+  '㏯' => '16日',
+  '㏰' => '17日',
+  '㏱' => '18日',
+  '㏲' => '19日',
+  '㏳' => '20日',
+  '㏴' => '21日',
+  '㏵' => '22日',
+  '㏶' => '23日',
+  '㏷' => '24日',
+  '㏸' => '25日',
+  '㏹' => '26日',
+  '㏺' => '27日',
+  '㏻' => '28日',
+  '㏼' => '29日',
+  '㏽' => '30日',
+  '㏾' => '31日',
+  '㏿' => 'gal',
+  'ꚜ' => 'ъ',
+  'ꚝ' => 'ь',
+  'ꝰ' => 'ꝯ',
+  'ꟸ' => 'Ħ',
+  'ꟹ' => 'œ',
+  'ꭜ' => 'ꜧ',
+  'ꭝ' => 'ꬷ',
+  'ꭞ' => 'ɫ',
+  'ꭟ' => 'ꭒ',
+  'ꭩ' => 'ʍ',
+  'ff' => 'ff',
+  'fi' => 'fi',
+  'fl' => 'fl',
+  'ffi' => 'ffi',
+  'ffl' => 'ffl',
+  'ſt' => 'st',
+  'st' => 'st',
+  'ﬓ' => 'մն',
+  'ﬔ' => 'մե',
+  'ﬕ' => 'մի',
+  'ﬖ' => 'վն',
+  'ﬗ' => 'մխ',
+  'ﬠ' => 'ע',
+  'ﬡ' => 'א',
+  'ﬢ' => 'ד',
+  'ﬣ' => 'ה',
+  'ﬤ' => 'כ',
+  'ﬥ' => 'ל',
+  'ﬦ' => 'ם',
+  'ﬧ' => 'ר',
+  'ﬨ' => 'ת',
+  '﬩' => '+',
+  'ﭏ' => 'אל',
+  'ﭐ' => 'ٱ',
+  'ﭑ' => 'ٱ',
+  'ﭒ' => 'ٻ',
+  'ﭓ' => 'ٻ',
+  'ﭔ' => 'ٻ',
+  'ﭕ' => 'ٻ',
+  'ﭖ' => 'پ',
+  'ﭗ' => 'پ',
+  'ﭘ' => 'پ',
+  'ﭙ' => 'پ',
+  'ﭚ' => 'ڀ',
+  'ﭛ' => 'ڀ',
+  'ﭜ' => 'ڀ',
+  'ﭝ' => 'ڀ',
+  'ﭞ' => 'ٺ',
+  'ﭟ' => 'ٺ',
+  'ﭠ' => 'ٺ',
+  'ﭡ' => 'ٺ',
+  'ﭢ' => 'ٿ',
+  'ﭣ' => 'ٿ',
+  'ﭤ' => 'ٿ',
+  'ﭥ' => 'ٿ',
+  'ﭦ' => 'ٹ',
+  'ﭧ' => 'ٹ',
+  'ﭨ' => 'ٹ',
+  'ﭩ' => 'ٹ',
+  'ﭪ' => 'ڤ',
+  'ﭫ' => 'ڤ',
+  'ﭬ' => 'ڤ',
+  'ﭭ' => 'ڤ',
+  'ﭮ' => 'ڦ',
+  'ﭯ' => 'ڦ',
+  'ﭰ' => 'ڦ',
+  'ﭱ' => 'ڦ',
+  'ﭲ' => 'ڄ',
+  'ﭳ' => 'ڄ',
+  'ﭴ' => 'ڄ',
+  'ﭵ' => 'ڄ',
+  'ﭶ' => 'ڃ',
+  'ﭷ' => 'ڃ',
+  'ﭸ' => 'ڃ',
+  'ﭹ' => 'ڃ',
+  'ﭺ' => 'چ',
+  'ﭻ' => 'چ',
+  'ﭼ' => 'چ',
+  'ﭽ' => 'چ',
+  'ﭾ' => 'ڇ',
+  'ﭿ' => 'ڇ',
+  'ﮀ' => 'ڇ',
+  'ﮁ' => 'ڇ',
+  'ﮂ' => 'ڍ',
+  'ﮃ' => 'ڍ',
+  'ﮄ' => 'ڌ',
+  'ﮅ' => 'ڌ',
+  'ﮆ' => 'ڎ',
+  'ﮇ' => 'ڎ',
+  'ﮈ' => 'ڈ',
+  'ﮉ' => 'ڈ',
+  'ﮊ' => 'ژ',
+  'ﮋ' => 'ژ',
+  'ﮌ' => 'ڑ',
+  'ﮍ' => 'ڑ',
+  'ﮎ' => 'ک',
+  'ﮏ' => 'ک',
+  'ﮐ' => 'ک',
+  'ﮑ' => 'ک',
+  'ﮒ' => 'گ',
+  'ﮓ' => 'گ',
+  'ﮔ' => 'گ',
+  'ﮕ' => 'گ',
+  'ﮖ' => 'ڳ',
+  'ﮗ' => 'ڳ',
+  'ﮘ' => 'ڳ',
+  'ﮙ' => 'ڳ',
+  'ﮚ' => 'ڱ',
+  'ﮛ' => 'ڱ',
+  'ﮜ' => 'ڱ',
+  'ﮝ' => 'ڱ',
+  'ﮞ' => 'ں',
+  'ﮟ' => 'ں',
+  'ﮠ' => 'ڻ',
+  'ﮡ' => 'ڻ',
+  'ﮢ' => 'ڻ',
+  'ﮣ' => 'ڻ',
+  'ﮤ' => 'ۀ',
+  'ﮥ' => 'ۀ',
+  'ﮦ' => 'ہ',
+  'ﮧ' => 'ہ',
+  'ﮨ' => 'ہ',
+  'ﮩ' => 'ہ',
+  'ﮪ' => 'ھ',
+  'ﮫ' => 'ھ',
+  'ﮬ' => 'ھ',
+  'ﮭ' => 'ھ',
+  'ﮮ' => 'ے',
+  'ﮯ' => 'ے',
+  'ﮰ' => 'ۓ',
+  'ﮱ' => 'ۓ',
+  'ﯓ' => 'ڭ',
+  'ﯔ' => 'ڭ',
+  'ﯕ' => 'ڭ',
+  'ﯖ' => 'ڭ',
+  'ﯗ' => 'ۇ',
+  'ﯘ' => 'ۇ',
+  'ﯙ' => 'ۆ',
+  'ﯚ' => 'ۆ',
+  'ﯛ' => 'ۈ',
+  'ﯜ' => 'ۈ',
+  'ﯝ' => 'ۇٴ',
+  'ﯞ' => 'ۋ',
+  'ﯟ' => 'ۋ',
+  'ﯠ' => 'ۅ',
+  'ﯡ' => 'ۅ',
+  'ﯢ' => 'ۉ',
+  'ﯣ' => 'ۉ',
+  'ﯤ' => 'ې',
+  'ﯥ' => 'ې',
+  'ﯦ' => 'ې',
+  'ﯧ' => 'ې',
+  'ﯨ' => 'ى',
+  'ﯩ' => 'ى',
+  'ﯪ' => 'ئا',
+  'ﯫ' => 'ئا',
+  'ﯬ' => 'ئە',
+  'ﯭ' => 'ئە',
+  'ﯮ' => 'ئو',
+  'ﯯ' => 'ئو',
+  'ﯰ' => 'ئۇ',
+  'ﯱ' => 'ئۇ',
+  'ﯲ' => 'ئۆ',
+  'ﯳ' => 'ئۆ',
+  'ﯴ' => 'ئۈ',
+  'ﯵ' => 'ئۈ',
+  'ﯶ' => 'ئې',
+  'ﯷ' => 'ئې',
+  'ﯸ' => 'ئې',
+  'ﯹ' => 'ئى',
+  'ﯺ' => 'ئى',
+  'ﯻ' => 'ئى',
+  'ﯼ' => 'ی',
+  'ﯽ' => 'ی',
+  'ﯾ' => 'ی',
+  'ﯿ' => 'ی',
+  'ﰀ' => 'ئج',
+  'ﰁ' => 'ئح',
+  'ﰂ' => 'ئم',
+  'ﰃ' => 'ئى',
+  'ﰄ' => 'ئي',
+  'ﰅ' => 'بج',
+  'ﰆ' => 'بح',
+  'ﰇ' => 'بخ',
+  'ﰈ' => 'بم',
+  'ﰉ' => 'بى',
+  'ﰊ' => 'بي',
+  'ﰋ' => 'تج',
+  'ﰌ' => 'تح',
+  'ﰍ' => 'تخ',
+  'ﰎ' => 'تم',
+  'ﰏ' => 'تى',
+  'ﰐ' => 'تي',
+  'ﰑ' => 'ثج',
+  'ﰒ' => 'ثم',
+  'ﰓ' => 'ثى',
+  'ﰔ' => 'ثي',
+  'ﰕ' => 'جح',
+  'ﰖ' => 'جم',
+  'ﰗ' => 'حج',
+  'ﰘ' => 'حم',
+  'ﰙ' => 'خج',
+  'ﰚ' => 'خح',
+  'ﰛ' => 'خم',
+  'ﰜ' => 'سج',
+  'ﰝ' => 'سح',
+  'ﰞ' => 'سخ',
+  'ﰟ' => 'سم',
+  'ﰠ' => 'صح',
+  'ﰡ' => 'صم',
+  'ﰢ' => 'ضج',
+  'ﰣ' => 'ضح',
+  'ﰤ' => 'ضخ',
+  'ﰥ' => 'ضم',
+  'ﰦ' => 'طح',
+  'ﰧ' => 'طم',
+  'ﰨ' => 'ظم',
+  'ﰩ' => 'عج',
+  'ﰪ' => 'عم',
+  'ﰫ' => 'غج',
+  'ﰬ' => 'غم',
+  'ﰭ' => 'فج',
+  'ﰮ' => 'فح',
+  'ﰯ' => 'فخ',
+  'ﰰ' => 'فم',
+  'ﰱ' => 'فى',
+  'ﰲ' => 'في',
+  'ﰳ' => 'قح',
+  'ﰴ' => 'قم',
+  'ﰵ' => 'قى',
+  'ﰶ' => 'قي',
+  'ﰷ' => 'كا',
+  'ﰸ' => 'كج',
+  'ﰹ' => 'كح',
+  'ﰺ' => 'كخ',
+  'ﰻ' => 'كل',
+  'ﰼ' => 'كم',
+  'ﰽ' => 'كى',
+  'ﰾ' => 'كي',
+  'ﰿ' => 'لج',
+  'ﱀ' => 'لح',
+  'ﱁ' => 'لخ',
+  'ﱂ' => 'لم',
+  'ﱃ' => 'لى',
+  'ﱄ' => 'لي',
+  'ﱅ' => 'مج',
+  'ﱆ' => 'مح',
+  'ﱇ' => 'مخ',
+  'ﱈ' => 'مم',
+  'ﱉ' => 'مى',
+  'ﱊ' => 'مي',
+  'ﱋ' => 'نج',
+  'ﱌ' => 'نح',
+  'ﱍ' => 'نخ',
+  'ﱎ' => 'نم',
+  'ﱏ' => 'نى',
+  'ﱐ' => 'ني',
+  'ﱑ' => 'هج',
+  'ﱒ' => 'هم',
+  'ﱓ' => 'هى',
+  'ﱔ' => 'هي',
+  'ﱕ' => 'يج',
+  'ﱖ' => 'يح',
+  'ﱗ' => 'يخ',
+  'ﱘ' => 'يم',
+  'ﱙ' => 'يى',
+  'ﱚ' => 'يي',
+  'ﱛ' => 'ذٰ',
+  'ﱜ' => 'رٰ',
+  'ﱝ' => 'ىٰ',
+  'ﱞ' => ' ٌّ',
+  'ﱟ' => ' ٍّ',
+  'ﱠ' => ' َّ',
+  'ﱡ' => ' ُّ',
+  'ﱢ' => ' ِّ',
+  'ﱣ' => ' ّٰ',
+  'ﱤ' => 'ئر',
+  'ﱥ' => 'ئز',
+  'ﱦ' => 'ئم',
+  'ﱧ' => 'ئن',
+  'ﱨ' => 'ئى',
+  'ﱩ' => 'ئي',
+  'ﱪ' => 'بر',
+  'ﱫ' => 'بز',
+  'ﱬ' => 'بم',
+  'ﱭ' => 'بن',
+  'ﱮ' => 'بى',
+  'ﱯ' => 'بي',
+  'ﱰ' => 'تر',
+  'ﱱ' => 'تز',
+  'ﱲ' => 'تم',
+  'ﱳ' => 'تن',
+  'ﱴ' => 'تى',
+  'ﱵ' => 'تي',
+  'ﱶ' => 'ثر',
+  'ﱷ' => 'ثز',
+  'ﱸ' => 'ثم',
+  'ﱹ' => 'ثن',
+  'ﱺ' => 'ثى',
+  'ﱻ' => 'ثي',
+  'ﱼ' => 'فى',
+  'ﱽ' => 'في',
+  'ﱾ' => 'قى',
+  'ﱿ' => 'قي',
+  'ﲀ' => 'كا',
+  'ﲁ' => 'كل',
+  'ﲂ' => 'كم',
+  'ﲃ' => 'كى',
+  'ﲄ' => 'كي',
+  'ﲅ' => 'لم',
+  'ﲆ' => 'لى',
+  'ﲇ' => 'لي',
+  'ﲈ' => 'ما',
+  'ﲉ' => 'مم',
+  'ﲊ' => 'نر',
+  'ﲋ' => 'نز',
+  'ﲌ' => 'نم',
+  'ﲍ' => 'نن',
+  'ﲎ' => 'نى',
+  'ﲏ' => 'ني',
+  'ﲐ' => 'ىٰ',
+  'ﲑ' => 'ير',
+  'ﲒ' => 'يز',
+  'ﲓ' => 'يم',
+  'ﲔ' => 'ين',
+  'ﲕ' => 'يى',
+  'ﲖ' => 'يي',
+  'ﲗ' => 'ئج',
+  'ﲘ' => 'ئح',
+  'ﲙ' => 'ئخ',
+  'ﲚ' => 'ئم',
+  'ﲛ' => 'ئه',
+  'ﲜ' => 'بج',
+  'ﲝ' => 'بح',
+  'ﲞ' => 'بخ',
+  'ﲟ' => 'بم',
+  'ﲠ' => 'به',
+  'ﲡ' => 'تج',
+  'ﲢ' => 'تح',
+  'ﲣ' => 'تخ',
+  'ﲤ' => 'تم',
+  'ﲥ' => 'ته',
+  'ﲦ' => 'ثم',
+  'ﲧ' => 'جح',
+  'ﲨ' => 'جم',
+  'ﲩ' => 'حج',
+  'ﲪ' => 'حم',
+  'ﲫ' => 'خج',
+  'ﲬ' => 'خم',
+  'ﲭ' => 'سج',
+  'ﲮ' => 'سح',
+  'ﲯ' => 'سخ',
+  'ﲰ' => 'سم',
+  'ﲱ' => 'صح',
+  'ﲲ' => 'صخ',
+  'ﲳ' => 'صم',
+  'ﲴ' => 'ضج',
+  'ﲵ' => 'ضح',
+  'ﲶ' => 'ضخ',
+  'ﲷ' => 'ضم',
+  'ﲸ' => 'طح',
+  'ﲹ' => 'ظم',
+  'ﲺ' => 'عج',
+  'ﲻ' => 'عم',
+  'ﲼ' => 'غج',
+  'ﲽ' => 'غم',
+  'ﲾ' => 'فج',
+  'ﲿ' => 'فح',
+  'ﳀ' => 'فخ',
+  'ﳁ' => 'فم',
+  'ﳂ' => 'قح',
+  'ﳃ' => 'قم',
+  'ﳄ' => 'كج',
+  'ﳅ' => 'كح',
+  'ﳆ' => 'كخ',
+  'ﳇ' => 'كل',
+  'ﳈ' => 'كم',
+  'ﳉ' => 'لج',
+  'ﳊ' => 'لح',
+  'ﳋ' => 'لخ',
+  'ﳌ' => 'لم',
+  'ﳍ' => 'له',
+  'ﳎ' => 'مج',
+  'ﳏ' => 'مح',
+  'ﳐ' => 'مخ',
+  'ﳑ' => 'مم',
+  'ﳒ' => 'نج',
+  'ﳓ' => 'نح',
+  'ﳔ' => 'نخ',
+  'ﳕ' => 'نم',
+  'ﳖ' => 'نه',
+  'ﳗ' => 'هج',
+  'ﳘ' => 'هم',
+  'ﳙ' => 'هٰ',
+  'ﳚ' => 'يج',
+  'ﳛ' => 'يح',
+  'ﳜ' => 'يخ',
+  'ﳝ' => 'يم',
+  'ﳞ' => 'يه',
+  'ﳟ' => 'ئم',
+  'ﳠ' => 'ئه',
+  'ﳡ' => 'بم',
+  'ﳢ' => 'به',
+  'ﳣ' => 'تم',
+  'ﳤ' => 'ته',
+  'ﳥ' => 'ثم',
+  'ﳦ' => 'ثه',
+  'ﳧ' => 'سم',
+  'ﳨ' => 'سه',
+  'ﳩ' => 'شم',
+  'ﳪ' => 'شه',
+  'ﳫ' => 'كل',
+  'ﳬ' => 'كم',
+  'ﳭ' => 'لم',
+  'ﳮ' => 'نم',
+  'ﳯ' => 'نه',
+  'ﳰ' => 'يم',
+  'ﳱ' => 'يه',
+  'ﳲ' => 'ـَّ',
+  'ﳳ' => 'ـُّ',
+  'ﳴ' => 'ـِّ',
+  'ﳵ' => 'طى',
+  'ﳶ' => 'طي',
+  'ﳷ' => 'عى',
+  'ﳸ' => 'عي',
+  'ﳹ' => 'غى',
+  'ﳺ' => 'غي',
+  'ﳻ' => 'سى',
+  'ﳼ' => 'سي',
+  'ﳽ' => 'شى',
+  'ﳾ' => 'شي',
+  'ﳿ' => 'حى',
+  'ﴀ' => 'حي',
+  'ﴁ' => 'جى',
+  'ﴂ' => 'جي',
+  'ﴃ' => 'خى',
+  'ﴄ' => 'خي',
+  'ﴅ' => 'صى',
+  'ﴆ' => 'صي',
+  'ﴇ' => 'ضى',
+  'ﴈ' => 'ضي',
+  'ﴉ' => 'شج',
+  'ﴊ' => 'شح',
+  'ﴋ' => 'شخ',
+  'ﴌ' => 'شم',
+  'ﴍ' => 'شر',
+  'ﴎ' => 'سر',
+  'ﴏ' => 'صر',
+  'ﴐ' => 'ضر',
+  'ﴑ' => 'طى',
+  'ﴒ' => 'طي',
+  'ﴓ' => 'عى',
+  'ﴔ' => 'عي',
+  'ﴕ' => 'غى',
+  'ﴖ' => 'غي',
+  'ﴗ' => 'سى',
+  'ﴘ' => 'سي',
+  'ﴙ' => 'شى',
+  'ﴚ' => 'شي',
+  'ﴛ' => 'حى',
+  'ﴜ' => 'حي',
+  'ﴝ' => 'جى',
+  'ﴞ' => 'جي',
+  'ﴟ' => 'خى',
+  'ﴠ' => 'خي',
+  'ﴡ' => 'صى',
+  'ﴢ' => 'صي',
+  'ﴣ' => 'ضى',
+  'ﴤ' => 'ضي',
+  'ﴥ' => 'شج',
+  'ﴦ' => 'شح',
+  'ﴧ' => 'شخ',
+  'ﴨ' => 'شم',
+  'ﴩ' => 'شر',
+  'ﴪ' => 'سر',
+  'ﴫ' => 'صر',
+  'ﴬ' => 'ضر',
+  'ﴭ' => 'شج',
+  'ﴮ' => 'شح',
+  'ﴯ' => 'شخ',
+  'ﴰ' => 'شم',
+  'ﴱ' => 'سه',
+  'ﴲ' => 'شه',
+  'ﴳ' => 'طم',
+  'ﴴ' => 'سج',
+  'ﴵ' => 'سح',
+  'ﴶ' => 'سخ',
+  'ﴷ' => 'شج',
+  'ﴸ' => 'شح',
+  'ﴹ' => 'شخ',
+  'ﴺ' => 'طم',
+  'ﴻ' => 'ظم',
+  'ﴼ' => 'اً',
+  'ﴽ' => 'اً',
+  'ﵐ' => 'تجم',
+  'ﵑ' => 'تحج',
+  'ﵒ' => 'تحج',
+  'ﵓ' => 'تحم',
+  'ﵔ' => 'تخم',
+  'ﵕ' => 'تمج',
+  'ﵖ' => 'تمح',
+  'ﵗ' => 'تمخ',
+  'ﵘ' => 'جمح',
+  'ﵙ' => 'جمح',
+  'ﵚ' => 'حمي',
+  'ﵛ' => 'حمى',
+  'ﵜ' => 'سحج',
+  'ﵝ' => 'سجح',
+  'ﵞ' => 'سجى',
+  'ﵟ' => 'سمح',
+  'ﵠ' => 'سمح',
+  'ﵡ' => 'سمج',
+  'ﵢ' => 'سمم',
+  'ﵣ' => 'سمم',
+  'ﵤ' => 'صحح',
+  'ﵥ' => 'صحح',
+  'ﵦ' => 'صمم',
+  'ﵧ' => 'شحم',
+  'ﵨ' => 'شحم',
+  'ﵩ' => 'شجي',
+  'ﵪ' => 'شمخ',
+  'ﵫ' => 'شمخ',
+  'ﵬ' => 'شمم',
+  'ﵭ' => 'شمم',
+  'ﵮ' => 'ضحى',
+  'ﵯ' => 'ضخم',
+  'ﵰ' => 'ضخم',
+  'ﵱ' => 'طمح',
+  'ﵲ' => 'طمح',
+  'ﵳ' => 'طمم',
+  'ﵴ' => 'طمي',
+  'ﵵ' => 'عجم',
+  'ﵶ' => 'عمم',
+  'ﵷ' => 'عمم',
+  'ﵸ' => 'عمى',
+  'ﵹ' => 'غمم',
+  'ﵺ' => 'غمي',
+  'ﵻ' => 'غمى',
+  'ﵼ' => 'فخم',
+  'ﵽ' => 'فخم',
+  'ﵾ' => 'قمح',
+  'ﵿ' => 'قمم',
+  'ﶀ' => 'لحم',
+  'ﶁ' => 'لحي',
+  'ﶂ' => 'لحى',
+  'ﶃ' => 'لجج',
+  'ﶄ' => 'لجج',
+  'ﶅ' => 'لخم',
+  'ﶆ' => 'لخم',
+  'ﶇ' => 'لمح',
+  'ﶈ' => 'لمح',
+  'ﶉ' => 'محج',
+  'ﶊ' => 'محم',
+  'ﶋ' => 'محي',
+  'ﶌ' => 'مجح',
+  'ﶍ' => 'مجم',
+  'ﶎ' => 'مخج',
+  'ﶏ' => 'مخم',
+  'ﶒ' => 'مجخ',
+  'ﶓ' => 'همج',
+  'ﶔ' => 'همم',
+  'ﶕ' => 'نحم',
+  'ﶖ' => 'نحى',
+  'ﶗ' => 'نجم',
+  'ﶘ' => 'نجم',
+  'ﶙ' => 'نجى',
+  'ﶚ' => 'نمي',
+  'ﶛ' => 'نمى',
+  'ﶜ' => 'يمم',
+  'ﶝ' => 'يمم',
+  'ﶞ' => 'بخي',
+  'ﶟ' => 'تجي',
+  'ﶠ' => 'تجى',
+  'ﶡ' => 'تخي',
+  'ﶢ' => 'تخى',
+  'ﶣ' => 'تمي',
+  'ﶤ' => 'تمى',
+  'ﶥ' => 'جمي',
+  'ﶦ' => 'جحى',
+  'ﶧ' => 'جمى',
+  'ﶨ' => 'سخى',
+  'ﶩ' => 'صحي',
+  'ﶪ' => 'شحي',
+  'ﶫ' => 'ضحي',
+  'ﶬ' => 'لجي',
+  'ﶭ' => 'لمي',
+  'ﶮ' => 'يحي',
+  'ﶯ' => 'يجي',
+  'ﶰ' => 'يمي',
+  'ﶱ' => 'ممي',
+  'ﶲ' => 'قمي',
+  'ﶳ' => 'نحي',
+  'ﶴ' => 'قمح',
+  'ﶵ' => 'لحم',
+  'ﶶ' => 'عمي',
+  'ﶷ' => 'كمي',
+  'ﶸ' => 'نجح',
+  'ﶹ' => 'مخي',
+  'ﶺ' => 'لجم',
+  'ﶻ' => 'كمم',
+  'ﶼ' => 'لجم',
+  'ﶽ' => 'نجح',
+  'ﶾ' => 'جحي',
+  'ﶿ' => 'حجي',
+  'ﷀ' => 'مجي',
+  'ﷁ' => 'فمي',
+  'ﷂ' => 'بحي',
+  'ﷃ' => 'كمم',
+  'ﷄ' => 'عجم',
+  'ﷅ' => 'صمم',
+  'ﷆ' => 'سخي',
+  'ﷇ' => 'نجي',
+  'ﷰ' => 'صلے',
+  'ﷱ' => 'قلے',
+  'ﷲ' => 'الله',
+  'ﷳ' => 'اكبر',
+  'ﷴ' => 'محمد',
+  'ﷵ' => 'صلعم',
+  'ﷶ' => 'رسول',
+  'ﷷ' => 'عليه',
+  'ﷸ' => 'وسلم',
+  'ﷹ' => 'صلى',
+  'ﷺ' => 'صلى الله عليه وسلم',
+  'ﷻ' => 'جل جلاله',
+  '﷼' => 'ریال',
+  '︐' => ',',
+  '︑' => '、',
+  '︒' => '。',
+  '︓' => ':',
+  '︔' => ';',
+  '︕' => '!',
+  '︖' => '?',
+  '︗' => '〖',
+  '︘' => '〗',
+  '︙' => '...',
+  '︰' => '..',
+  '︱' => '—',
+  '︲' => '–',
+  '︳' => '_',
+  '︴' => '_',
+  '︵' => '(',
+  '︶' => ')',
+  '︷' => '{',
+  '︸' => '}',
+  '︹' => '〔',
+  '︺' => '〕',
+  '︻' => '【',
+  '︼' => '】',
+  '︽' => '《',
+  '︾' => '》',
+  '︿' => '〈',
+  '﹀' => '〉',
+  '﹁' => '「',
+  '﹂' => '」',
+  '﹃' => '『',
+  '﹄' => '』',
+  '﹇' => '[',
+  '﹈' => ']',
+  '﹉' => ' ̅',
+  '﹊' => ' ̅',
+  '﹋' => ' ̅',
+  '﹌' => ' ̅',
+  '﹍' => '_',
+  '﹎' => '_',
+  '﹏' => '_',
+  '﹐' => ',',
+  '﹑' => '、',
+  '﹒' => '.',
+  '﹔' => ';',
+  '﹕' => ':',
+  '﹖' => '?',
+  '﹗' => '!',
+  '﹘' => '—',
+  '﹙' => '(',
+  '﹚' => ')',
+  '﹛' => '{',
+  '﹜' => '}',
+  '﹝' => '〔',
+  '﹞' => '〕',
+  '﹟' => '#',
+  '﹠' => '&',
+  '﹡' => '*',
+  '﹢' => '+',
+  '﹣' => '-',
+  '﹤' => '<',
+  '﹥' => '>',
+  '﹦' => '=',
+  '﹨' => '\\',
+  '﹩' => '$',
+  '﹪' => '%',
+  '﹫' => '@',
+  'ﹰ' => ' ً',
+  'ﹱ' => 'ـً',
+  'ﹲ' => ' ٌ',
+  'ﹴ' => ' ٍ',
+  'ﹶ' => ' َ',
+  'ﹷ' => 'ـَ',
+  'ﹸ' => ' ُ',
+  'ﹹ' => 'ـُ',
+  'ﹺ' => ' ِ',
+  'ﹻ' => 'ـِ',
+  'ﹼ' => ' ّ',
+  'ﹽ' => 'ـّ',
+  'ﹾ' => ' ْ',
+  'ﹿ' => 'ـْ',
+  'ﺀ' => 'ء',
+  'ﺁ' => 'آ',
+  'ﺂ' => 'آ',
+  'ﺃ' => 'أ',
+  'ﺄ' => 'أ',
+  'ﺅ' => 'ؤ',
+  'ﺆ' => 'ؤ',
+  'ﺇ' => 'إ',
+  'ﺈ' => 'إ',
+  'ﺉ' => 'ئ',
+  'ﺊ' => 'ئ',
+  'ﺋ' => 'ئ',
+  'ﺌ' => 'ئ',
+  'ﺍ' => 'ا',
+  'ﺎ' => 'ا',
+  'ﺏ' => 'ب',
+  'ﺐ' => 'ب',
+  'ﺑ' => 'ب',
+  'ﺒ' => 'ب',
+  'ﺓ' => 'ة',
+  'ﺔ' => 'ة',
+  'ﺕ' => 'ت',
+  'ﺖ' => 'ت',
+  'ﺗ' => 'ت',
+  'ﺘ' => 'ت',
+  'ﺙ' => 'ث',
+  'ﺚ' => 'ث',
+  'ﺛ' => 'ث',
+  'ﺜ' => 'ث',
+  'ﺝ' => 'ج',
+  'ﺞ' => 'ج',
+  'ﺟ' => 'ج',
+  'ﺠ' => 'ج',
+  'ﺡ' => 'ح',
+  'ﺢ' => 'ح',
+  'ﺣ' => 'ح',
+  'ﺤ' => 'ح',
+  'ﺥ' => 'خ',
+  'ﺦ' => 'خ',
+  'ﺧ' => 'خ',
+  'ﺨ' => 'خ',
+  'ﺩ' => 'د',
+  'ﺪ' => 'د',
+  'ﺫ' => 'ذ',
+  'ﺬ' => 'ذ',
+  'ﺭ' => 'ر',
+  'ﺮ' => 'ر',
+  'ﺯ' => 'ز',
+  'ﺰ' => 'ز',
+  'ﺱ' => 'س',
+  'ﺲ' => 'س',
+  'ﺳ' => 'س',
+  'ﺴ' => 'س',
+  'ﺵ' => 'ش',
+  'ﺶ' => 'ش',
+  'ﺷ' => 'ش',
+  'ﺸ' => 'ش',
+  'ﺹ' => 'ص',
+  'ﺺ' => 'ص',
+  'ﺻ' => 'ص',
+  'ﺼ' => 'ص',
+  'ﺽ' => 'ض',
+  'ﺾ' => 'ض',
+  'ﺿ' => 'ض',
+  'ﻀ' => 'ض',
+  'ﻁ' => 'ط',
+  'ﻂ' => 'ط',
+  'ﻃ' => 'ط',
+  'ﻄ' => 'ط',
+  'ﻅ' => 'ظ',
+  'ﻆ' => 'ظ',
+  'ﻇ' => 'ظ',
+  'ﻈ' => 'ظ',
+  'ﻉ' => 'ع',
+  'ﻊ' => 'ع',
+  'ﻋ' => 'ع',
+  'ﻌ' => 'ع',
+  'ﻍ' => 'غ',
+  'ﻎ' => 'غ',
+  'ﻏ' => 'غ',
+  'ﻐ' => 'غ',
+  'ﻑ' => 'ف',
+  'ﻒ' => 'ف',
+  'ﻓ' => 'ف',
+  'ﻔ' => 'ف',
+  'ﻕ' => 'ق',
+  'ﻖ' => 'ق',
+  'ﻗ' => 'ق',
+  'ﻘ' => 'ق',
+  'ﻙ' => 'ك',
+  'ﻚ' => 'ك',
+  'ﻛ' => 'ك',
+  'ﻜ' => 'ك',
+  'ﻝ' => 'ل',
+  'ﻞ' => 'ل',
+  'ﻟ' => 'ل',
+  'ﻠ' => 'ل',
+  'ﻡ' => 'م',
+  'ﻢ' => 'م',
+  'ﻣ' => 'م',
+  'ﻤ' => 'م',
+  'ﻥ' => 'ن',
+  'ﻦ' => 'ن',
+  'ﻧ' => 'ن',
+  'ﻨ' => 'ن',
+  'ﻩ' => 'ه',
+  'ﻪ' => 'ه',
+  'ﻫ' => 'ه',
+  'ﻬ' => 'ه',
+  'ﻭ' => 'و',
+  'ﻮ' => 'و',
+  'ﻯ' => 'ى',
+  'ﻰ' => 'ى',
+  'ﻱ' => 'ي',
+  'ﻲ' => 'ي',
+  'ﻳ' => 'ي',
+  'ﻴ' => 'ي',
+  'ﻵ' => 'لآ',
+  'ﻶ' => 'لآ',
+  'ﻷ' => 'لأ',
+  'ﻸ' => 'لأ',
+  'ﻹ' => 'لإ',
+  'ﻺ' => 'لإ',
+  'ﻻ' => 'لا',
+  'ﻼ' => 'لا',
+  '!' => '!',
+  '"' => '"',
+  '#' => '#',
+  '$' => '$',
+  '%' => '%',
+  '&' => '&',
+  ''' => '\'',
+  '(' => '(',
+  ')' => ')',
+  '*' => '*',
+  '+' => '+',
+  ',' => ',',
+  '-' => '-',
+  '.' => '.',
+  '/' => '/',
+  '0' => '0',
+  '1' => '1',
+  '2' => '2',
+  '3' => '3',
+  '4' => '4',
+  '5' => '5',
+  '6' => '6',
+  '7' => '7',
+  '8' => '8',
+  '9' => '9',
+  ':' => ':',
+  ';' => ';',
+  '<' => '<',
+  '=' => '=',
+  '>' => '>',
+  '?' => '?',
+  '@' => '@',
+  'A' => 'A',
+  'B' => 'B',
+  'C' => 'C',
+  'D' => 'D',
+  'E' => 'E',
+  'F' => 'F',
+  'G' => 'G',
+  'H' => 'H',
+  'I' => 'I',
+  'J' => 'J',
+  'K' => 'K',
+  'L' => 'L',
+  'M' => 'M',
+  'N' => 'N',
+  'O' => 'O',
+  'P' => 'P',
+  'Q' => 'Q',
+  'R' => 'R',
+  'S' => 'S',
+  'T' => 'T',
+  'U' => 'U',
+  'V' => 'V',
+  'W' => 'W',
+  'X' => 'X',
+  'Y' => 'Y',
+  'Z' => 'Z',
+  '[' => '[',
+  '\' => '\\',
+  ']' => ']',
+  '^' => '^',
+  '_' => '_',
+  '`' => '`',
+  'a' => 'a',
+  'b' => 'b',
+  'c' => 'c',
+  'd' => 'd',
+  'e' => 'e',
+  'f' => 'f',
+  'g' => 'g',
+  'h' => 'h',
+  'i' => 'i',
+  'j' => 'j',
+  'k' => 'k',
+  'l' => 'l',
+  'm' => 'm',
+  'n' => 'n',
+  'o' => 'o',
+  'p' => 'p',
+  'q' => 'q',
+  'r' => 'r',
+  's' => 's',
+  't' => 't',
+  'u' => 'u',
+  'v' => 'v',
+  'w' => 'w',
+  'x' => 'x',
+  'y' => 'y',
+  'z' => 'z',
+  '{' => '{',
+  '|' => '|',
+  '}' => '}',
+  '~' => '~',
+  '⦅' => '⦅',
+  '⦆' => '⦆',
+  '。' => '。',
+  '「' => '「',
+  '」' => '」',
+  '、' => '、',
+  '・' => '・',
+  'ヲ' => 'ヲ',
+  'ァ' => 'ァ',
+  'ィ' => 'ィ',
+  'ゥ' => 'ゥ',
+  'ェ' => 'ェ',
+  'ォ' => 'ォ',
+  'ャ' => 'ャ',
+  'ュ' => 'ュ',
+  'ョ' => 'ョ',
+  'ッ' => 'ッ',
+  'ー' => 'ー',
+  'ア' => 'ア',
+  'イ' => 'イ',
+  'ウ' => 'ウ',
+  'エ' => 'エ',
+  'オ' => 'オ',
+  'カ' => 'カ',
+  'キ' => 'キ',
+  'ク' => 'ク',
+  'ケ' => 'ケ',
+  'コ' => 'コ',
+  'サ' => 'サ',
+  'シ' => 'シ',
+  'ス' => 'ス',
+  'セ' => 'セ',
+  'ソ' => 'ソ',
+  'タ' => 'タ',
+  'チ' => 'チ',
+  'ツ' => 'ツ',
+  'テ' => 'テ',
+  'ト' => 'ト',
+  'ナ' => 'ナ',
+  'ニ' => 'ニ',
+  'ヌ' => 'ヌ',
+  'ネ' => 'ネ',
+  'ノ' => 'ノ',
+  'ハ' => 'ハ',
+  'ヒ' => 'ヒ',
+  'フ' => 'フ',
+  'ヘ' => 'ヘ',
+  'ホ' => 'ホ',
+  'マ' => 'マ',
+  'ミ' => 'ミ',
+  'ム' => 'ム',
+  'メ' => 'メ',
+  'モ' => 'モ',
+  'ヤ' => 'ヤ',
+  'ユ' => 'ユ',
+  'ヨ' => 'ヨ',
+  'ラ' => 'ラ',
+  'リ' => 'リ',
+  'ル' => 'ル',
+  'レ' => 'レ',
+  'ロ' => 'ロ',
+  'ワ' => 'ワ',
+  'ン' => 'ン',
+  '゙' => '゙',
+  '゚' => '゚',
+  'ᅠ' => 'ᅠ',
+  'ᄀ' => 'ᄀ',
+  'ᄁ' => 'ᄁ',
+  'ᆪ' => 'ᆪ',
+  'ᄂ' => 'ᄂ',
+  'ᆬ' => 'ᆬ',
+  'ᆭ' => 'ᆭ',
+  'ᄃ' => 'ᄃ',
+  'ᄄ' => 'ᄄ',
+  'ᄅ' => 'ᄅ',
+  'ᆰ' => 'ᆰ',
+  'ᆱ' => 'ᆱ',
+  'ᆲ' => 'ᆲ',
+  'ᆳ' => 'ᆳ',
+  'ᆴ' => 'ᆴ',
+  'ᆵ' => 'ᆵ',
+  'ᄚ' => 'ᄚ',
+  'ᄆ' => 'ᄆ',
+  'ᄇ' => 'ᄇ',
+  'ᄈ' => 'ᄈ',
+  'ᄡ' => 'ᄡ',
+  'ᄉ' => 'ᄉ',
+  'ᄊ' => 'ᄊ',
+  'ᄋ' => 'ᄋ',
+  'ᄌ' => 'ᄌ',
+  'ᄍ' => 'ᄍ',
+  'ᄎ' => 'ᄎ',
+  'ᄏ' => 'ᄏ',
+  'ᄐ' => 'ᄐ',
+  'ᄑ' => 'ᄑ',
+  'ᄒ' => 'ᄒ',
+  'ᅡ' => 'ᅡ',
+  'ᅢ' => 'ᅢ',
+  'ᅣ' => 'ᅣ',
+  'ᅤ' => 'ᅤ',
+  'ᅥ' => 'ᅥ',
+  'ᅦ' => 'ᅦ',
+  'ᅧ' => 'ᅧ',
+  'ᅨ' => 'ᅨ',
+  'ᅩ' => 'ᅩ',
+  'ᅪ' => 'ᅪ',
+  'ᅫ' => 'ᅫ',
+  'ᅬ' => 'ᅬ',
+  'ᅭ' => 'ᅭ',
+  'ᅮ' => 'ᅮ',
+  'ᅯ' => 'ᅯ',
+  'ᅰ' => 'ᅰ',
+  'ᅱ' => 'ᅱ',
+  'ᅲ' => 'ᅲ',
+  'ᅳ' => 'ᅳ',
+  'ᅴ' => 'ᅴ',
+  'ᅵ' => 'ᅵ',
+  '¢' => '¢',
+  '£' => '£',
+  '¬' => '¬',
+  ' ̄' => ' ̄',
+  '¦' => '¦',
+  '¥' => '¥',
+  '₩' => '₩',
+  '│' => '│',
+  '←' => '←',
+  '↑' => '↑',
+  '→' => '→',
+  '↓' => '↓',
+  '■' => '■',
+  '○' => '○',
+  '𝐀' => 'A',
+  '𝐁' => 'B',
+  '𝐂' => 'C',
+  '𝐃' => 'D',
+  '𝐄' => 'E',
+  '𝐅' => 'F',
+  '𝐆' => 'G',
+  '𝐇' => 'H',
+  '𝐈' => 'I',
+  '𝐉' => 'J',
+  '𝐊' => 'K',
+  '𝐋' => 'L',
+  '𝐌' => 'M',
+  '𝐍' => 'N',
+  '𝐎' => 'O',
+  '𝐏' => 'P',
+  '𝐐' => 'Q',
+  '𝐑' => 'R',
+  '𝐒' => 'S',
+  '𝐓' => 'T',
+  '𝐔' => 'U',
+  '𝐕' => 'V',
+  '𝐖' => 'W',
+  '𝐗' => 'X',
+  '𝐘' => 'Y',
+  '𝐙' => 'Z',
+  '𝐚' => 'a',
+  '𝐛' => 'b',
+  '𝐜' => 'c',
+  '𝐝' => 'd',
+  '𝐞' => 'e',
+  '𝐟' => 'f',
+  '𝐠' => 'g',
+  '𝐡' => 'h',
+  '𝐢' => 'i',
+  '𝐣' => 'j',
+  '𝐤' => 'k',
+  '𝐥' => 'l',
+  '𝐦' => 'm',
+  '𝐧' => 'n',
+  '𝐨' => 'o',
+  '𝐩' => 'p',
+  '𝐪' => 'q',
+  '𝐫' => 'r',
+  '𝐬' => 's',
+  '𝐭' => 't',
+  '𝐮' => 'u',
+  '𝐯' => 'v',
+  '𝐰' => 'w',
+  '𝐱' => 'x',
+  '𝐲' => 'y',
+  '𝐳' => 'z',
+  '𝐴' => 'A',
+  '𝐵' => 'B',
+  '𝐶' => 'C',
+  '𝐷' => 'D',
+  '𝐸' => 'E',
+  '𝐹' => 'F',
+  '𝐺' => 'G',
+  '𝐻' => 'H',
+  '𝐼' => 'I',
+  '𝐽' => 'J',
+  '𝐾' => 'K',
+  '𝐿' => 'L',
+  '𝑀' => 'M',
+  '𝑁' => 'N',
+  '𝑂' => 'O',
+  '𝑃' => 'P',
+  '𝑄' => 'Q',
+  '𝑅' => 'R',
+  '𝑆' => 'S',
+  '𝑇' => 'T',
+  '𝑈' => 'U',
+  '𝑉' => 'V',
+  '𝑊' => 'W',
+  '𝑋' => 'X',
+  '𝑌' => 'Y',
+  '𝑍' => 'Z',
+  '𝑎' => 'a',
+  '𝑏' => 'b',
+  '𝑐' => 'c',
+  '𝑑' => 'd',
+  '𝑒' => 'e',
+  '𝑓' => 'f',
+  '𝑔' => 'g',
+  '𝑖' => 'i',
+  '𝑗' => 'j',
+  '𝑘' => 'k',
+  '𝑙' => 'l',
+  '𝑚' => 'm',
+  '𝑛' => 'n',
+  '𝑜' => 'o',
+  '𝑝' => 'p',
+  '𝑞' => 'q',
+  '𝑟' => 'r',
+  '𝑠' => 's',
+  '𝑡' => 't',
+  '𝑢' => 'u',
+  '𝑣' => 'v',
+  '𝑤' => 'w',
+  '𝑥' => 'x',
+  '𝑦' => 'y',
+  '𝑧' => 'z',
+  '𝑨' => 'A',
+  '𝑩' => 'B',
+  '𝑪' => 'C',
+  '𝑫' => 'D',
+  '𝑬' => 'E',
+  '𝑭' => 'F',
+  '𝑮' => 'G',
+  '𝑯' => 'H',
+  '𝑰' => 'I',
+  '𝑱' => 'J',
+  '𝑲' => 'K',
+  '𝑳' => 'L',
+  '𝑴' => 'M',
+  '𝑵' => 'N',
+  '𝑶' => 'O',
+  '𝑷' => 'P',
+  '𝑸' => 'Q',
+  '𝑹' => 'R',
+  '𝑺' => 'S',
+  '𝑻' => 'T',
+  '𝑼' => 'U',
+  '𝑽' => 'V',
+  '𝑾' => 'W',
+  '𝑿' => 'X',
+  '𝒀' => 'Y',
+  '𝒁' => 'Z',
+  '𝒂' => 'a',
+  '𝒃' => 'b',
+  '𝒄' => 'c',
+  '𝒅' => 'd',
+  '𝒆' => 'e',
+  '𝒇' => 'f',
+  '𝒈' => 'g',
+  '𝒉' => 'h',
+  '𝒊' => 'i',
+  '𝒋' => 'j',
+  '𝒌' => 'k',
+  '𝒍' => 'l',
+  '𝒎' => 'm',
+  '𝒏' => 'n',
+  '𝒐' => 'o',
+  '𝒑' => 'p',
+  '𝒒' => 'q',
+  '𝒓' => 'r',
+  '𝒔' => 's',
+  '𝒕' => 't',
+  '𝒖' => 'u',
+  '𝒗' => 'v',
+  '𝒘' => 'w',
+  '𝒙' => 'x',
+  '𝒚' => 'y',
+  '𝒛' => 'z',
+  '𝒜' => 'A',
+  '𝒞' => 'C',
+  '𝒟' => 'D',
+  '𝒢' => 'G',
+  '𝒥' => 'J',
+  '𝒦' => 'K',
+  '𝒩' => 'N',
+  '𝒪' => 'O',
+  '𝒫' => 'P',
+  '𝒬' => 'Q',
+  '𝒮' => 'S',
+  '𝒯' => 'T',
+  '𝒰' => 'U',
+  '𝒱' => 'V',
+  '𝒲' => 'W',
+  '𝒳' => 'X',
+  '𝒴' => 'Y',
+  '𝒵' => 'Z',
+  '𝒶' => 'a',
+  '𝒷' => 'b',
+  '𝒸' => 'c',
+  '𝒹' => 'd',
+  '𝒻' => 'f',
+  '𝒽' => 'h',
+  '𝒾' => 'i',
+  '𝒿' => 'j',
+  '𝓀' => 'k',
+  '𝓁' => 'l',
+  '𝓂' => 'm',
+  '𝓃' => 'n',
+  '𝓅' => 'p',
+  '𝓆' => 'q',
+  '𝓇' => 'r',
+  '𝓈' => 's',
+  '𝓉' => 't',
+  '𝓊' => 'u',
+  '𝓋' => 'v',
+  '𝓌' => 'w',
+  '𝓍' => 'x',
+  '𝓎' => 'y',
+  '𝓏' => 'z',
+  '𝓐' => 'A',
+  '𝓑' => 'B',
+  '𝓒' => 'C',
+  '𝓓' => 'D',
+  '𝓔' => 'E',
+  '𝓕' => 'F',
+  '𝓖' => 'G',
+  '𝓗' => 'H',
+  '𝓘' => 'I',
+  '𝓙' => 'J',
+  '𝓚' => 'K',
+  '𝓛' => 'L',
+  '𝓜' => 'M',
+  '𝓝' => 'N',
+  '𝓞' => 'O',
+  '𝓟' => 'P',
+  '𝓠' => 'Q',
+  '𝓡' => 'R',
+  '𝓢' => 'S',
+  '𝓣' => 'T',
+  '𝓤' => 'U',
+  '𝓥' => 'V',
+  '𝓦' => 'W',
+  '𝓧' => 'X',
+  '𝓨' => 'Y',
+  '𝓩' => 'Z',
+  '𝓪' => 'a',
+  '𝓫' => 'b',
+  '𝓬' => 'c',
+  '𝓭' => 'd',
+  '𝓮' => 'e',
+  '𝓯' => 'f',
+  '𝓰' => 'g',
+  '𝓱' => 'h',
+  '𝓲' => 'i',
+  '𝓳' => 'j',
+  '𝓴' => 'k',
+  '𝓵' => 'l',
+  '𝓶' => 'm',
+  '𝓷' => 'n',
+  '𝓸' => 'o',
+  '𝓹' => 'p',
+  '𝓺' => 'q',
+  '𝓻' => 'r',
+  '𝓼' => 's',
+  '𝓽' => 't',
+  '𝓾' => 'u',
+  '𝓿' => 'v',
+  '𝔀' => 'w',
+  '𝔁' => 'x',
+  '𝔂' => 'y',
+  '𝔃' => 'z',
+  '𝔄' => 'A',
+  '𝔅' => 'B',
+  '𝔇' => 'D',
+  '𝔈' => 'E',
+  '𝔉' => 'F',
+  '𝔊' => 'G',
+  '𝔍' => 'J',
+  '𝔎' => 'K',
+  '𝔏' => 'L',
+  '𝔐' => 'M',
+  '𝔑' => 'N',
+  '𝔒' => 'O',
+  '𝔓' => 'P',
+  '𝔔' => 'Q',
+  '𝔖' => 'S',
+  '𝔗' => 'T',
+  '𝔘' => 'U',
+  '𝔙' => 'V',
+  '𝔚' => 'W',
+  '𝔛' => 'X',
+  '𝔜' => 'Y',
+  '𝔞' => 'a',
+  '𝔟' => 'b',
+  '𝔠' => 'c',
+  '𝔡' => 'd',
+  '𝔢' => 'e',
+  '𝔣' => 'f',
+  '𝔤' => 'g',
+  '𝔥' => 'h',
+  '𝔦' => 'i',
+  '𝔧' => 'j',
+  '𝔨' => 'k',
+  '𝔩' => 'l',
+  '𝔪' => 'm',
+  '𝔫' => 'n',
+  '𝔬' => 'o',
+  '𝔭' => 'p',
+  '𝔮' => 'q',
+  '𝔯' => 'r',
+  '𝔰' => 's',
+  '𝔱' => 't',
+  '𝔲' => 'u',
+  '𝔳' => 'v',
+  '𝔴' => 'w',
+  '𝔵' => 'x',
+  '𝔶' => 'y',
+  '𝔷' => 'z',
+  '𝔸' => 'A',
+  '𝔹' => 'B',
+  '𝔻' => 'D',
+  '𝔼' => 'E',
+  '𝔽' => 'F',
+  '𝔾' => 'G',
+  '𝕀' => 'I',
+  '𝕁' => 'J',
+  '𝕂' => 'K',
+  '𝕃' => 'L',
+  '𝕄' => 'M',
+  '𝕆' => 'O',
+  '𝕊' => 'S',
+  '𝕋' => 'T',
+  '𝕌' => 'U',
+  '𝕍' => 'V',
+  '𝕎' => 'W',
+  '𝕏' => 'X',
+  '𝕐' => 'Y',
+  '𝕒' => 'a',
+  '𝕓' => 'b',
+  '𝕔' => 'c',
+  '𝕕' => 'd',
+  '𝕖' => 'e',
+  '𝕗' => 'f',
+  '𝕘' => 'g',
+  '𝕙' => 'h',
+  '𝕚' => 'i',
+  '𝕛' => 'j',
+  '𝕜' => 'k',
+  '𝕝' => 'l',
+  '𝕞' => 'm',
+  '𝕟' => 'n',
+  '𝕠' => 'o',
+  '𝕡' => 'p',
+  '𝕢' => 'q',
+  '𝕣' => 'r',
+  '𝕤' => 's',
+  '𝕥' => 't',
+  '𝕦' => 'u',
+  '𝕧' => 'v',
+  '𝕨' => 'w',
+  '𝕩' => 'x',
+  '𝕪' => 'y',
+  '𝕫' => 'z',
+  '𝕬' => 'A',
+  '𝕭' => 'B',
+  '𝕮' => 'C',
+  '𝕯' => 'D',
+  '𝕰' => 'E',
+  '𝕱' => 'F',
+  '𝕲' => 'G',
+  '𝕳' => 'H',
+  '𝕴' => 'I',
+  '𝕵' => 'J',
+  '𝕶' => 'K',
+  '𝕷' => 'L',
+  '𝕸' => 'M',
+  '𝕹' => 'N',
+  '𝕺' => 'O',
+  '𝕻' => 'P',
+  '𝕼' => 'Q',
+  '𝕽' => 'R',
+  '𝕾' => 'S',
+  '𝕿' => 'T',
+  '𝖀' => 'U',
+  '𝖁' => 'V',
+  '𝖂' => 'W',
+  '𝖃' => 'X',
+  '𝖄' => 'Y',
+  '𝖅' => 'Z',
+  '𝖆' => 'a',
+  '𝖇' => 'b',
+  '𝖈' => 'c',
+  '𝖉' => 'd',
+  '𝖊' => 'e',
+  '𝖋' => 'f',
+  '𝖌' => 'g',
+  '𝖍' => 'h',
+  '𝖎' => 'i',
+  '𝖏' => 'j',
+  '𝖐' => 'k',
+  '𝖑' => 'l',
+  '𝖒' => 'm',
+  '𝖓' => 'n',
+  '𝖔' => 'o',
+  '𝖕' => 'p',
+  '𝖖' => 'q',
+  '𝖗' => 'r',
+  '𝖘' => 's',
+  '𝖙' => 't',
+  '𝖚' => 'u',
+  '𝖛' => 'v',
+  '𝖜' => 'w',
+  '𝖝' => 'x',
+  '𝖞' => 'y',
+  '𝖟' => 'z',
+  '𝖠' => 'A',
+  '𝖡' => 'B',
+  '𝖢' => 'C',
+  '𝖣' => 'D',
+  '𝖤' => 'E',
+  '𝖥' => 'F',
+  '𝖦' => 'G',
+  '𝖧' => 'H',
+  '𝖨' => 'I',
+  '𝖩' => 'J',
+  '𝖪' => 'K',
+  '𝖫' => 'L',
+  '𝖬' => 'M',
+  '𝖭' => 'N',
+  '𝖮' => 'O',
+  '𝖯' => 'P',
+  '𝖰' => 'Q',
+  '𝖱' => 'R',
+  '𝖲' => 'S',
+  '𝖳' => 'T',
+  '𝖴' => 'U',
+  '𝖵' => 'V',
+  '𝖶' => 'W',
+  '𝖷' => 'X',
+  '𝖸' => 'Y',
+  '𝖹' => 'Z',
+  '𝖺' => 'a',
+  '𝖻' => 'b',
+  '𝖼' => 'c',
+  '𝖽' => 'd',
+  '𝖾' => 'e',
+  '𝖿' => 'f',
+  '𝗀' => 'g',
+  '𝗁' => 'h',
+  '𝗂' => 'i',
+  '𝗃' => 'j',
+  '𝗄' => 'k',
+  '𝗅' => 'l',
+  '𝗆' => 'm',
+  '𝗇' => 'n',
+  '𝗈' => 'o',
+  '𝗉' => 'p',
+  '𝗊' => 'q',
+  '𝗋' => 'r',
+  '𝗌' => 's',
+  '𝗍' => 't',
+  '𝗎' => 'u',
+  '𝗏' => 'v',
+  '𝗐' => 'w',
+  '𝗑' => 'x',
+  '𝗒' => 'y',
+  '𝗓' => 'z',
+  '𝗔' => 'A',
+  '𝗕' => 'B',
+  '𝗖' => 'C',
+  '𝗗' => 'D',
+  '𝗘' => 'E',
+  '𝗙' => 'F',
+  '𝗚' => 'G',
+  '𝗛' => 'H',
+  '𝗜' => 'I',
+  '𝗝' => 'J',
+  '𝗞' => 'K',
+  '𝗟' => 'L',
+  '𝗠' => 'M',
+  '𝗡' => 'N',
+  '𝗢' => 'O',
+  '𝗣' => 'P',
+  '𝗤' => 'Q',
+  '𝗥' => 'R',
+  '𝗦' => 'S',
+  '𝗧' => 'T',
+  '𝗨' => 'U',
+  '𝗩' => 'V',
+  '𝗪' => 'W',
+  '𝗫' => 'X',
+  '𝗬' => 'Y',
+  '𝗭' => 'Z',
+  '𝗮' => 'a',
+  '𝗯' => 'b',
+  '𝗰' => 'c',
+  '𝗱' => 'd',
+  '𝗲' => 'e',
+  '𝗳' => 'f',
+  '𝗴' => 'g',
+  '𝗵' => 'h',
+  '𝗶' => 'i',
+  '𝗷' => 'j',
+  '𝗸' => 'k',
+  '𝗹' => 'l',
+  '𝗺' => 'm',
+  '𝗻' => 'n',
+  '𝗼' => 'o',
+  '𝗽' => 'p',
+  '𝗾' => 'q',
+  '𝗿' => 'r',
+  '𝘀' => 's',
+  '𝘁' => 't',
+  '𝘂' => 'u',
+  '𝘃' => 'v',
+  '𝘄' => 'w',
+  '𝘅' => 'x',
+  '𝘆' => 'y',
+  '𝘇' => 'z',
+  '𝘈' => 'A',
+  '𝘉' => 'B',
+  '𝘊' => 'C',
+  '𝘋' => 'D',
+  '𝘌' => 'E',
+  '𝘍' => 'F',
+  '𝘎' => 'G',
+  '𝘏' => 'H',
+  '𝘐' => 'I',
+  '𝘑' => 'J',
+  '𝘒' => 'K',
+  '𝘓' => 'L',
+  '𝘔' => 'M',
+  '𝘕' => 'N',
+  '𝘖' => 'O',
+  '𝘗' => 'P',
+  '𝘘' => 'Q',
+  '𝘙' => 'R',
+  '𝘚' => 'S',
+  '𝘛' => 'T',
+  '𝘜' => 'U',
+  '𝘝' => 'V',
+  '𝘞' => 'W',
+  '𝘟' => 'X',
+  '𝘠' => 'Y',
+  '𝘡' => 'Z',
+  '𝘢' => 'a',
+  '𝘣' => 'b',
+  '𝘤' => 'c',
+  '𝘥' => 'd',
+  '𝘦' => 'e',
+  '𝘧' => 'f',
+  '𝘨' => 'g',
+  '𝘩' => 'h',
+  '𝘪' => 'i',
+  '𝘫' => 'j',
+  '𝘬' => 'k',
+  '𝘭' => 'l',
+  '𝘮' => 'm',
+  '𝘯' => 'n',
+  '𝘰' => 'o',
+  '𝘱' => 'p',
+  '𝘲' => 'q',
+  '𝘳' => 'r',
+  '𝘴' => 's',
+  '𝘵' => 't',
+  '𝘶' => 'u',
+  '𝘷' => 'v',
+  '𝘸' => 'w',
+  '𝘹' => 'x',
+  '𝘺' => 'y',
+  '𝘻' => 'z',
+  '𝘼' => 'A',
+  '𝘽' => 'B',
+  '𝘾' => 'C',
+  '𝘿' => 'D',
+  '𝙀' => 'E',
+  '𝙁' => 'F',
+  '𝙂' => 'G',
+  '𝙃' => 'H',
+  '𝙄' => 'I',
+  '𝙅' => 'J',
+  '𝙆' => 'K',
+  '𝙇' => 'L',
+  '𝙈' => 'M',
+  '𝙉' => 'N',
+  '𝙊' => 'O',
+  '𝙋' => 'P',
+  '𝙌' => 'Q',
+  '𝙍' => 'R',
+  '𝙎' => 'S',
+  '𝙏' => 'T',
+  '𝙐' => 'U',
+  '𝙑' => 'V',
+  '𝙒' => 'W',
+  '𝙓' => 'X',
+  '𝙔' => 'Y',
+  '𝙕' => 'Z',
+  '𝙖' => 'a',
+  '𝙗' => 'b',
+  '𝙘' => 'c',
+  '𝙙' => 'd',
+  '𝙚' => 'e',
+  '𝙛' => 'f',
+  '𝙜' => 'g',
+  '𝙝' => 'h',
+  '𝙞' => 'i',
+  '𝙟' => 'j',
+  '𝙠' => 'k',
+  '𝙡' => 'l',
+  '𝙢' => 'm',
+  '𝙣' => 'n',
+  '𝙤' => 'o',
+  '𝙥' => 'p',
+  '𝙦' => 'q',
+  '𝙧' => 'r',
+  '𝙨' => 's',
+  '𝙩' => 't',
+  '𝙪' => 'u',
+  '𝙫' => 'v',
+  '𝙬' => 'w',
+  '𝙭' => 'x',
+  '𝙮' => 'y',
+  '𝙯' => 'z',
+  '𝙰' => 'A',
+  '𝙱' => 'B',
+  '𝙲' => 'C',
+  '𝙳' => 'D',
+  '𝙴' => 'E',
+  '𝙵' => 'F',
+  '𝙶' => 'G',
+  '𝙷' => 'H',
+  '𝙸' => 'I',
+  '𝙹' => 'J',
+  '𝙺' => 'K',
+  '𝙻' => 'L',
+  '𝙼' => 'M',
+  '𝙽' => 'N',
+  '𝙾' => 'O',
+  '𝙿' => 'P',
+  '𝚀' => 'Q',
+  '𝚁' => 'R',
+  '𝚂' => 'S',
+  '𝚃' => 'T',
+  '𝚄' => 'U',
+  '𝚅' => 'V',
+  '𝚆' => 'W',
+  '𝚇' => 'X',
+  '𝚈' => 'Y',
+  '𝚉' => 'Z',
+  '𝚊' => 'a',
+  '𝚋' => 'b',
+  '𝚌' => 'c',
+  '𝚍' => 'd',
+  '𝚎' => 'e',
+  '𝚏' => 'f',
+  '𝚐' => 'g',
+  '𝚑' => 'h',
+  '𝚒' => 'i',
+  '𝚓' => 'j',
+  '𝚔' => 'k',
+  '𝚕' => 'l',
+  '𝚖' => 'm',
+  '𝚗' => 'n',
+  '𝚘' => 'o',
+  '𝚙' => 'p',
+  '𝚚' => 'q',
+  '𝚛' => 'r',
+  '𝚜' => 's',
+  '𝚝' => 't',
+  '𝚞' => 'u',
+  '𝚟' => 'v',
+  '𝚠' => 'w',
+  '𝚡' => 'x',
+  '𝚢' => 'y',
+  '𝚣' => 'z',
+  '𝚤' => 'ı',
+  '𝚥' => 'ȷ',
+  '𝚨' => 'Α',
+  '𝚩' => 'Β',
+  '𝚪' => 'Γ',
+  '𝚫' => 'Δ',
+  '𝚬' => 'Ε',
+  '𝚭' => 'Ζ',
+  '𝚮' => 'Η',
+  '𝚯' => 'Θ',
+  '𝚰' => 'Ι',
+  '𝚱' => 'Κ',
+  '𝚲' => 'Λ',
+  '𝚳' => 'Μ',
+  '𝚴' => 'Ν',
+  '𝚵' => 'Ξ',
+  '𝚶' => 'Ο',
+  '𝚷' => 'Π',
+  '𝚸' => 'Ρ',
+  '𝚹' => 'Θ',
+  '𝚺' => 'Σ',
+  '𝚻' => 'Τ',
+  '𝚼' => 'Υ',
+  '𝚽' => 'Φ',
+  '𝚾' => 'Χ',
+  '𝚿' => 'Ψ',
+  '𝛀' => 'Ω',
+  '𝛁' => '∇',
+  '𝛂' => 'α',
+  '𝛃' => 'β',
+  '𝛄' => 'γ',
+  '𝛅' => 'δ',
+  '𝛆' => 'ε',
+  '𝛇' => 'ζ',
+  '𝛈' => 'η',
+  '𝛉' => 'θ',
+  '𝛊' => 'ι',
+  '𝛋' => 'κ',
+  '𝛌' => 'λ',
+  '𝛍' => 'μ',
+  '𝛎' => 'ν',
+  '𝛏' => 'ξ',
+  '𝛐' => 'ο',
+  '𝛑' => 'π',
+  '𝛒' => 'ρ',
+  '𝛓' => 'ς',
+  '𝛔' => 'σ',
+  '𝛕' => 'τ',
+  '𝛖' => 'υ',
+  '𝛗' => 'φ',
+  '𝛘' => 'χ',
+  '𝛙' => 'ψ',
+  '𝛚' => 'ω',
+  '𝛛' => '∂',
+  '𝛜' => 'ε',
+  '𝛝' => 'θ',
+  '𝛞' => 'κ',
+  '𝛟' => 'φ',
+  '𝛠' => 'ρ',
+  '𝛡' => 'π',
+  '𝛢' => 'Α',
+  '𝛣' => 'Β',
+  '𝛤' => 'Γ',
+  '𝛥' => 'Δ',
+  '𝛦' => 'Ε',
+  '𝛧' => 'Ζ',
+  '𝛨' => 'Η',
+  '𝛩' => 'Θ',
+  '𝛪' => 'Ι',
+  '𝛫' => 'Κ',
+  '𝛬' => 'Λ',
+  '𝛭' => 'Μ',
+  '𝛮' => 'Ν',
+  '𝛯' => 'Ξ',
+  '𝛰' => 'Ο',
+  '𝛱' => 'Π',
+  '𝛲' => 'Ρ',
+  '𝛳' => 'Θ',
+  '𝛴' => 'Σ',
+  '𝛵' => 'Τ',
+  '𝛶' => 'Υ',
+  '𝛷' => 'Φ',
+  '𝛸' => 'Χ',
+  '𝛹' => 'Ψ',
+  '𝛺' => 'Ω',
+  '𝛻' => '∇',
+  '𝛼' => 'α',
+  '𝛽' => 'β',
+  '𝛾' => 'γ',
+  '𝛿' => 'δ',
+  '𝜀' => 'ε',
+  '𝜁' => 'ζ',
+  '𝜂' => 'η',
+  '𝜃' => 'θ',
+  '𝜄' => 'ι',
+  '𝜅' => 'κ',
+  '𝜆' => 'λ',
+  '𝜇' => 'μ',
+  '𝜈' => 'ν',
+  '𝜉' => 'ξ',
+  '𝜊' => 'ο',
+  '𝜋' => 'π',
+  '𝜌' => 'ρ',
+  '𝜍' => 'ς',
+  '𝜎' => 'σ',
+  '𝜏' => 'τ',
+  '𝜐' => 'υ',
+  '𝜑' => 'φ',
+  '𝜒' => 'χ',
+  '𝜓' => 'ψ',
+  '𝜔' => 'ω',
+  '𝜕' => '∂',
+  '𝜖' => 'ε',
+  '𝜗' => 'θ',
+  '𝜘' => 'κ',
+  '𝜙' => 'φ',
+  '𝜚' => 'ρ',
+  '𝜛' => 'π',
+  '𝜜' => 'Α',
+  '𝜝' => 'Β',
+  '𝜞' => 'Γ',
+  '𝜟' => 'Δ',
+  '𝜠' => 'Ε',
+  '𝜡' => 'Ζ',
+  '𝜢' => 'Η',
+  '𝜣' => 'Θ',
+  '𝜤' => 'Ι',
+  '𝜥' => 'Κ',
+  '𝜦' => 'Λ',
+  '𝜧' => 'Μ',
+  '𝜨' => 'Ν',
+  '𝜩' => 'Ξ',
+  '𝜪' => 'Ο',
+  '𝜫' => 'Π',
+  '𝜬' => 'Ρ',
+  '𝜭' => 'Θ',
+  '𝜮' => 'Σ',
+  '𝜯' => 'Τ',
+  '𝜰' => 'Υ',
+  '𝜱' => 'Φ',
+  '𝜲' => 'Χ',
+  '𝜳' => 'Ψ',
+  '𝜴' => 'Ω',
+  '𝜵' => '∇',
+  '𝜶' => 'α',
+  '𝜷' => 'β',
+  '𝜸' => 'γ',
+  '𝜹' => 'δ',
+  '𝜺' => 'ε',
+  '𝜻' => 'ζ',
+  '𝜼' => 'η',
+  '𝜽' => 'θ',
+  '𝜾' => 'ι',
+  '𝜿' => 'κ',
+  '𝝀' => 'λ',
+  '𝝁' => 'μ',
+  '𝝂' => 'ν',
+  '𝝃' => 'ξ',
+  '𝝄' => 'ο',
+  '𝝅' => 'π',
+  '𝝆' => 'ρ',
+  '𝝇' => 'ς',
+  '𝝈' => 'σ',
+  '𝝉' => 'τ',
+  '𝝊' => 'υ',
+  '𝝋' => 'φ',
+  '𝝌' => 'χ',
+  '𝝍' => 'ψ',
+  '𝝎' => 'ω',
+  '𝝏' => '∂',
+  '𝝐' => 'ε',
+  '𝝑' => 'θ',
+  '𝝒' => 'κ',
+  '𝝓' => 'φ',
+  '𝝔' => 'ρ',
+  '𝝕' => 'π',
+  '𝝖' => 'Α',
+  '𝝗' => 'Β',
+  '𝝘' => 'Γ',
+  '𝝙' => 'Δ',
+  '𝝚' => 'Ε',
+  '𝝛' => 'Ζ',
+  '𝝜' => 'Η',
+  '𝝝' => 'Θ',
+  '𝝞' => 'Ι',
+  '𝝟' => 'Κ',
+  '𝝠' => 'Λ',
+  '𝝡' => 'Μ',
+  '𝝢' => 'Ν',
+  '𝝣' => 'Ξ',
+  '𝝤' => 'Ο',
+  '𝝥' => 'Π',
+  '𝝦' => 'Ρ',
+  '𝝧' => 'Θ',
+  '𝝨' => 'Σ',
+  '𝝩' => 'Τ',
+  '𝝪' => 'Υ',
+  '𝝫' => 'Φ',
+  '𝝬' => 'Χ',
+  '𝝭' => 'Ψ',
+  '𝝮' => 'Ω',
+  '𝝯' => '∇',
+  '𝝰' => 'α',
+  '𝝱' => 'β',
+  '𝝲' => 'γ',
+  '𝝳' => 'δ',
+  '𝝴' => 'ε',
+  '𝝵' => 'ζ',
+  '𝝶' => 'η',
+  '𝝷' => 'θ',
+  '𝝸' => 'ι',
+  '𝝹' => 'κ',
+  '𝝺' => 'λ',
+  '𝝻' => 'μ',
+  '𝝼' => 'ν',
+  '𝝽' => 'ξ',
+  '𝝾' => 'ο',
+  '𝝿' => 'π',
+  '𝞀' => 'ρ',
+  '𝞁' => 'ς',
+  '𝞂' => 'σ',
+  '𝞃' => 'τ',
+  '𝞄' => 'υ',
+  '𝞅' => 'φ',
+  '𝞆' => 'χ',
+  '𝞇' => 'ψ',
+  '𝞈' => 'ω',
+  '𝞉' => '∂',
+  '𝞊' => 'ε',
+  '𝞋' => 'θ',
+  '𝞌' => 'κ',
+  '𝞍' => 'φ',
+  '𝞎' => 'ρ',
+  '𝞏' => 'π',
+  '𝞐' => 'Α',
+  '𝞑' => 'Β',
+  '𝞒' => 'Γ',
+  '𝞓' => 'Δ',
+  '𝞔' => 'Ε',
+  '𝞕' => 'Ζ',
+  '𝞖' => 'Η',
+  '𝞗' => 'Θ',
+  '𝞘' => 'Ι',
+  '𝞙' => 'Κ',
+  '𝞚' => 'Λ',
+  '𝞛' => 'Μ',
+  '𝞜' => 'Ν',
+  '𝞝' => 'Ξ',
+  '𝞞' => 'Ο',
+  '𝞟' => 'Π',
+  '𝞠' => 'Ρ',
+  '𝞡' => 'Θ',
+  '𝞢' => 'Σ',
+  '𝞣' => 'Τ',
+  '𝞤' => 'Υ',
+  '𝞥' => 'Φ',
+  '𝞦' => 'Χ',
+  '𝞧' => 'Ψ',
+  '𝞨' => 'Ω',
+  '𝞩' => '∇',
+  '𝞪' => 'α',
+  '𝞫' => 'β',
+  '𝞬' => 'γ',
+  '𝞭' => 'δ',
+  '𝞮' => 'ε',
+  '𝞯' => 'ζ',
+  '𝞰' => 'η',
+  '𝞱' => 'θ',
+  '𝞲' => 'ι',
+  '𝞳' => 'κ',
+  '𝞴' => 'λ',
+  '𝞵' => 'μ',
+  '𝞶' => 'ν',
+  '𝞷' => 'ξ',
+  '𝞸' => 'ο',
+  '𝞹' => 'π',
+  '𝞺' => 'ρ',
+  '𝞻' => 'ς',
+  '𝞼' => 'σ',
+  '𝞽' => 'τ',
+  '𝞾' => 'υ',
+  '𝞿' => 'φ',
+  '𝟀' => 'χ',
+  '𝟁' => 'ψ',
+  '𝟂' => 'ω',
+  '𝟃' => '∂',
+  '𝟄' => 'ε',
+  '𝟅' => 'θ',
+  '𝟆' => 'κ',
+  '𝟇' => 'φ',
+  '𝟈' => 'ρ',
+  '𝟉' => 'π',
+  '𝟊' => 'Ϝ',
+  '𝟋' => 'ϝ',
+  '𝟎' => '0',
+  '𝟏' => '1',
+  '𝟐' => '2',
+  '𝟑' => '3',
+  '𝟒' => '4',
+  '𝟓' => '5',
+  '𝟔' => '6',
+  '𝟕' => '7',
+  '𝟖' => '8',
+  '𝟗' => '9',
+  '𝟘' => '0',
+  '𝟙' => '1',
+  '𝟚' => '2',
+  '𝟛' => '3',
+  '𝟜' => '4',
+  '𝟝' => '5',
+  '𝟞' => '6',
+  '𝟟' => '7',
+  '𝟠' => '8',
+  '𝟡' => '9',
+  '𝟢' => '0',
+  '𝟣' => '1',
+  '𝟤' => '2',
+  '𝟥' => '3',
+  '𝟦' => '4',
+  '𝟧' => '5',
+  '𝟨' => '6',
+  '𝟩' => '7',
+  '𝟪' => '8',
+  '𝟫' => '9',
+  '𝟬' => '0',
+  '𝟭' => '1',
+  '𝟮' => '2',
+  '𝟯' => '3',
+  '𝟰' => '4',
+  '𝟱' => '5',
+  '𝟲' => '6',
+  '𝟳' => '7',
+  '𝟴' => '8',
+  '𝟵' => '9',
+  '𝟶' => '0',
+  '𝟷' => '1',
+  '𝟸' => '2',
+  '𝟹' => '3',
+  '𝟺' => '4',
+  '𝟻' => '5',
+  '𝟼' => '6',
+  '𝟽' => '7',
+  '𝟾' => '8',
+  '𝟿' => '9',
+  '𞸀' => 'ا',
+  '𞸁' => 'ب',
+  '𞸂' => 'ج',
+  '𞸃' => 'د',
+  '𞸅' => 'و',
+  '𞸆' => 'ز',
+  '𞸇' => 'ح',
+  '𞸈' => 'ط',
+  '𞸉' => 'ي',
+  '𞸊' => 'ك',
+  '𞸋' => 'ل',
+  '𞸌' => 'م',
+  '𞸍' => 'ن',
+  '𞸎' => 'س',
+  '𞸏' => 'ع',
+  '𞸐' => 'ف',
+  '𞸑' => 'ص',
+  '𞸒' => 'ق',
+  '𞸓' => 'ر',
+  '𞸔' => 'ش',
+  '𞸕' => 'ت',
+  '𞸖' => 'ث',
+  '𞸗' => 'خ',
+  '𞸘' => 'ذ',
+  '𞸙' => 'ض',
+  '𞸚' => 'ظ',
+  '𞸛' => 'غ',
+  '𞸜' => 'ٮ',
+  '𞸝' => 'ں',
+  '𞸞' => 'ڡ',
+  '𞸟' => 'ٯ',
+  '𞸡' => 'ب',
+  '𞸢' => 'ج',
+  '𞸤' => 'ه',
+  '𞸧' => 'ح',
+  '𞸩' => 'ي',
+  '𞸪' => 'ك',
+  '𞸫' => 'ل',
+  '𞸬' => 'م',
+  '𞸭' => 'ن',
+  '𞸮' => 'س',
+  '𞸯' => 'ع',
+  '𞸰' => 'ف',
+  '𞸱' => 'ص',
+  '𞸲' => 'ق',
+  '𞸴' => 'ش',
+  '𞸵' => 'ت',
+  '𞸶' => 'ث',
+  '𞸷' => 'خ',
+  '𞸹' => 'ض',
+  '𞸻' => 'غ',
+  '𞹂' => 'ج',
+  '𞹇' => 'ح',
+  '𞹉' => 'ي',
+  '𞹋' => 'ل',
+  '𞹍' => 'ن',
+  '𞹎' => 'س',
+  '𞹏' => 'ع',
+  '𞹑' => 'ص',
+  '𞹒' => 'ق',
+  '𞹔' => 'ش',
+  '𞹗' => 'خ',
+  '𞹙' => 'ض',
+  '𞹛' => 'غ',
+  '𞹝' => 'ں',
+  '𞹟' => 'ٯ',
+  '𞹡' => 'ب',
+  '𞹢' => 'ج',
+  '𞹤' => 'ه',
+  '𞹧' => 'ح',
+  '𞹨' => 'ط',
+  '𞹩' => 'ي',
+  '𞹪' => 'ك',
+  '𞹬' => 'م',
+  '𞹭' => 'ن',
+  '𞹮' => 'س',
+  '𞹯' => 'ع',
+  '𞹰' => 'ف',
+  '𞹱' => 'ص',
+  '𞹲' => 'ق',
+  '𞹴' => 'ش',
+  '𞹵' => 'ت',
+  '𞹶' => 'ث',
+  '𞹷' => 'خ',
+  '𞹹' => 'ض',
+  '𞹺' => 'ظ',
+  '𞹻' => 'غ',
+  '𞹼' => 'ٮ',
+  '𞹾' => 'ڡ',
+  '𞺀' => 'ا',
+  '𞺁' => 'ب',
+  '𞺂' => 'ج',
+  '𞺃' => 'د',
+  '𞺄' => 'ه',
+  '𞺅' => 'و',
+  '𞺆' => 'ز',
+  '𞺇' => 'ح',
+  '𞺈' => 'ط',
+  '𞺉' => 'ي',
+  '𞺋' => 'ل',
+  '𞺌' => 'م',
+  '𞺍' => 'ن',
+  '𞺎' => 'س',
+  '𞺏' => 'ع',
+  '𞺐' => 'ف',
+  '𞺑' => 'ص',
+  '𞺒' => 'ق',
+  '𞺓' => 'ر',
+  '𞺔' => 'ش',
+  '𞺕' => 'ت',
+  '𞺖' => 'ث',
+  '𞺗' => 'خ',
+  '𞺘' => 'ذ',
+  '𞺙' => 'ض',
+  '𞺚' => 'ظ',
+  '𞺛' => 'غ',
+  '𞺡' => 'ب',
+  '𞺢' => 'ج',
+  '𞺣' => 'د',
+  '𞺥' => 'و',
+  '𞺦' => 'ز',
+  '𞺧' => 'ح',
+  '𞺨' => 'ط',
+  '𞺩' => 'ي',
+  '𞺫' => 'ل',
+  '𞺬' => 'م',
+  '𞺭' => 'ن',
+  '𞺮' => 'س',
+  '𞺯' => 'ع',
+  '𞺰' => 'ف',
+  '𞺱' => 'ص',
+  '𞺲' => 'ق',
+  '𞺳' => 'ر',
+  '𞺴' => 'ش',
+  '𞺵' => 'ت',
+  '𞺶' => 'ث',
+  '𞺷' => 'خ',
+  '𞺸' => 'ذ',
+  '𞺹' => 'ض',
+  '𞺺' => 'ظ',
+  '𞺻' => 'غ',
+  '🄀' => '0.',
+  '🄁' => '0,',
+  '🄂' => '1,',
+  '🄃' => '2,',
+  '🄄' => '3,',
+  '🄅' => '4,',
+  '🄆' => '5,',
+  '🄇' => '6,',
+  '🄈' => '7,',
+  '🄉' => '8,',
+  '🄊' => '9,',
+  '🄐' => '(A)',
+  '🄑' => '(B)',
+  '🄒' => '(C)',
+  '🄓' => '(D)',
+  '🄔' => '(E)',
+  '🄕' => '(F)',
+  '🄖' => '(G)',
+  '🄗' => '(H)',
+  '🄘' => '(I)',
+  '🄙' => '(J)',
+  '🄚' => '(K)',
+  '🄛' => '(L)',
+  '🄜' => '(M)',
+  '🄝' => '(N)',
+  '🄞' => '(O)',
+  '🄟' => '(P)',
+  '🄠' => '(Q)',
+  '🄡' => '(R)',
+  '🄢' => '(S)',
+  '🄣' => '(T)',
+  '🄤' => '(U)',
+  '🄥' => '(V)',
+  '🄦' => '(W)',
+  '🄧' => '(X)',
+  '🄨' => '(Y)',
+  '🄩' => '(Z)',
+  '🄪' => '〔S〕',
+  '🄫' => 'C',
+  '🄬' => 'R',
+  '🄭' => 'CD',
+  '🄮' => 'WZ',
+  '🄰' => 'A',
+  '🄱' => 'B',
+  '🄲' => 'C',
+  '🄳' => 'D',
+  '🄴' => 'E',
+  '🄵' => 'F',
+  '🄶' => 'G',
+  '🄷' => 'H',
+  '🄸' => 'I',
+  '🄹' => 'J',
+  '🄺' => 'K',
+  '🄻' => 'L',
+  '🄼' => 'M',
+  '🄽' => 'N',
+  '🄾' => 'O',
+  '🄿' => 'P',
+  '🅀' => 'Q',
+  '🅁' => 'R',
+  '🅂' => 'S',
+  '🅃' => 'T',
+  '🅄' => 'U',
+  '🅅' => 'V',
+  '🅆' => 'W',
+  '🅇' => 'X',
+  '🅈' => 'Y',
+  '🅉' => 'Z',
+  '🅊' => 'HV',
+  '🅋' => 'MV',
+  '🅌' => 'SD',
+  '🅍' => 'SS',
+  '🅎' => 'PPV',
+  '🅏' => 'WC',
+  '🅪' => 'MC',
+  '🅫' => 'MD',
+  '🅬' => 'MR',
+  '🆐' => 'DJ',
+  '🈀' => 'ほか',
+  '🈁' => 'ココ',
+  '🈂' => 'サ',
+  '🈐' => '手',
+  '🈑' => '字',
+  '🈒' => '双',
+  '🈓' => 'デ',
+  '🈔' => '二',
+  '🈕' => '多',
+  '🈖' => '解',
+  '🈗' => '天',
+  '🈘' => '交',
+  '🈙' => '映',
+  '🈚' => '無',
+  '🈛' => '料',
+  '🈜' => '前',
+  '🈝' => '後',
+  '🈞' => '再',
+  '🈟' => '新',
+  '🈠' => '初',
+  '🈡' => '終',
+  '🈢' => '生',
+  '🈣' => '販',
+  '🈤' => '声',
+  '🈥' => '吹',
+  '🈦' => '演',
+  '🈧' => '投',
+  '🈨' => '捕',
+  '🈩' => '一',
+  '🈪' => '三',
+  '🈫' => '遊',
+  '🈬' => '左',
+  '🈭' => '中',
+  '🈮' => '右',
+  '🈯' => '指',
+  '🈰' => '走',
+  '🈱' => '打',
+  '🈲' => '禁',
+  '🈳' => '空',
+  '🈴' => '合',
+  '🈵' => '満',
+  '🈶' => '有',
+  '🈷' => '月',
+  '🈸' => '申',
+  '🈹' => '割',
+  '🈺' => '営',
+  '🈻' => '配',
+  '🉀' => '〔本〕',
+  '🉁' => '〔三〕',
+  '🉂' => '〔二〕',
+  '🉃' => '〔安〕',
+  '🉄' => '〔点〕',
+  '🉅' => '〔打〕',
+  '🉆' => '〔盗〕',
+  '🉇' => '〔勝〕',
+  '🉈' => '〔敗〕',
+  '🉐' => '得',
+  '🉑' => '可',
+  '🯰' => '0',
+  '🯱' => '1',
+  '🯲' => '2',
+  '🯳' => '3',
+  '🯴' => '4',
+  '🯵' => '5',
+  '🯶' => '6',
+  '🯷' => '7',
+  '🯸' => '8',
+  '🯹' => '9',
+);
diff --git a/vendor/symfony/polyfill-intl-normalizer/bootstrap.php b/vendor/symfony/polyfill-intl-normalizer/bootstrap.php
new file mode 100644
index 000000000..3608e5c05
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-normalizer/bootstrap.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Intl\Normalizer as p;
+
+if (\PHP_VERSION_ID >= 80000) {
+    return require __DIR__.'/bootstrap80.php';
+}
+
+if (!function_exists('normalizer_is_normalized')) {
+    function normalizer_is_normalized($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::isNormalized($string, $form); }
+}
+if (!function_exists('normalizer_normalize')) {
+    function normalizer_normalize($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::normalize($string, $form); }
+}
diff --git a/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php b/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php
new file mode 100644
index 000000000..e36d1a947
--- /dev/null
+++ b/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php
@@ -0,0 +1,19 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Intl\Normalizer as p;
+
+if (!function_exists('normalizer_is_normalized')) {
+    function normalizer_is_normalized(?string $string, ?int $form = p\Normalizer::FORM_C): bool { return p\Normalizer::isNormalized((string) $string, (int) $form); }
+}
+if (!function_exists('normalizer_normalize')) {
+    function normalizer_normalize(?string $string, ?int $form = p\Normalizer::FORM_C): string|false { return p\Normalizer::normalize((string) $string, (int) $form); }
+}
diff --git a/vendor/symfony/polyfill-mbstring/composer.json b/vendor/symfony/polyfill-intl-normalizer/composer.json
similarity index 62%
rename from vendor/symfony/polyfill-mbstring/composer.json
rename to vendor/symfony/polyfill-intl-normalizer/composer.json
index 69b3cd228..8f4cfb4dc 100644
--- a/vendor/symfony/polyfill-mbstring/composer.json
+++ b/vendor/symfony/polyfill-intl-normalizer/composer.json
@@ -1,8 +1,8 @@
 {
-    "name": "symfony/polyfill-mbstring",
+    "name": "symfony/polyfill-intl-normalizer",
     "type": "library",
-    "description": "Symfony polyfill for the Mbstring extension",
-    "keywords": ["polyfill", "shim", "compatibility", "portable", "mbstring"],
+    "description": "Symfony polyfill for intl's Normalizer class and related functions",
+    "keywords": ["polyfill", "shim", "compatibility", "portable", "intl", "normalizer"],
     "homepage": "https://symfony.com",
     "license": "MIT",
     "authors": [
@@ -16,19 +16,20 @@
         }
     ],
     "require": {
-        "php": ">=5.3.3"
+        "php": ">=7.1"
     },
     "autoload": {
-        "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" },
-        "files": [ "bootstrap.php" ]
+        "psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" },
+        "files": [ "bootstrap.php" ],
+        "classmap": [ "Resources/stubs" ]
     },
     "suggest": {
-        "ext-mbstring": "For best performance"
+        "ext-intl": "For best performance"
     },
     "minimum-stability": "dev",
     "extra": {
         "branch-alias": {
-            "dev-master": "1.17-dev"
+            "dev-main": "1.22-dev"
         },
         "thanks": {
             "name": "symfony/polyfill",
diff --git a/vendor/symfony/polyfill-mbstring/Mbstring.php b/vendor/symfony/polyfill-mbstring/Mbstring.php
deleted file mode 100644
index 15503bc9d..000000000
--- a/vendor/symfony/polyfill-mbstring/Mbstring.php
+++ /dev/null
@@ -1,847 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Polyfill\Mbstring;
-
-/**
- * Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
- *
- * Implemented:
- * - mb_chr                  - Returns a specific character from its Unicode code point
- * - mb_convert_encoding     - Convert character encoding
- * - mb_convert_variables    - Convert character code in variable(s)
- * - mb_decode_mimeheader    - Decode string in MIME header field
- * - mb_encode_mimeheader    - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED
- * - mb_decode_numericentity - Decode HTML numeric string reference to character
- * - mb_encode_numericentity - Encode character to HTML numeric string reference
- * - mb_convert_case         - Perform case folding on a string
- * - mb_detect_encoding      - Detect character encoding
- * - mb_get_info             - Get internal settings of mbstring
- * - mb_http_input           - Detect HTTP input character encoding
- * - mb_http_output          - Set/Get HTTP output character encoding
- * - mb_internal_encoding    - Set/Get internal character encoding
- * - mb_list_encodings       - Returns an array of all supported encodings
- * - mb_ord                  - Returns the Unicode code point of a character
- * - mb_output_handler       - Callback function converts character encoding in output buffer
- * - mb_scrub                - Replaces ill-formed byte sequences with substitute characters
- * - mb_strlen               - Get string length
- * - mb_strpos               - Find position of first occurrence of string in a string
- * - mb_strrpos              - Find position of last occurrence of a string in a string
- * - mb_str_split            - Convert a string to an array
- * - mb_strtolower           - Make a string lowercase
- * - mb_strtoupper           - Make a string uppercase
- * - mb_substitute_character - Set/Get substitution character
- * - mb_substr               - Get part of string
- * - mb_stripos              - Finds position of first occurrence of a string within another, case insensitive
- * - mb_stristr              - Finds first occurrence of a string within another, case insensitive
- * - mb_strrchr              - Finds the last occurrence of a character in a string within another
- * - mb_strrichr             - Finds the last occurrence of a character in a string within another, case insensitive
- * - mb_strripos             - Finds position of last occurrence of a string within another, case insensitive
- * - mb_strstr               - Finds first occurrence of a string within another
- * - mb_strwidth             - Return width of string
- * - mb_substr_count         - Count the number of substring occurrences
- *
- * Not implemented:
- * - mb_convert_kana         - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
- * - mb_ereg_*               - Regular expression with multibyte support
- * - mb_parse_str            - Parse GET/POST/COOKIE data and set global variable
- * - mb_preferred_mime_name  - Get MIME charset string
- * - mb_regex_encoding       - Returns current encoding for multibyte regex as string
- * - mb_regex_set_options    - Set/Get the default options for mbregex functions
- * - mb_send_mail            - Send encoded mail
- * - mb_split                - Split multibyte string using regular expression
- * - mb_strcut               - Get part of string
- * - mb_strimwidth           - Get truncated string with specified width
- *
- * @author Nicolas Grekas 
- *
- * @internal
- */
-final class Mbstring
-{
-    const MB_CASE_FOLD = PHP_INT_MAX;
-
-    private static $encodingList = array('ASCII', 'UTF-8');
-    private static $language = 'neutral';
-    private static $internalEncoding = 'UTF-8';
-    private static $caseFold = array(
-        array('µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"),
-        array('μ', 's', 'ι',        'σ', 'β',        'θ',        'φ',        'π',        'κ',        'ρ',        'ε',        "\xE1\xB9\xA1", 'ι'),
-    );
-
-    public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
-    {
-        if (\is_array($fromEncoding) || false !== strpos($fromEncoding, ',')) {
-            $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
-        } else {
-            $fromEncoding = self::getEncoding($fromEncoding);
-        }
-
-        $toEncoding = self::getEncoding($toEncoding);
-
-        if ('BASE64' === $fromEncoding) {
-            $s = base64_decode($s);
-            $fromEncoding = $toEncoding;
-        }
-
-        if ('BASE64' === $toEncoding) {
-            return base64_encode($s);
-        }
-
-        if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
-            if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
-                $fromEncoding = 'Windows-1252';
-            }
-            if ('UTF-8' !== $fromEncoding) {
-                $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s);
-            }
-
-            return preg_replace_callback('/[\x80-\xFF]+/', array(__CLASS__, 'html_encoding_callback'), $s);
-        }
-
-        if ('HTML-ENTITIES' === $fromEncoding) {
-            $s = html_entity_decode($s, ENT_COMPAT, 'UTF-8');
-            $fromEncoding = 'UTF-8';
-        }
-
-        return iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
-    }
-
-    public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null)
-    {
-        $vars = array(&$a, &$b, &$c, &$d, &$e, &$f);
-
-        $ok = true;
-        array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) {
-            if (false === $v = Mbstring::mb_convert_encoding($v, $toEncoding, $fromEncoding)) {
-                $ok = false;
-            }
-        });
-
-        return $ok ? $fromEncoding : false;
-    }
-
-    public static function mb_decode_mimeheader($s)
-    {
-        return iconv_mime_decode($s, 2, self::$internalEncoding);
-    }
-
-    public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
-    {
-        trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING);
-    }
-
-    public static function mb_decode_numericentity($s, $convmap, $encoding = null)
-    {
-        if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
-            trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING);
-
-            return null;
-        }
-
-        if (!\is_array($convmap) || !$convmap) {
-            return false;
-        }
-
-        if (null !== $encoding && !\is_scalar($encoding)) {
-            trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING);
-
-            return '';  // Instead of null (cf. mb_encode_numericentity).
-        }
-
-        $s = (string) $s;
-        if ('' === $s) {
-            return '';
-        }
-
-        $encoding = self::getEncoding($encoding);
-
-        if ('UTF-8' === $encoding) {
-            $encoding = null;
-            if (!preg_match('//u', $s)) {
-                $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
-            }
-        } else {
-            $s = iconv($encoding, 'UTF-8//IGNORE', $s);
-        }
-
-        $cnt = floor(\count($convmap) / 4) * 4;
-
-        for ($i = 0; $i < $cnt; $i += 4) {
-            // collector_decode_htmlnumericentity ignores $convmap[$i + 3]
-            $convmap[$i] += $convmap[$i + 2];
-            $convmap[$i + 1] += $convmap[$i + 2];
-        }
-
-        $s = preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use ($cnt, $convmap) {
-            $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1];
-            for ($i = 0; $i < $cnt; $i += 4) {
-                if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) {
-                    return Mbstring::mb_chr($c - $convmap[$i + 2]);
-                }
-            }
-
-            return $m[0];
-        }, $s);
-
-        if (null === $encoding) {
-            return $s;
-        }
-
-        return iconv('UTF-8', $encoding.'//IGNORE', $s);
-    }
-
-    public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false)
-    {
-        if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
-            trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING);
-
-            return null;
-        }
-
-        if (!\is_array($convmap) || !$convmap) {
-            return false;
-        }
-
-        if (null !== $encoding && !\is_scalar($encoding)) {
-            trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING);
-
-            return null;  // Instead of '' (cf. mb_decode_numericentity).
-        }
-
-        if (null !== $is_hex && !\is_scalar($is_hex)) {
-            trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', E_USER_WARNING);
-
-            return null;
-        }
-
-        $s = (string) $s;
-        if ('' === $s) {
-            return '';
-        }
-
-        $encoding = self::getEncoding($encoding);
-
-        if ('UTF-8' === $encoding) {
-            $encoding = null;
-            if (!preg_match('//u', $s)) {
-                $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
-            }
-        } else {
-            $s = iconv($encoding, 'UTF-8//IGNORE', $s);
-        }
-
-        static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
-
-        $cnt = floor(\count($convmap) / 4) * 4;
-        $i = 0;
-        $len = \strlen($s);
-        $result = '';
-
-        while ($i < $len) {
-            $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
-            $uchr = substr($s, $i, $ulen);
-            $i += $ulen;
-            $c = self::mb_ord($uchr);
-
-            for ($j = 0; $j < $cnt; $j += 4) {
-                if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) {
-                    $cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3];
-                    $result .= $is_hex ? sprintf('&#x%X;', $cOffset) : '&#'.$cOffset.';';
-                    continue 2;
-                }
-            }
-            $result .= $uchr;
-        }
-
-        if (null === $encoding) {
-            return $result;
-        }
-
-        return iconv('UTF-8', $encoding.'//IGNORE', $result);
-    }
-
-    public static function mb_convert_case($s, $mode, $encoding = null)
-    {
-        $s = (string) $s;
-        if ('' === $s) {
-            return '';
-        }
-
-        $encoding = self::getEncoding($encoding);
-
-        if ('UTF-8' === $encoding) {
-            $encoding = null;
-            if (!preg_match('//u', $s)) {
-                $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
-            }
-        } else {
-            $s = iconv($encoding, 'UTF-8//IGNORE', $s);
-        }
-
-        if (MB_CASE_TITLE == $mode) {
-            static $titleRegexp = null;
-            if (null === $titleRegexp) {
-                $titleRegexp = self::getData('titleCaseRegexp');
-            }
-            $s = preg_replace_callback($titleRegexp, array(__CLASS__, 'title_case'), $s);
-        } else {
-            if (MB_CASE_UPPER == $mode) {
-                static $upper = null;
-                if (null === $upper) {
-                    $upper = self::getData('upperCase');
-                }
-                $map = $upper;
-            } else {
-                if (self::MB_CASE_FOLD === $mode) {
-                    $s = str_replace(self::$caseFold[0], self::$caseFold[1], $s);
-                }
-
-                static $lower = null;
-                if (null === $lower) {
-                    $lower = self::getData('lowerCase');
-                }
-                $map = $lower;
-            }
-
-            static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
-
-            $i = 0;
-            $len = \strlen($s);
-
-            while ($i < $len) {
-                $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
-                $uchr = substr($s, $i, $ulen);
-                $i += $ulen;
-
-                if (isset($map[$uchr])) {
-                    $uchr = $map[$uchr];
-                    $nlen = \strlen($uchr);
-
-                    if ($nlen == $ulen) {
-                        $nlen = $i;
-                        do {
-                            $s[--$nlen] = $uchr[--$ulen];
-                        } while ($ulen);
-                    } else {
-                        $s = substr_replace($s, $uchr, $i - $ulen, $ulen);
-                        $len += $nlen - $ulen;
-                        $i += $nlen - $ulen;
-                    }
-                }
-            }
-        }
-
-        if (null === $encoding) {
-            return $s;
-        }
-
-        return iconv('UTF-8', $encoding.'//IGNORE', $s);
-    }
-
-    public static function mb_internal_encoding($encoding = null)
-    {
-        if (null === $encoding) {
-            return self::$internalEncoding;
-        }
-
-        $encoding = self::getEncoding($encoding);
-
-        if ('UTF-8' === $encoding || false !== @iconv($encoding, $encoding, ' ')) {
-            self::$internalEncoding = $encoding;
-
-            return true;
-        }
-
-        return false;
-    }
-
-    public static function mb_language($lang = null)
-    {
-        if (null === $lang) {
-            return self::$language;
-        }
-
-        switch ($lang = strtolower($lang)) {
-            case 'uni':
-            case 'neutral':
-                self::$language = $lang;
-
-                return true;
-        }
-
-        return false;
-    }
-
-    public static function mb_list_encodings()
-    {
-        return array('UTF-8');
-    }
-
-    public static function mb_encoding_aliases($encoding)
-    {
-        switch (strtoupper($encoding)) {
-            case 'UTF8':
-            case 'UTF-8':
-                return array('utf8');
-        }
-
-        return false;
-    }
-
-    public static function mb_check_encoding($var = null, $encoding = null)
-    {
-        if (null === $encoding) {
-            if (null === $var) {
-                return false;
-            }
-            $encoding = self::$internalEncoding;
-        }
-
-        return self::mb_detect_encoding($var, array($encoding)) || false !== @iconv($encoding, $encoding, $var);
-    }
-
-    public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
-    {
-        if (null === $encodingList) {
-            $encodingList = self::$encodingList;
-        } else {
-            if (!\is_array($encodingList)) {
-                $encodingList = array_map('trim', explode(',', $encodingList));
-            }
-            $encodingList = array_map('strtoupper', $encodingList);
-        }
-
-        foreach ($encodingList as $enc) {
-            switch ($enc) {
-                case 'ASCII':
-                    if (!preg_match('/[\x80-\xFF]/', $str)) {
-                        return $enc;
-                    }
-                    break;
-
-                case 'UTF8':
-                case 'UTF-8':
-                    if (preg_match('//u', $str)) {
-                        return 'UTF-8';
-                    }
-                    break;
-
-                default:
-                    if (0 === strncmp($enc, 'ISO-8859-', 9)) {
-                        return $enc;
-                    }
-            }
-        }
-
-        return false;
-    }
-
-    public static function mb_detect_order($encodingList = null)
-    {
-        if (null === $encodingList) {
-            return self::$encodingList;
-        }
-
-        if (!\is_array($encodingList)) {
-            $encodingList = array_map('trim', explode(',', $encodingList));
-        }
-        $encodingList = array_map('strtoupper', $encodingList);
-
-        foreach ($encodingList as $enc) {
-            switch ($enc) {
-                default:
-                    if (strncmp($enc, 'ISO-8859-', 9)) {
-                        return false;
-                    }
-                    // no break
-                case 'ASCII':
-                case 'UTF8':
-                case 'UTF-8':
-            }
-        }
-
-        self::$encodingList = $encodingList;
-
-        return true;
-    }
-
-    public static function mb_strlen($s, $encoding = null)
-    {
-        $encoding = self::getEncoding($encoding);
-        if ('CP850' === $encoding || 'ASCII' === $encoding) {
-            return \strlen($s);
-        }
-
-        return @iconv_strlen($s, $encoding);
-    }
-
-    public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
-    {
-        $encoding = self::getEncoding($encoding);
-        if ('CP850' === $encoding || 'ASCII' === $encoding) {
-            return strpos($haystack, $needle, $offset);
-        }
-
-        $needle = (string) $needle;
-        if ('' === $needle) {
-            trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING);
-
-            return false;
-        }
-
-        return iconv_strpos($haystack, $needle, $offset, $encoding);
-    }
-
-    public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
-    {
-        $encoding = self::getEncoding($encoding);
-        if ('CP850' === $encoding || 'ASCII' === $encoding) {
-            return strrpos($haystack, $needle, $offset);
-        }
-
-        if ($offset != (int) $offset) {
-            $offset = 0;
-        } elseif ($offset = (int) $offset) {
-            if ($offset < 0) {
-                if (0 > $offset += self::mb_strlen($needle)) {
-                    $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
-                }
-                $offset = 0;
-            } else {
-                $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
-            }
-        }
-
-        $pos = iconv_strrpos($haystack, $needle, $encoding);
-
-        return false !== $pos ? $offset + $pos : false;
-    }
-
-    public static function mb_str_split($string, $split_length = 1, $encoding = null)
-    {
-        if (null !== $string && !\is_scalar($string) && !(\is_object($string) && \method_exists($string, '__toString'))) {
-            trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', E_USER_WARNING);
-
-            return null;
-        }
-
-        if (1 > $split_length = (int) $split_length) {
-            trigger_error('The length of each segment must be greater than zero', E_USER_WARNING);
-
-            return false;
-        }
-
-        if (null === $encoding) {
-            $encoding = mb_internal_encoding();
-        }
-
-        if ('UTF-8' === $encoding = self::getEncoding($encoding)) {
-            $rx = '/(';
-            while (65535 < $split_length) {
-                $rx .= '.{65535}';
-                $split_length -= 65535;
-            }
-            $rx .= '.{'.$split_length.'})/us';
-
-            return preg_split($rx, $string, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
-        }
-
-        $result = array();
-        $length = mb_strlen($string, $encoding);
-
-        for ($i = 0; $i < $length; $i += $split_length) {
-            $result[] = mb_substr($string, $i, $split_length, $encoding);
-        }
-
-        return $result;
-    }
-
-    public static function mb_strtolower($s, $encoding = null)
-    {
-        return self::mb_convert_case($s, MB_CASE_LOWER, $encoding);
-    }
-
-    public static function mb_strtoupper($s, $encoding = null)
-    {
-        return self::mb_convert_case($s, MB_CASE_UPPER, $encoding);
-    }
-
-    public static function mb_substitute_character($c = null)
-    {
-        if (0 === strcasecmp($c, 'none')) {
-            return true;
-        }
-
-        return null !== $c ? false : 'none';
-    }
-
-    public static function mb_substr($s, $start, $length = null, $encoding = null)
-    {
-        $encoding = self::getEncoding($encoding);
-        if ('CP850' === $encoding || 'ASCII' === $encoding) {
-            return (string) substr($s, $start, null === $length ? 2147483647 : $length);
-        }
-
-        if ($start < 0) {
-            $start = iconv_strlen($s, $encoding) + $start;
-            if ($start < 0) {
-                $start = 0;
-            }
-        }
-
-        if (null === $length) {
-            $length = 2147483647;
-        } elseif ($length < 0) {
-            $length = iconv_strlen($s, $encoding) + $length - $start;
-            if ($length < 0) {
-                return '';
-            }
-        }
-
-        return (string) iconv_substr($s, $start, $length, $encoding);
-    }
-
-    public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
-    {
-        $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
-        $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
-
-        return self::mb_strpos($haystack, $needle, $offset, $encoding);
-    }
-
-    public static function mb_stristr($haystack, $needle, $part = false, $encoding = null)
-    {
-        $pos = self::mb_stripos($haystack, $needle, 0, $encoding);
-
-        return self::getSubpart($pos, $part, $haystack, $encoding);
-    }
-
-    public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null)
-    {
-        $encoding = self::getEncoding($encoding);
-        if ('CP850' === $encoding || 'ASCII' === $encoding) {
-            return strrchr($haystack, $needle, $part);
-        }
-        $needle = self::mb_substr($needle, 0, 1, $encoding);
-        $pos = iconv_strrpos($haystack, $needle, $encoding);
-
-        return self::getSubpart($pos, $part, $haystack, $encoding);
-    }
-
-    public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null)
-    {
-        $needle = self::mb_substr($needle, 0, 1, $encoding);
-        $pos = self::mb_strripos($haystack, $needle, $encoding);
-
-        return self::getSubpart($pos, $part, $haystack, $encoding);
-    }
-
-    public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
-    {
-        $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
-        $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
-
-        return self::mb_strrpos($haystack, $needle, $offset, $encoding);
-    }
-
-    public static function mb_strstr($haystack, $needle, $part = false, $encoding = null)
-    {
-        $pos = strpos($haystack, $needle);
-        if (false === $pos) {
-            return false;
-        }
-        if ($part) {
-            return substr($haystack, 0, $pos);
-        }
-
-        return substr($haystack, $pos);
-    }
-
-    public static function mb_get_info($type = 'all')
-    {
-        $info = array(
-            'internal_encoding' => self::$internalEncoding,
-            'http_output' => 'pass',
-            'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)',
-            'func_overload' => 0,
-            'func_overload_list' => 'no overload',
-            'mail_charset' => 'UTF-8',
-            'mail_header_encoding' => 'BASE64',
-            'mail_body_encoding' => 'BASE64',
-            'illegal_chars' => 0,
-            'encoding_translation' => 'Off',
-            'language' => self::$language,
-            'detect_order' => self::$encodingList,
-            'substitute_character' => 'none',
-            'strict_detection' => 'Off',
-        );
-
-        if ('all' === $type) {
-            return $info;
-        }
-        if (isset($info[$type])) {
-            return $info[$type];
-        }
-
-        return false;
-    }
-
-    public static function mb_http_input($type = '')
-    {
-        return false;
-    }
-
-    public static function mb_http_output($encoding = null)
-    {
-        return null !== $encoding ? 'pass' === $encoding : 'pass';
-    }
-
-    public static function mb_strwidth($s, $encoding = null)
-    {
-        $encoding = self::getEncoding($encoding);
-
-        if ('UTF-8' !== $encoding) {
-            $s = iconv($encoding, 'UTF-8//IGNORE', $s);
-        }
-
-        $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);
-
-        return ($wide << 1) + iconv_strlen($s, 'UTF-8');
-    }
-
-    public static function mb_substr_count($haystack, $needle, $encoding = null)
-    {
-        return substr_count($haystack, $needle);
-    }
-
-    public static function mb_output_handler($contents, $status)
-    {
-        return $contents;
-    }
-
-    public static function mb_chr($code, $encoding = null)
-    {
-        if (0x80 > $code %= 0x200000) {
-            $s = \chr($code);
-        } elseif (0x800 > $code) {
-            $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
-        } elseif (0x10000 > $code) {
-            $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
-        } else {
-            $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
-        }
-
-        if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
-            $s = mb_convert_encoding($s, $encoding, 'UTF-8');
-        }
-
-        return $s;
-    }
-
-    public static function mb_ord($s, $encoding = null)
-    {
-        if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
-            $s = mb_convert_encoding($s, 'UTF-8', $encoding);
-        }
-
-        if (1 === \strlen($s)) {
-            return \ord($s);
-        }
-
-        $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
-        if (0xF0 <= $code) {
-            return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
-        }
-        if (0xE0 <= $code) {
-            return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
-        }
-        if (0xC0 <= $code) {
-            return (($code - 0xC0) << 6) + $s[2] - 0x80;
-        }
-
-        return $code;
-    }
-
-    private static function getSubpart($pos, $part, $haystack, $encoding)
-    {
-        if (false === $pos) {
-            return false;
-        }
-        if ($part) {
-            return self::mb_substr($haystack, 0, $pos, $encoding);
-        }
-
-        return self::mb_substr($haystack, $pos, null, $encoding);
-    }
-
-    private static function html_encoding_callback(array $m)
-    {
-        $i = 1;
-        $entities = '';
-        $m = unpack('C*', htmlentities($m[0], ENT_COMPAT, 'UTF-8'));
-
-        while (isset($m[$i])) {
-            if (0x80 > $m[$i]) {
-                $entities .= \chr($m[$i++]);
-                continue;
-            }
-            if (0xF0 <= $m[$i]) {
-                $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
-            } elseif (0xE0 <= $m[$i]) {
-                $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
-            } else {
-                $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
-            }
-
-            $entities .= '&#'.$c.';';
-        }
-
-        return $entities;
-    }
-
-    private static function title_case(array $s)
-    {
-        return self::mb_convert_case($s[1], MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], MB_CASE_LOWER, 'UTF-8');
-    }
-
-    private static function getData($file)
-    {
-        if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
-            return require $file;
-        }
-
-        return false;
-    }
-
-    private static function getEncoding($encoding)
-    {
-        if (null === $encoding) {
-            return self::$internalEncoding;
-        }
-
-        if ('UTF-8' === $encoding) {
-            return 'UTF-8';
-        }
-
-        $encoding = strtoupper($encoding);
-
-        if ('8BIT' === $encoding || 'BINARY' === $encoding) {
-            return 'CP850';
-        }
-
-        if ('UTF8' === $encoding) {
-            return 'UTF-8';
-        }
-
-        return $encoding;
-    }
-}
diff --git a/vendor/symfony/polyfill-mbstring/README.md b/vendor/symfony/polyfill-mbstring/README.md
deleted file mode 100644
index 4efb599d8..000000000
--- a/vendor/symfony/polyfill-mbstring/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-Symfony Polyfill / Mbstring
-===========================
-
-This component provides a partial, native PHP implementation for the
-[Mbstring](https://php.net/mbstring) extension.
-
-More information can be found in the
-[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
-
-License
-=======
-
-This library is released under the [MIT license](LICENSE).
diff --git a/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php b/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php
deleted file mode 100644
index a22eca57b..000000000
--- a/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php
+++ /dev/null
@@ -1,1397 +0,0 @@
- 'a',
-  'B' => 'b',
-  'C' => 'c',
-  'D' => 'd',
-  'E' => 'e',
-  'F' => 'f',
-  'G' => 'g',
-  'H' => 'h',
-  'I' => 'i',
-  'J' => 'j',
-  'K' => 'k',
-  'L' => 'l',
-  'M' => 'm',
-  'N' => 'n',
-  'O' => 'o',
-  'P' => 'p',
-  'Q' => 'q',
-  'R' => 'r',
-  'S' => 's',
-  'T' => 't',
-  'U' => 'u',
-  'V' => 'v',
-  'W' => 'w',
-  'X' => 'x',
-  'Y' => 'y',
-  'Z' => 'z',
-  'À' => 'à',
-  'Á' => 'á',
-  'Â' => 'â',
-  'Ã' => 'ã',
-  'Ä' => 'ä',
-  'Å' => 'å',
-  'Æ' => 'æ',
-  'Ç' => 'ç',
-  'È' => 'è',
-  'É' => 'é',
-  'Ê' => 'ê',
-  'Ë' => 'ë',
-  'Ì' => 'ì',
-  'Í' => 'í',
-  'Î' => 'î',
-  'Ï' => 'ï',
-  'Ð' => 'ð',
-  'Ñ' => 'ñ',
-  'Ò' => 'ò',
-  'Ó' => 'ó',
-  'Ô' => 'ô',
-  'Õ' => 'õ',
-  'Ö' => 'ö',
-  'Ø' => 'ø',
-  'Ù' => 'ù',
-  'Ú' => 'ú',
-  'Û' => 'û',
-  'Ü' => 'ü',
-  'Ý' => 'ý',
-  'Þ' => 'þ',
-  'Ā' => 'ā',
-  'Ă' => 'ă',
-  'Ą' => 'ą',
-  'Ć' => 'ć',
-  'Ĉ' => 'ĉ',
-  'Ċ' => 'ċ',
-  'Č' => 'č',
-  'Ď' => 'ď',
-  'Đ' => 'đ',
-  'Ē' => 'ē',
-  'Ĕ' => 'ĕ',
-  'Ė' => 'ė',
-  'Ę' => 'ę',
-  'Ě' => 'ě',
-  'Ĝ' => 'ĝ',
-  'Ğ' => 'ğ',
-  'Ġ' => 'ġ',
-  'Ģ' => 'ģ',
-  'Ĥ' => 'ĥ',
-  'Ħ' => 'ħ',
-  'Ĩ' => 'ĩ',
-  'Ī' => 'ī',
-  'Ĭ' => 'ĭ',
-  'Į' => 'į',
-  'İ' => 'i',
-  'IJ' => 'ij',
-  'Ĵ' => 'ĵ',
-  'Ķ' => 'ķ',
-  'Ĺ' => 'ĺ',
-  'Ļ' => 'ļ',
-  'Ľ' => 'ľ',
-  'Ŀ' => 'ŀ',
-  'Ł' => 'ł',
-  'Ń' => 'ń',
-  'Ņ' => 'ņ',
-  'Ň' => 'ň',
-  'Ŋ' => 'ŋ',
-  'Ō' => 'ō',
-  'Ŏ' => 'ŏ',
-  'Ő' => 'ő',
-  'Œ' => 'œ',
-  'Ŕ' => 'ŕ',
-  'Ŗ' => 'ŗ',
-  'Ř' => 'ř',
-  'Ś' => 'ś',
-  'Ŝ' => 'ŝ',
-  'Ş' => 'ş',
-  'Š' => 'š',
-  'Ţ' => 'ţ',
-  'Ť' => 'ť',
-  'Ŧ' => 'ŧ',
-  'Ũ' => 'ũ',
-  'Ū' => 'ū',
-  'Ŭ' => 'ŭ',
-  'Ů' => 'ů',
-  'Ű' => 'ű',
-  'Ų' => 'ų',
-  'Ŵ' => 'ŵ',
-  'Ŷ' => 'ŷ',
-  'Ÿ' => 'ÿ',
-  'Ź' => 'ź',
-  'Ż' => 'ż',
-  'Ž' => 'ž',
-  'Ɓ' => 'ɓ',
-  'Ƃ' => 'ƃ',
-  'Ƅ' => 'ƅ',
-  'Ɔ' => 'ɔ',
-  'Ƈ' => 'ƈ',
-  'Ɖ' => 'ɖ',
-  'Ɗ' => 'ɗ',
-  'Ƌ' => 'ƌ',
-  'Ǝ' => 'ǝ',
-  'Ə' => 'ə',
-  'Ɛ' => 'ɛ',
-  'Ƒ' => 'ƒ',
-  'Ɠ' => 'ɠ',
-  'Ɣ' => 'ɣ',
-  'Ɩ' => 'ɩ',
-  'Ɨ' => 'ɨ',
-  'Ƙ' => 'ƙ',
-  'Ɯ' => 'ɯ',
-  'Ɲ' => 'ɲ',
-  'Ɵ' => 'ɵ',
-  'Ơ' => 'ơ',
-  'Ƣ' => 'ƣ',
-  'Ƥ' => 'ƥ',
-  'Ʀ' => 'ʀ',
-  'Ƨ' => 'ƨ',
-  'Ʃ' => 'ʃ',
-  'Ƭ' => 'ƭ',
-  'Ʈ' => 'ʈ',
-  'Ư' => 'ư',
-  'Ʊ' => 'ʊ',
-  'Ʋ' => 'ʋ',
-  'Ƴ' => 'ƴ',
-  'Ƶ' => 'ƶ',
-  'Ʒ' => 'ʒ',
-  'Ƹ' => 'ƹ',
-  'Ƽ' => 'ƽ',
-  'DŽ' => 'dž',
-  'Dž' => 'dž',
-  'LJ' => 'lj',
-  'Lj' => 'lj',
-  'NJ' => 'nj',
-  'Nj' => 'nj',
-  'Ǎ' => 'ǎ',
-  'Ǐ' => 'ǐ',
-  'Ǒ' => 'ǒ',
-  'Ǔ' => 'ǔ',
-  'Ǖ' => 'ǖ',
-  'Ǘ' => 'ǘ',
-  'Ǚ' => 'ǚ',
-  'Ǜ' => 'ǜ',
-  'Ǟ' => 'ǟ',
-  'Ǡ' => 'ǡ',
-  'Ǣ' => 'ǣ',
-  'Ǥ' => 'ǥ',
-  'Ǧ' => 'ǧ',
-  'Ǩ' => 'ǩ',
-  'Ǫ' => 'ǫ',
-  'Ǭ' => 'ǭ',
-  'Ǯ' => 'ǯ',
-  'DZ' => 'dz',
-  'Dz' => 'dz',
-  'Ǵ' => 'ǵ',
-  'Ƕ' => 'ƕ',
-  'Ƿ' => 'ƿ',
-  'Ǹ' => 'ǹ',
-  'Ǻ' => 'ǻ',
-  'Ǽ' => 'ǽ',
-  'Ǿ' => 'ǿ',
-  'Ȁ' => 'ȁ',
-  'Ȃ' => 'ȃ',
-  'Ȅ' => 'ȅ',
-  'Ȇ' => 'ȇ',
-  'Ȉ' => 'ȉ',
-  'Ȋ' => 'ȋ',
-  'Ȍ' => 'ȍ',
-  'Ȏ' => 'ȏ',
-  'Ȑ' => 'ȑ',
-  'Ȓ' => 'ȓ',
-  'Ȕ' => 'ȕ',
-  'Ȗ' => 'ȗ',
-  'Ș' => 'ș',
-  'Ț' => 'ț',
-  'Ȝ' => 'ȝ',
-  'Ȟ' => 'ȟ',
-  'Ƞ' => 'ƞ',
-  'Ȣ' => 'ȣ',
-  'Ȥ' => 'ȥ',
-  'Ȧ' => 'ȧ',
-  'Ȩ' => 'ȩ',
-  'Ȫ' => 'ȫ',
-  'Ȭ' => 'ȭ',
-  'Ȯ' => 'ȯ',
-  'Ȱ' => 'ȱ',
-  'Ȳ' => 'ȳ',
-  'Ⱥ' => 'ⱥ',
-  'Ȼ' => 'ȼ',
-  'Ƚ' => 'ƚ',
-  'Ⱦ' => 'ⱦ',
-  'Ɂ' => 'ɂ',
-  'Ƀ' => 'ƀ',
-  'Ʉ' => 'ʉ',
-  'Ʌ' => 'ʌ',
-  'Ɇ' => 'ɇ',
-  'Ɉ' => 'ɉ',
-  'Ɋ' => 'ɋ',
-  'Ɍ' => 'ɍ',
-  'Ɏ' => 'ɏ',
-  'Ͱ' => 'ͱ',
-  'Ͳ' => 'ͳ',
-  'Ͷ' => 'ͷ',
-  'Ϳ' => 'ϳ',
-  'Ά' => 'ά',
-  'Έ' => 'έ',
-  'Ή' => 'ή',
-  'Ί' => 'ί',
-  'Ό' => 'ό',
-  'Ύ' => 'ύ',
-  'Ώ' => 'ώ',
-  'Α' => 'α',
-  'Β' => 'β',
-  'Γ' => 'γ',
-  'Δ' => 'δ',
-  'Ε' => 'ε',
-  'Ζ' => 'ζ',
-  'Η' => 'η',
-  'Θ' => 'θ',
-  'Ι' => 'ι',
-  'Κ' => 'κ',
-  'Λ' => 'λ',
-  'Μ' => 'μ',
-  'Ν' => 'ν',
-  'Ξ' => 'ξ',
-  'Ο' => 'ο',
-  'Π' => 'π',
-  'Ρ' => 'ρ',
-  'Σ' => 'σ',
-  'Τ' => 'τ',
-  'Υ' => 'υ',
-  'Φ' => 'φ',
-  'Χ' => 'χ',
-  'Ψ' => 'ψ',
-  'Ω' => 'ω',
-  'Ϊ' => 'ϊ',
-  'Ϋ' => 'ϋ',
-  'Ϗ' => 'ϗ',
-  'Ϙ' => 'ϙ',
-  'Ϛ' => 'ϛ',
-  'Ϝ' => 'ϝ',
-  'Ϟ' => 'ϟ',
-  'Ϡ' => 'ϡ',
-  'Ϣ' => 'ϣ',
-  'Ϥ' => 'ϥ',
-  'Ϧ' => 'ϧ',
-  'Ϩ' => 'ϩ',
-  'Ϫ' => 'ϫ',
-  'Ϭ' => 'ϭ',
-  'Ϯ' => 'ϯ',
-  'ϴ' => 'θ',
-  'Ϸ' => 'ϸ',
-  'Ϲ' => 'ϲ',
-  'Ϻ' => 'ϻ',
-  'Ͻ' => 'ͻ',
-  'Ͼ' => 'ͼ',
-  'Ͽ' => 'ͽ',
-  'Ѐ' => 'ѐ',
-  'Ё' => 'ё',
-  'Ђ' => 'ђ',
-  'Ѓ' => 'ѓ',
-  'Є' => 'є',
-  'Ѕ' => 'ѕ',
-  'І' => 'і',
-  'Ї' => 'ї',
-  'Ј' => 'ј',
-  'Љ' => 'љ',
-  'Њ' => 'њ',
-  'Ћ' => 'ћ',
-  'Ќ' => 'ќ',
-  'Ѝ' => 'ѝ',
-  'Ў' => 'ў',
-  'Џ' => 'џ',
-  'А' => 'а',
-  'Б' => 'б',
-  'В' => 'в',
-  'Г' => 'г',
-  'Д' => 'д',
-  'Е' => 'е',
-  'Ж' => 'ж',
-  'З' => 'з',
-  'И' => 'и',
-  'Й' => 'й',
-  'К' => 'к',
-  'Л' => 'л',
-  'М' => 'м',
-  'Н' => 'н',
-  'О' => 'о',
-  'П' => 'п',
-  'Р' => 'р',
-  'С' => 'с',
-  'Т' => 'т',
-  'У' => 'у',
-  'Ф' => 'ф',
-  'Х' => 'х',
-  'Ц' => 'ц',
-  'Ч' => 'ч',
-  'Ш' => 'ш',
-  'Щ' => 'щ',
-  'Ъ' => 'ъ',
-  'Ы' => 'ы',
-  'Ь' => 'ь',
-  'Э' => 'э',
-  'Ю' => 'ю',
-  'Я' => 'я',
-  'Ѡ' => 'ѡ',
-  'Ѣ' => 'ѣ',
-  'Ѥ' => 'ѥ',
-  'Ѧ' => 'ѧ',
-  'Ѩ' => 'ѩ',
-  'Ѫ' => 'ѫ',
-  'Ѭ' => 'ѭ',
-  'Ѯ' => 'ѯ',
-  'Ѱ' => 'ѱ',
-  'Ѳ' => 'ѳ',
-  'Ѵ' => 'ѵ',
-  'Ѷ' => 'ѷ',
-  'Ѹ' => 'ѹ',
-  'Ѻ' => 'ѻ',
-  'Ѽ' => 'ѽ',
-  'Ѿ' => 'ѿ',
-  'Ҁ' => 'ҁ',
-  'Ҋ' => 'ҋ',
-  'Ҍ' => 'ҍ',
-  'Ҏ' => 'ҏ',
-  'Ґ' => 'ґ',
-  'Ғ' => 'ғ',
-  'Ҕ' => 'ҕ',
-  'Җ' => 'җ',
-  'Ҙ' => 'ҙ',
-  'Қ' => 'қ',
-  'Ҝ' => 'ҝ',
-  'Ҟ' => 'ҟ',
-  'Ҡ' => 'ҡ',
-  'Ң' => 'ң',
-  'Ҥ' => 'ҥ',
-  'Ҧ' => 'ҧ',
-  'Ҩ' => 'ҩ',
-  'Ҫ' => 'ҫ',
-  'Ҭ' => 'ҭ',
-  'Ү' => 'ү',
-  'Ұ' => 'ұ',
-  'Ҳ' => 'ҳ',
-  'Ҵ' => 'ҵ',
-  'Ҷ' => 'ҷ',
-  'Ҹ' => 'ҹ',
-  'Һ' => 'һ',
-  'Ҽ' => 'ҽ',
-  'Ҿ' => 'ҿ',
-  'Ӏ' => 'ӏ',
-  'Ӂ' => 'ӂ',
-  'Ӄ' => 'ӄ',
-  'Ӆ' => 'ӆ',
-  'Ӈ' => 'ӈ',
-  'Ӊ' => 'ӊ',
-  'Ӌ' => 'ӌ',
-  'Ӎ' => 'ӎ',
-  'Ӑ' => 'ӑ',
-  'Ӓ' => 'ӓ',
-  'Ӕ' => 'ӕ',
-  'Ӗ' => 'ӗ',
-  'Ә' => 'ә',
-  'Ӛ' => 'ӛ',
-  'Ӝ' => 'ӝ',
-  'Ӟ' => 'ӟ',
-  'Ӡ' => 'ӡ',
-  'Ӣ' => 'ӣ',
-  'Ӥ' => 'ӥ',
-  'Ӧ' => 'ӧ',
-  'Ө' => 'ө',
-  'Ӫ' => 'ӫ',
-  'Ӭ' => 'ӭ',
-  'Ӯ' => 'ӯ',
-  'Ӱ' => 'ӱ',
-  'Ӳ' => 'ӳ',
-  'Ӵ' => 'ӵ',
-  'Ӷ' => 'ӷ',
-  'Ӹ' => 'ӹ',
-  'Ӻ' => 'ӻ',
-  'Ӽ' => 'ӽ',
-  'Ӿ' => 'ӿ',
-  'Ԁ' => 'ԁ',
-  'Ԃ' => 'ԃ',
-  'Ԅ' => 'ԅ',
-  'Ԇ' => 'ԇ',
-  'Ԉ' => 'ԉ',
-  'Ԋ' => 'ԋ',
-  'Ԍ' => 'ԍ',
-  'Ԏ' => 'ԏ',
-  'Ԑ' => 'ԑ',
-  'Ԓ' => 'ԓ',
-  'Ԕ' => 'ԕ',
-  'Ԗ' => 'ԗ',
-  'Ԙ' => 'ԙ',
-  'Ԛ' => 'ԛ',
-  'Ԝ' => 'ԝ',
-  'Ԟ' => 'ԟ',
-  'Ԡ' => 'ԡ',
-  'Ԣ' => 'ԣ',
-  'Ԥ' => 'ԥ',
-  'Ԧ' => 'ԧ',
-  'Ԩ' => 'ԩ',
-  'Ԫ' => 'ԫ',
-  'Ԭ' => 'ԭ',
-  'Ԯ' => 'ԯ',
-  'Ա' => 'ա',
-  'Բ' => 'բ',
-  'Գ' => 'գ',
-  'Դ' => 'դ',
-  'Ե' => 'ե',
-  'Զ' => 'զ',
-  'Է' => 'է',
-  'Ը' => 'ը',
-  'Թ' => 'թ',
-  'Ժ' => 'ժ',
-  'Ի' => 'ի',
-  'Լ' => 'լ',
-  'Խ' => 'խ',
-  'Ծ' => 'ծ',
-  'Կ' => 'կ',
-  'Հ' => 'հ',
-  'Ձ' => 'ձ',
-  'Ղ' => 'ղ',
-  'Ճ' => 'ճ',
-  'Մ' => 'մ',
-  'Յ' => 'յ',
-  'Ն' => 'ն',
-  'Շ' => 'շ',
-  'Ո' => 'ո',
-  'Չ' => 'չ',
-  'Պ' => 'պ',
-  'Ջ' => 'ջ',
-  'Ռ' => 'ռ',
-  'Ս' => 'ս',
-  'Վ' => 'վ',
-  'Տ' => 'տ',
-  'Ր' => 'ր',
-  'Ց' => 'ց',
-  'Ւ' => 'ւ',
-  'Փ' => 'փ',
-  'Ք' => 'ք',
-  'Օ' => 'օ',
-  'Ֆ' => 'ֆ',
-  'Ⴀ' => 'ⴀ',
-  'Ⴁ' => 'ⴁ',
-  'Ⴂ' => 'ⴂ',
-  'Ⴃ' => 'ⴃ',
-  'Ⴄ' => 'ⴄ',
-  'Ⴅ' => 'ⴅ',
-  'Ⴆ' => 'ⴆ',
-  'Ⴇ' => 'ⴇ',
-  'Ⴈ' => 'ⴈ',
-  'Ⴉ' => 'ⴉ',
-  'Ⴊ' => 'ⴊ',
-  'Ⴋ' => 'ⴋ',
-  'Ⴌ' => 'ⴌ',
-  'Ⴍ' => 'ⴍ',
-  'Ⴎ' => 'ⴎ',
-  'Ⴏ' => 'ⴏ',
-  'Ⴐ' => 'ⴐ',
-  'Ⴑ' => 'ⴑ',
-  'Ⴒ' => 'ⴒ',
-  'Ⴓ' => 'ⴓ',
-  'Ⴔ' => 'ⴔ',
-  'Ⴕ' => 'ⴕ',
-  'Ⴖ' => 'ⴖ',
-  'Ⴗ' => 'ⴗ',
-  'Ⴘ' => 'ⴘ',
-  'Ⴙ' => 'ⴙ',
-  'Ⴚ' => 'ⴚ',
-  'Ⴛ' => 'ⴛ',
-  'Ⴜ' => 'ⴜ',
-  'Ⴝ' => 'ⴝ',
-  'Ⴞ' => 'ⴞ',
-  'Ⴟ' => 'ⴟ',
-  'Ⴠ' => 'ⴠ',
-  'Ⴡ' => 'ⴡ',
-  'Ⴢ' => 'ⴢ',
-  'Ⴣ' => 'ⴣ',
-  'Ⴤ' => 'ⴤ',
-  'Ⴥ' => 'ⴥ',
-  'Ⴧ' => 'ⴧ',
-  'Ⴭ' => 'ⴭ',
-  'Ꭰ' => 'ꭰ',
-  'Ꭱ' => 'ꭱ',
-  'Ꭲ' => 'ꭲ',
-  'Ꭳ' => 'ꭳ',
-  'Ꭴ' => 'ꭴ',
-  'Ꭵ' => 'ꭵ',
-  'Ꭶ' => 'ꭶ',
-  'Ꭷ' => 'ꭷ',
-  'Ꭸ' => 'ꭸ',
-  'Ꭹ' => 'ꭹ',
-  'Ꭺ' => 'ꭺ',
-  'Ꭻ' => 'ꭻ',
-  'Ꭼ' => 'ꭼ',
-  'Ꭽ' => 'ꭽ',
-  'Ꭾ' => 'ꭾ',
-  'Ꭿ' => 'ꭿ',
-  'Ꮀ' => 'ꮀ',
-  'Ꮁ' => 'ꮁ',
-  'Ꮂ' => 'ꮂ',
-  'Ꮃ' => 'ꮃ',
-  'Ꮄ' => 'ꮄ',
-  'Ꮅ' => 'ꮅ',
-  'Ꮆ' => 'ꮆ',
-  'Ꮇ' => 'ꮇ',
-  'Ꮈ' => 'ꮈ',
-  'Ꮉ' => 'ꮉ',
-  'Ꮊ' => 'ꮊ',
-  'Ꮋ' => 'ꮋ',
-  'Ꮌ' => 'ꮌ',
-  'Ꮍ' => 'ꮍ',
-  'Ꮎ' => 'ꮎ',
-  'Ꮏ' => 'ꮏ',
-  'Ꮐ' => 'ꮐ',
-  'Ꮑ' => 'ꮑ',
-  'Ꮒ' => 'ꮒ',
-  'Ꮓ' => 'ꮓ',
-  'Ꮔ' => 'ꮔ',
-  'Ꮕ' => 'ꮕ',
-  'Ꮖ' => 'ꮖ',
-  'Ꮗ' => 'ꮗ',
-  'Ꮘ' => 'ꮘ',
-  'Ꮙ' => 'ꮙ',
-  'Ꮚ' => 'ꮚ',
-  'Ꮛ' => 'ꮛ',
-  'Ꮜ' => 'ꮜ',
-  'Ꮝ' => 'ꮝ',
-  'Ꮞ' => 'ꮞ',
-  'Ꮟ' => 'ꮟ',
-  'Ꮠ' => 'ꮠ',
-  'Ꮡ' => 'ꮡ',
-  'Ꮢ' => 'ꮢ',
-  'Ꮣ' => 'ꮣ',
-  'Ꮤ' => 'ꮤ',
-  'Ꮥ' => 'ꮥ',
-  'Ꮦ' => 'ꮦ',
-  'Ꮧ' => 'ꮧ',
-  'Ꮨ' => 'ꮨ',
-  'Ꮩ' => 'ꮩ',
-  'Ꮪ' => 'ꮪ',
-  'Ꮫ' => 'ꮫ',
-  'Ꮬ' => 'ꮬ',
-  'Ꮭ' => 'ꮭ',
-  'Ꮮ' => 'ꮮ',
-  'Ꮯ' => 'ꮯ',
-  'Ꮰ' => 'ꮰ',
-  'Ꮱ' => 'ꮱ',
-  'Ꮲ' => 'ꮲ',
-  'Ꮳ' => 'ꮳ',
-  'Ꮴ' => 'ꮴ',
-  'Ꮵ' => 'ꮵ',
-  'Ꮶ' => 'ꮶ',
-  'Ꮷ' => 'ꮷ',
-  'Ꮸ' => 'ꮸ',
-  'Ꮹ' => 'ꮹ',
-  'Ꮺ' => 'ꮺ',
-  'Ꮻ' => 'ꮻ',
-  'Ꮼ' => 'ꮼ',
-  'Ꮽ' => 'ꮽ',
-  'Ꮾ' => 'ꮾ',
-  'Ꮿ' => 'ꮿ',
-  'Ᏸ' => 'ᏸ',
-  'Ᏹ' => 'ᏹ',
-  'Ᏺ' => 'ᏺ',
-  'Ᏻ' => 'ᏻ',
-  'Ᏼ' => 'ᏼ',
-  'Ᏽ' => 'ᏽ',
-  'Ა' => 'ა',
-  'Ბ' => 'ბ',
-  'Გ' => 'გ',
-  'Დ' => 'დ',
-  'Ე' => 'ე',
-  'Ვ' => 'ვ',
-  'Ზ' => 'ზ',
-  'Თ' => 'თ',
-  'Ი' => 'ი',
-  'Კ' => 'კ',
-  'Ლ' => 'ლ',
-  'Მ' => 'მ',
-  'Ნ' => 'ნ',
-  'Ო' => 'ო',
-  'Პ' => 'პ',
-  'Ჟ' => 'ჟ',
-  'Რ' => 'რ',
-  'Ს' => 'ს',
-  'Ტ' => 'ტ',
-  'Უ' => 'უ',
-  'Ფ' => 'ფ',
-  'Ქ' => 'ქ',
-  'Ღ' => 'ღ',
-  'Ყ' => 'ყ',
-  'Შ' => 'შ',
-  'Ჩ' => 'ჩ',
-  'Ც' => 'ც',
-  'Ძ' => 'ძ',
-  'Წ' => 'წ',
-  'Ჭ' => 'ჭ',
-  'Ხ' => 'ხ',
-  'Ჯ' => 'ჯ',
-  'Ჰ' => 'ჰ',
-  'Ჱ' => 'ჱ',
-  'Ჲ' => 'ჲ',
-  'Ჳ' => 'ჳ',
-  'Ჴ' => 'ჴ',
-  'Ჵ' => 'ჵ',
-  'Ჶ' => 'ჶ',
-  'Ჷ' => 'ჷ',
-  'Ჸ' => 'ჸ',
-  'Ჹ' => 'ჹ',
-  'Ჺ' => 'ჺ',
-  'Ჽ' => 'ჽ',
-  'Ჾ' => 'ჾ',
-  'Ჿ' => 'ჿ',
-  'Ḁ' => 'ḁ',
-  'Ḃ' => 'ḃ',
-  'Ḅ' => 'ḅ',
-  'Ḇ' => 'ḇ',
-  'Ḉ' => 'ḉ',
-  'Ḋ' => 'ḋ',
-  'Ḍ' => 'ḍ',
-  'Ḏ' => 'ḏ',
-  'Ḑ' => 'ḑ',
-  'Ḓ' => 'ḓ',
-  'Ḕ' => 'ḕ',
-  'Ḗ' => 'ḗ',
-  'Ḙ' => 'ḙ',
-  'Ḛ' => 'ḛ',
-  'Ḝ' => 'ḝ',
-  'Ḟ' => 'ḟ',
-  'Ḡ' => 'ḡ',
-  'Ḣ' => 'ḣ',
-  'Ḥ' => 'ḥ',
-  'Ḧ' => 'ḧ',
-  'Ḩ' => 'ḩ',
-  'Ḫ' => 'ḫ',
-  'Ḭ' => 'ḭ',
-  'Ḯ' => 'ḯ',
-  'Ḱ' => 'ḱ',
-  'Ḳ' => 'ḳ',
-  'Ḵ' => 'ḵ',
-  'Ḷ' => 'ḷ',
-  'Ḹ' => 'ḹ',
-  'Ḻ' => 'ḻ',
-  'Ḽ' => 'ḽ',
-  'Ḿ' => 'ḿ',
-  'Ṁ' => 'ṁ',
-  'Ṃ' => 'ṃ',
-  'Ṅ' => 'ṅ',
-  'Ṇ' => 'ṇ',
-  'Ṉ' => 'ṉ',
-  'Ṋ' => 'ṋ',
-  'Ṍ' => 'ṍ',
-  'Ṏ' => 'ṏ',
-  'Ṑ' => 'ṑ',
-  'Ṓ' => 'ṓ',
-  'Ṕ' => 'ṕ',
-  'Ṗ' => 'ṗ',
-  'Ṙ' => 'ṙ',
-  'Ṛ' => 'ṛ',
-  'Ṝ' => 'ṝ',
-  'Ṟ' => 'ṟ',
-  'Ṡ' => 'ṡ',
-  'Ṣ' => 'ṣ',
-  'Ṥ' => 'ṥ',
-  'Ṧ' => 'ṧ',
-  'Ṩ' => 'ṩ',
-  'Ṫ' => 'ṫ',
-  'Ṭ' => 'ṭ',
-  'Ṯ' => 'ṯ',
-  'Ṱ' => 'ṱ',
-  'Ṳ' => 'ṳ',
-  'Ṵ' => 'ṵ',
-  'Ṷ' => 'ṷ',
-  'Ṹ' => 'ṹ',
-  'Ṻ' => 'ṻ',
-  'Ṽ' => 'ṽ',
-  'Ṿ' => 'ṿ',
-  'Ẁ' => 'ẁ',
-  'Ẃ' => 'ẃ',
-  'Ẅ' => 'ẅ',
-  'Ẇ' => 'ẇ',
-  'Ẉ' => 'ẉ',
-  'Ẋ' => 'ẋ',
-  'Ẍ' => 'ẍ',
-  'Ẏ' => 'ẏ',
-  'Ẑ' => 'ẑ',
-  'Ẓ' => 'ẓ',
-  'Ẕ' => 'ẕ',
-  'ẞ' => 'ß',
-  'Ạ' => 'ạ',
-  'Ả' => 'ả',
-  'Ấ' => 'ấ',
-  'Ầ' => 'ầ',
-  'Ẩ' => 'ẩ',
-  'Ẫ' => 'ẫ',
-  'Ậ' => 'ậ',
-  'Ắ' => 'ắ',
-  'Ằ' => 'ằ',
-  'Ẳ' => 'ẳ',
-  'Ẵ' => 'ẵ',
-  'Ặ' => 'ặ',
-  'Ẹ' => 'ẹ',
-  'Ẻ' => 'ẻ',
-  'Ẽ' => 'ẽ',
-  'Ế' => 'ế',
-  'Ề' => 'ề',
-  'Ể' => 'ể',
-  'Ễ' => 'ễ',
-  'Ệ' => 'ệ',
-  'Ỉ' => 'ỉ',
-  'Ị' => 'ị',
-  'Ọ' => 'ọ',
-  'Ỏ' => 'ỏ',
-  'Ố' => 'ố',
-  'Ồ' => 'ồ',
-  'Ổ' => 'ổ',
-  'Ỗ' => 'ỗ',
-  'Ộ' => 'ộ',
-  'Ớ' => 'ớ',
-  'Ờ' => 'ờ',
-  'Ở' => 'ở',
-  'Ỡ' => 'ỡ',
-  'Ợ' => 'ợ',
-  'Ụ' => 'ụ',
-  'Ủ' => 'ủ',
-  'Ứ' => 'ứ',
-  'Ừ' => 'ừ',
-  'Ử' => 'ử',
-  'Ữ' => 'ữ',
-  'Ự' => 'ự',
-  'Ỳ' => 'ỳ',
-  'Ỵ' => 'ỵ',
-  'Ỷ' => 'ỷ',
-  'Ỹ' => 'ỹ',
-  'Ỻ' => 'ỻ',
-  'Ỽ' => 'ỽ',
-  'Ỿ' => 'ỿ',
-  'Ἀ' => 'ἀ',
-  'Ἁ' => 'ἁ',
-  'Ἂ' => 'ἂ',
-  'Ἃ' => 'ἃ',
-  'Ἄ' => 'ἄ',
-  'Ἅ' => 'ἅ',
-  'Ἆ' => 'ἆ',
-  'Ἇ' => 'ἇ',
-  'Ἐ' => 'ἐ',
-  'Ἑ' => 'ἑ',
-  'Ἒ' => 'ἒ',
-  'Ἓ' => 'ἓ',
-  'Ἔ' => 'ἔ',
-  'Ἕ' => 'ἕ',
-  'Ἠ' => 'ἠ',
-  'Ἡ' => 'ἡ',
-  'Ἢ' => 'ἢ',
-  'Ἣ' => 'ἣ',
-  'Ἤ' => 'ἤ',
-  'Ἥ' => 'ἥ',
-  'Ἦ' => 'ἦ',
-  'Ἧ' => 'ἧ',
-  'Ἰ' => 'ἰ',
-  'Ἱ' => 'ἱ',
-  'Ἲ' => 'ἲ',
-  'Ἳ' => 'ἳ',
-  'Ἴ' => 'ἴ',
-  'Ἵ' => 'ἵ',
-  'Ἶ' => 'ἶ',
-  'Ἷ' => 'ἷ',
-  'Ὀ' => 'ὀ',
-  'Ὁ' => 'ὁ',
-  'Ὂ' => 'ὂ',
-  'Ὃ' => 'ὃ',
-  'Ὄ' => 'ὄ',
-  'Ὅ' => 'ὅ',
-  'Ὑ' => 'ὑ',
-  'Ὓ' => 'ὓ',
-  'Ὕ' => 'ὕ',
-  'Ὗ' => 'ὗ',
-  'Ὠ' => 'ὠ',
-  'Ὡ' => 'ὡ',
-  'Ὢ' => 'ὢ',
-  'Ὣ' => 'ὣ',
-  'Ὤ' => 'ὤ',
-  'Ὥ' => 'ὥ',
-  'Ὦ' => 'ὦ',
-  'Ὧ' => 'ὧ',
-  'ᾈ' => 'ᾀ',
-  'ᾉ' => 'ᾁ',
-  'ᾊ' => 'ᾂ',
-  'ᾋ' => 'ᾃ',
-  'ᾌ' => 'ᾄ',
-  'ᾍ' => 'ᾅ',
-  'ᾎ' => 'ᾆ',
-  'ᾏ' => 'ᾇ',
-  'ᾘ' => 'ᾐ',
-  'ᾙ' => 'ᾑ',
-  'ᾚ' => 'ᾒ',
-  'ᾛ' => 'ᾓ',
-  'ᾜ' => 'ᾔ',
-  'ᾝ' => 'ᾕ',
-  'ᾞ' => 'ᾖ',
-  'ᾟ' => 'ᾗ',
-  'ᾨ' => 'ᾠ',
-  'ᾩ' => 'ᾡ',
-  'ᾪ' => 'ᾢ',
-  'ᾫ' => 'ᾣ',
-  'ᾬ' => 'ᾤ',
-  'ᾭ' => 'ᾥ',
-  'ᾮ' => 'ᾦ',
-  'ᾯ' => 'ᾧ',
-  'Ᾰ' => 'ᾰ',
-  'Ᾱ' => 'ᾱ',
-  'Ὰ' => 'ὰ',
-  'Ά' => 'ά',
-  'ᾼ' => 'ᾳ',
-  'Ὲ' => 'ὲ',
-  'Έ' => 'έ',
-  'Ὴ' => 'ὴ',
-  'Ή' => 'ή',
-  'ῌ' => 'ῃ',
-  'Ῐ' => 'ῐ',
-  'Ῑ' => 'ῑ',
-  'Ὶ' => 'ὶ',
-  'Ί' => 'ί',
-  'Ῠ' => 'ῠ',
-  'Ῡ' => 'ῡ',
-  'Ὺ' => 'ὺ',
-  'Ύ' => 'ύ',
-  'Ῥ' => 'ῥ',
-  'Ὸ' => 'ὸ',
-  'Ό' => 'ό',
-  'Ὼ' => 'ὼ',
-  'Ώ' => 'ώ',
-  'ῼ' => 'ῳ',
-  'Ω' => 'ω',
-  'K' => 'k',
-  'Å' => 'å',
-  'Ⅎ' => 'ⅎ',
-  'Ⅰ' => 'ⅰ',
-  'Ⅱ' => 'ⅱ',
-  'Ⅲ' => 'ⅲ',
-  'Ⅳ' => 'ⅳ',
-  'Ⅴ' => 'ⅴ',
-  'Ⅵ' => 'ⅵ',
-  'Ⅶ' => 'ⅶ',
-  'Ⅷ' => 'ⅷ',
-  'Ⅸ' => 'ⅸ',
-  'Ⅹ' => 'ⅹ',
-  'Ⅺ' => 'ⅺ',
-  'Ⅻ' => 'ⅻ',
-  'Ⅼ' => 'ⅼ',
-  'Ⅽ' => 'ⅽ',
-  'Ⅾ' => 'ⅾ',
-  'Ⅿ' => 'ⅿ',
-  'Ↄ' => 'ↄ',
-  'Ⓐ' => 'ⓐ',
-  'Ⓑ' => 'ⓑ',
-  'Ⓒ' => 'ⓒ',
-  'Ⓓ' => 'ⓓ',
-  'Ⓔ' => 'ⓔ',
-  'Ⓕ' => 'ⓕ',
-  'Ⓖ' => 'ⓖ',
-  'Ⓗ' => 'ⓗ',
-  'Ⓘ' => 'ⓘ',
-  'Ⓙ' => 'ⓙ',
-  'Ⓚ' => 'ⓚ',
-  'Ⓛ' => 'ⓛ',
-  'Ⓜ' => 'ⓜ',
-  'Ⓝ' => 'ⓝ',
-  'Ⓞ' => 'ⓞ',
-  'Ⓟ' => 'ⓟ',
-  'Ⓠ' => 'ⓠ',
-  'Ⓡ' => 'ⓡ',
-  'Ⓢ' => 'ⓢ',
-  'Ⓣ' => 'ⓣ',
-  'Ⓤ' => 'ⓤ',
-  'Ⓥ' => 'ⓥ',
-  'Ⓦ' => 'ⓦ',
-  'Ⓧ' => 'ⓧ',
-  'Ⓨ' => 'ⓨ',
-  'Ⓩ' => 'ⓩ',
-  'Ⰰ' => 'ⰰ',
-  'Ⰱ' => 'ⰱ',
-  'Ⰲ' => 'ⰲ',
-  'Ⰳ' => 'ⰳ',
-  'Ⰴ' => 'ⰴ',
-  'Ⰵ' => 'ⰵ',
-  'Ⰶ' => 'ⰶ',
-  'Ⰷ' => 'ⰷ',
-  'Ⰸ' => 'ⰸ',
-  'Ⰹ' => 'ⰹ',
-  'Ⰺ' => 'ⰺ',
-  'Ⰻ' => 'ⰻ',
-  'Ⰼ' => 'ⰼ',
-  'Ⰽ' => 'ⰽ',
-  'Ⰾ' => 'ⰾ',
-  'Ⰿ' => 'ⰿ',
-  'Ⱀ' => 'ⱀ',
-  'Ⱁ' => 'ⱁ',
-  'Ⱂ' => 'ⱂ',
-  'Ⱃ' => 'ⱃ',
-  'Ⱄ' => 'ⱄ',
-  'Ⱅ' => 'ⱅ',
-  'Ⱆ' => 'ⱆ',
-  'Ⱇ' => 'ⱇ',
-  'Ⱈ' => 'ⱈ',
-  'Ⱉ' => 'ⱉ',
-  'Ⱊ' => 'ⱊ',
-  'Ⱋ' => 'ⱋ',
-  'Ⱌ' => 'ⱌ',
-  'Ⱍ' => 'ⱍ',
-  'Ⱎ' => 'ⱎ',
-  'Ⱏ' => 'ⱏ',
-  'Ⱐ' => 'ⱐ',
-  'Ⱑ' => 'ⱑ',
-  'Ⱒ' => 'ⱒ',
-  'Ⱓ' => 'ⱓ',
-  'Ⱔ' => 'ⱔ',
-  'Ⱕ' => 'ⱕ',
-  'Ⱖ' => 'ⱖ',
-  'Ⱗ' => 'ⱗ',
-  'Ⱘ' => 'ⱘ',
-  'Ⱙ' => 'ⱙ',
-  'Ⱚ' => 'ⱚ',
-  'Ⱛ' => 'ⱛ',
-  'Ⱜ' => 'ⱜ',
-  'Ⱝ' => 'ⱝ',
-  'Ⱞ' => 'ⱞ',
-  'Ⱡ' => 'ⱡ',
-  'Ɫ' => 'ɫ',
-  'Ᵽ' => 'ᵽ',
-  'Ɽ' => 'ɽ',
-  'Ⱨ' => 'ⱨ',
-  'Ⱪ' => 'ⱪ',
-  'Ⱬ' => 'ⱬ',
-  'Ɑ' => 'ɑ',
-  'Ɱ' => 'ɱ',
-  'Ɐ' => 'ɐ',
-  'Ɒ' => 'ɒ',
-  'Ⱳ' => 'ⱳ',
-  'Ⱶ' => 'ⱶ',
-  'Ȿ' => 'ȿ',
-  'Ɀ' => 'ɀ',
-  'Ⲁ' => 'ⲁ',
-  'Ⲃ' => 'ⲃ',
-  'Ⲅ' => 'ⲅ',
-  'Ⲇ' => 'ⲇ',
-  'Ⲉ' => 'ⲉ',
-  'Ⲋ' => 'ⲋ',
-  'Ⲍ' => 'ⲍ',
-  'Ⲏ' => 'ⲏ',
-  'Ⲑ' => 'ⲑ',
-  'Ⲓ' => 'ⲓ',
-  'Ⲕ' => 'ⲕ',
-  'Ⲗ' => 'ⲗ',
-  'Ⲙ' => 'ⲙ',
-  'Ⲛ' => 'ⲛ',
-  'Ⲝ' => 'ⲝ',
-  'Ⲟ' => 'ⲟ',
-  'Ⲡ' => 'ⲡ',
-  'Ⲣ' => 'ⲣ',
-  'Ⲥ' => 'ⲥ',
-  'Ⲧ' => 'ⲧ',
-  'Ⲩ' => 'ⲩ',
-  'Ⲫ' => 'ⲫ',
-  'Ⲭ' => 'ⲭ',
-  'Ⲯ' => 'ⲯ',
-  'Ⲱ' => 'ⲱ',
-  'Ⲳ' => 'ⲳ',
-  'Ⲵ' => 'ⲵ',
-  'Ⲷ' => 'ⲷ',
-  'Ⲹ' => 'ⲹ',
-  'Ⲻ' => 'ⲻ',
-  'Ⲽ' => 'ⲽ',
-  'Ⲿ' => 'ⲿ',
-  'Ⳁ' => 'ⳁ',
-  'Ⳃ' => 'ⳃ',
-  'Ⳅ' => 'ⳅ',
-  'Ⳇ' => 'ⳇ',
-  'Ⳉ' => 'ⳉ',
-  'Ⳋ' => 'ⳋ',
-  'Ⳍ' => 'ⳍ',
-  'Ⳏ' => 'ⳏ',
-  'Ⳑ' => 'ⳑ',
-  'Ⳓ' => 'ⳓ',
-  'Ⳕ' => 'ⳕ',
-  'Ⳗ' => 'ⳗ',
-  'Ⳙ' => 'ⳙ',
-  'Ⳛ' => 'ⳛ',
-  'Ⳝ' => 'ⳝ',
-  'Ⳟ' => 'ⳟ',
-  'Ⳡ' => 'ⳡ',
-  'Ⳣ' => 'ⳣ',
-  'Ⳬ' => 'ⳬ',
-  'Ⳮ' => 'ⳮ',
-  'Ⳳ' => 'ⳳ',
-  'Ꙁ' => 'ꙁ',
-  'Ꙃ' => 'ꙃ',
-  'Ꙅ' => 'ꙅ',
-  'Ꙇ' => 'ꙇ',
-  'Ꙉ' => 'ꙉ',
-  'Ꙋ' => 'ꙋ',
-  'Ꙍ' => 'ꙍ',
-  'Ꙏ' => 'ꙏ',
-  'Ꙑ' => 'ꙑ',
-  'Ꙓ' => 'ꙓ',
-  'Ꙕ' => 'ꙕ',
-  'Ꙗ' => 'ꙗ',
-  'Ꙙ' => 'ꙙ',
-  'Ꙛ' => 'ꙛ',
-  'Ꙝ' => 'ꙝ',
-  'Ꙟ' => 'ꙟ',
-  'Ꙡ' => 'ꙡ',
-  'Ꙣ' => 'ꙣ',
-  'Ꙥ' => 'ꙥ',
-  'Ꙧ' => 'ꙧ',
-  'Ꙩ' => 'ꙩ',
-  'Ꙫ' => 'ꙫ',
-  'Ꙭ' => 'ꙭ',
-  'Ꚁ' => 'ꚁ',
-  'Ꚃ' => 'ꚃ',
-  'Ꚅ' => 'ꚅ',
-  'Ꚇ' => 'ꚇ',
-  'Ꚉ' => 'ꚉ',
-  'Ꚋ' => 'ꚋ',
-  'Ꚍ' => 'ꚍ',
-  'Ꚏ' => 'ꚏ',
-  'Ꚑ' => 'ꚑ',
-  'Ꚓ' => 'ꚓ',
-  'Ꚕ' => 'ꚕ',
-  'Ꚗ' => 'ꚗ',
-  'Ꚙ' => 'ꚙ',
-  'Ꚛ' => 'ꚛ',
-  'Ꜣ' => 'ꜣ',
-  'Ꜥ' => 'ꜥ',
-  'Ꜧ' => 'ꜧ',
-  'Ꜩ' => 'ꜩ',
-  'Ꜫ' => 'ꜫ',
-  'Ꜭ' => 'ꜭ',
-  'Ꜯ' => 'ꜯ',
-  'Ꜳ' => 'ꜳ',
-  'Ꜵ' => 'ꜵ',
-  'Ꜷ' => 'ꜷ',
-  'Ꜹ' => 'ꜹ',
-  'Ꜻ' => 'ꜻ',
-  'Ꜽ' => 'ꜽ',
-  'Ꜿ' => 'ꜿ',
-  'Ꝁ' => 'ꝁ',
-  'Ꝃ' => 'ꝃ',
-  'Ꝅ' => 'ꝅ',
-  'Ꝇ' => 'ꝇ',
-  'Ꝉ' => 'ꝉ',
-  'Ꝋ' => 'ꝋ',
-  'Ꝍ' => 'ꝍ',
-  'Ꝏ' => 'ꝏ',
-  'Ꝑ' => 'ꝑ',
-  'Ꝓ' => 'ꝓ',
-  'Ꝕ' => 'ꝕ',
-  'Ꝗ' => 'ꝗ',
-  'Ꝙ' => 'ꝙ',
-  'Ꝛ' => 'ꝛ',
-  'Ꝝ' => 'ꝝ',
-  'Ꝟ' => 'ꝟ',
-  'Ꝡ' => 'ꝡ',
-  'Ꝣ' => 'ꝣ',
-  'Ꝥ' => 'ꝥ',
-  'Ꝧ' => 'ꝧ',
-  'Ꝩ' => 'ꝩ',
-  'Ꝫ' => 'ꝫ',
-  'Ꝭ' => 'ꝭ',
-  'Ꝯ' => 'ꝯ',
-  'Ꝺ' => 'ꝺ',
-  'Ꝼ' => 'ꝼ',
-  'Ᵹ' => 'ᵹ',
-  'Ꝿ' => 'ꝿ',
-  'Ꞁ' => 'ꞁ',
-  'Ꞃ' => 'ꞃ',
-  'Ꞅ' => 'ꞅ',
-  'Ꞇ' => 'ꞇ',
-  'Ꞌ' => 'ꞌ',
-  'Ɥ' => 'ɥ',
-  'Ꞑ' => 'ꞑ',
-  'Ꞓ' => 'ꞓ',
-  'Ꞗ' => 'ꞗ',
-  'Ꞙ' => 'ꞙ',
-  'Ꞛ' => 'ꞛ',
-  'Ꞝ' => 'ꞝ',
-  'Ꞟ' => 'ꞟ',
-  'Ꞡ' => 'ꞡ',
-  'Ꞣ' => 'ꞣ',
-  'Ꞥ' => 'ꞥ',
-  'Ꞧ' => 'ꞧ',
-  'Ꞩ' => 'ꞩ',
-  'Ɦ' => 'ɦ',
-  'Ɜ' => 'ɜ',
-  'Ɡ' => 'ɡ',
-  'Ɬ' => 'ɬ',
-  'Ɪ' => 'ɪ',
-  'Ʞ' => 'ʞ',
-  'Ʇ' => 'ʇ',
-  'Ʝ' => 'ʝ',
-  'Ꭓ' => 'ꭓ',
-  'Ꞵ' => 'ꞵ',
-  'Ꞷ' => 'ꞷ',
-  'Ꞹ' => 'ꞹ',
-  'Ꞻ' => 'ꞻ',
-  'Ꞽ' => 'ꞽ',
-  'Ꞿ' => 'ꞿ',
-  'Ꟃ' => 'ꟃ',
-  'Ꞔ' => 'ꞔ',
-  'Ʂ' => 'ʂ',
-  'Ᶎ' => 'ᶎ',
-  'Ꟈ' => 'ꟈ',
-  'Ꟊ' => 'ꟊ',
-  'Ꟶ' => 'ꟶ',
-  'A' => 'a',
-  'B' => 'b',
-  'C' => 'c',
-  'D' => 'd',
-  'E' => 'e',
-  'F' => 'f',
-  'G' => 'g',
-  'H' => 'h',
-  'I' => 'i',
-  'J' => 'j',
-  'K' => 'k',
-  'L' => 'l',
-  'M' => 'm',
-  'N' => 'n',
-  'O' => 'o',
-  'P' => 'p',
-  'Q' => 'q',
-  'R' => 'r',
-  'S' => 's',
-  'T' => 't',
-  'U' => 'u',
-  'V' => 'v',
-  'W' => 'w',
-  'X' => 'x',
-  'Y' => 'y',
-  'Z' => 'z',
-  '𐐀' => '𐐨',
-  '𐐁' => '𐐩',
-  '𐐂' => '𐐪',
-  '𐐃' => '𐐫',
-  '𐐄' => '𐐬',
-  '𐐅' => '𐐭',
-  '𐐆' => '𐐮',
-  '𐐇' => '𐐯',
-  '𐐈' => '𐐰',
-  '𐐉' => '𐐱',
-  '𐐊' => '𐐲',
-  '𐐋' => '𐐳',
-  '𐐌' => '𐐴',
-  '𐐍' => '𐐵',
-  '𐐎' => '𐐶',
-  '𐐏' => '𐐷',
-  '𐐐' => '𐐸',
-  '𐐑' => '𐐹',
-  '𐐒' => '𐐺',
-  '𐐓' => '𐐻',
-  '𐐔' => '𐐼',
-  '𐐕' => '𐐽',
-  '𐐖' => '𐐾',
-  '𐐗' => '𐐿',
-  '𐐘' => '𐑀',
-  '𐐙' => '𐑁',
-  '𐐚' => '𐑂',
-  '𐐛' => '𐑃',
-  '𐐜' => '𐑄',
-  '𐐝' => '𐑅',
-  '𐐞' => '𐑆',
-  '𐐟' => '𐑇',
-  '𐐠' => '𐑈',
-  '𐐡' => '𐑉',
-  '𐐢' => '𐑊',
-  '𐐣' => '𐑋',
-  '𐐤' => '𐑌',
-  '𐐥' => '𐑍',
-  '𐐦' => '𐑎',
-  '𐐧' => '𐑏',
-  '𐒰' => '𐓘',
-  '𐒱' => '𐓙',
-  '𐒲' => '𐓚',
-  '𐒳' => '𐓛',
-  '𐒴' => '𐓜',
-  '𐒵' => '𐓝',
-  '𐒶' => '𐓞',
-  '𐒷' => '𐓟',
-  '𐒸' => '𐓠',
-  '𐒹' => '𐓡',
-  '𐒺' => '𐓢',
-  '𐒻' => '𐓣',
-  '𐒼' => '𐓤',
-  '𐒽' => '𐓥',
-  '𐒾' => '𐓦',
-  '𐒿' => '𐓧',
-  '𐓀' => '𐓨',
-  '𐓁' => '𐓩',
-  '𐓂' => '𐓪',
-  '𐓃' => '𐓫',
-  '𐓄' => '𐓬',
-  '𐓅' => '𐓭',
-  '𐓆' => '𐓮',
-  '𐓇' => '𐓯',
-  '𐓈' => '𐓰',
-  '𐓉' => '𐓱',
-  '𐓊' => '𐓲',
-  '𐓋' => '𐓳',
-  '𐓌' => '𐓴',
-  '𐓍' => '𐓵',
-  '𐓎' => '𐓶',
-  '𐓏' => '𐓷',
-  '𐓐' => '𐓸',
-  '𐓑' => '𐓹',
-  '𐓒' => '𐓺',
-  '𐓓' => '𐓻',
-  '𐲀' => '𐳀',
-  '𐲁' => '𐳁',
-  '𐲂' => '𐳂',
-  '𐲃' => '𐳃',
-  '𐲄' => '𐳄',
-  '𐲅' => '𐳅',
-  '𐲆' => '𐳆',
-  '𐲇' => '𐳇',
-  '𐲈' => '𐳈',
-  '𐲉' => '𐳉',
-  '𐲊' => '𐳊',
-  '𐲋' => '𐳋',
-  '𐲌' => '𐳌',
-  '𐲍' => '𐳍',
-  '𐲎' => '𐳎',
-  '𐲏' => '𐳏',
-  '𐲐' => '𐳐',
-  '𐲑' => '𐳑',
-  '𐲒' => '𐳒',
-  '𐲓' => '𐳓',
-  '𐲔' => '𐳔',
-  '𐲕' => '𐳕',
-  '𐲖' => '𐳖',
-  '𐲗' => '𐳗',
-  '𐲘' => '𐳘',
-  '𐲙' => '𐳙',
-  '𐲚' => '𐳚',
-  '𐲛' => '𐳛',
-  '𐲜' => '𐳜',
-  '𐲝' => '𐳝',
-  '𐲞' => '𐳞',
-  '𐲟' => '𐳟',
-  '𐲠' => '𐳠',
-  '𐲡' => '𐳡',
-  '𐲢' => '𐳢',
-  '𐲣' => '𐳣',
-  '𐲤' => '𐳤',
-  '𐲥' => '𐳥',
-  '𐲦' => '𐳦',
-  '𐲧' => '𐳧',
-  '𐲨' => '𐳨',
-  '𐲩' => '𐳩',
-  '𐲪' => '𐳪',
-  '𐲫' => '𐳫',
-  '𐲬' => '𐳬',
-  '𐲭' => '𐳭',
-  '𐲮' => '𐳮',
-  '𐲯' => '𐳯',
-  '𐲰' => '𐳰',
-  '𐲱' => '𐳱',
-  '𐲲' => '𐳲',
-  '𑢠' => '𑣀',
-  '𑢡' => '𑣁',
-  '𑢢' => '𑣂',
-  '𑢣' => '𑣃',
-  '𑢤' => '𑣄',
-  '𑢥' => '𑣅',
-  '𑢦' => '𑣆',
-  '𑢧' => '𑣇',
-  '𑢨' => '𑣈',
-  '𑢩' => '𑣉',
-  '𑢪' => '𑣊',
-  '𑢫' => '𑣋',
-  '𑢬' => '𑣌',
-  '𑢭' => '𑣍',
-  '𑢮' => '𑣎',
-  '𑢯' => '𑣏',
-  '𑢰' => '𑣐',
-  '𑢱' => '𑣑',
-  '𑢲' => '𑣒',
-  '𑢳' => '𑣓',
-  '𑢴' => '𑣔',
-  '𑢵' => '𑣕',
-  '𑢶' => '𑣖',
-  '𑢷' => '𑣗',
-  '𑢸' => '𑣘',
-  '𑢹' => '𑣙',
-  '𑢺' => '𑣚',
-  '𑢻' => '𑣛',
-  '𑢼' => '𑣜',
-  '𑢽' => '𑣝',
-  '𑢾' => '𑣞',
-  '𑢿' => '𑣟',
-  '𖹀' => '𖹠',
-  '𖹁' => '𖹡',
-  '𖹂' => '𖹢',
-  '𖹃' => '𖹣',
-  '𖹄' => '𖹤',
-  '𖹅' => '𖹥',
-  '𖹆' => '𖹦',
-  '𖹇' => '𖹧',
-  '𖹈' => '𖹨',
-  '𖹉' => '𖹩',
-  '𖹊' => '𖹪',
-  '𖹋' => '𖹫',
-  '𖹌' => '𖹬',
-  '𖹍' => '𖹭',
-  '𖹎' => '𖹮',
-  '𖹏' => '𖹯',
-  '𖹐' => '𖹰',
-  '𖹑' => '𖹱',
-  '𖹒' => '𖹲',
-  '𖹓' => '𖹳',
-  '𖹔' => '𖹴',
-  '𖹕' => '𖹵',
-  '𖹖' => '𖹶',
-  '𖹗' => '𖹷',
-  '𖹘' => '𖹸',
-  '𖹙' => '𖹹',
-  '𖹚' => '𖹺',
-  '𖹛' => '𖹻',
-  '𖹜' => '𖹼',
-  '𖹝' => '𖹽',
-  '𖹞' => '𖹾',
-  '𖹟' => '𖹿',
-  '𞤀' => '𞤢',
-  '𞤁' => '𞤣',
-  '𞤂' => '𞤤',
-  '𞤃' => '𞤥',
-  '𞤄' => '𞤦',
-  '𞤅' => '𞤧',
-  '𞤆' => '𞤨',
-  '𞤇' => '𞤩',
-  '𞤈' => '𞤪',
-  '𞤉' => '𞤫',
-  '𞤊' => '𞤬',
-  '𞤋' => '𞤭',
-  '𞤌' => '𞤮',
-  '𞤍' => '𞤯',
-  '𞤎' => '𞤰',
-  '𞤏' => '𞤱',
-  '𞤐' => '𞤲',
-  '𞤑' => '𞤳',
-  '𞤒' => '𞤴',
-  '𞤓' => '𞤵',
-  '𞤔' => '𞤶',
-  '𞤕' => '𞤷',
-  '𞤖' => '𞤸',
-  '𞤗' => '𞤹',
-  '𞤘' => '𞤺',
-  '𞤙' => '𞤻',
-  '𞤚' => '𞤼',
-  '𞤛' => '𞤽',
-  '𞤜' => '𞤾',
-  '𞤝' => '𞤿',
-  '𞤞' => '𞥀',
-  '𞤟' => '𞥁',
-  '𞤠' => '𞥂',
-  '𞤡' => '𞥃',
-);
diff --git a/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php b/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php
deleted file mode 100644
index 2a8f6e73b..000000000
--- a/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php
+++ /dev/null
@@ -1,5 +0,0 @@
- 'A',
-  'b' => 'B',
-  'c' => 'C',
-  'd' => 'D',
-  'e' => 'E',
-  'f' => 'F',
-  'g' => 'G',
-  'h' => 'H',
-  'i' => 'I',
-  'j' => 'J',
-  'k' => 'K',
-  'l' => 'L',
-  'm' => 'M',
-  'n' => 'N',
-  'o' => 'O',
-  'p' => 'P',
-  'q' => 'Q',
-  'r' => 'R',
-  's' => 'S',
-  't' => 'T',
-  'u' => 'U',
-  'v' => 'V',
-  'w' => 'W',
-  'x' => 'X',
-  'y' => 'Y',
-  'z' => 'Z',
-  'µ' => 'Μ',
-  'à' => 'À',
-  'á' => 'Á',
-  'â' => 'Â',
-  'ã' => 'Ã',
-  'ä' => 'Ä',
-  'å' => 'Å',
-  'æ' => 'Æ',
-  'ç' => 'Ç',
-  'è' => 'È',
-  'é' => 'É',
-  'ê' => 'Ê',
-  'ë' => 'Ë',
-  'ì' => 'Ì',
-  'í' => 'Í',
-  'î' => 'Î',
-  'ï' => 'Ï',
-  'ð' => 'Ð',
-  'ñ' => 'Ñ',
-  'ò' => 'Ò',
-  'ó' => 'Ó',
-  'ô' => 'Ô',
-  'õ' => 'Õ',
-  'ö' => 'Ö',
-  'ø' => 'Ø',
-  'ù' => 'Ù',
-  'ú' => 'Ú',
-  'û' => 'Û',
-  'ü' => 'Ü',
-  'ý' => 'Ý',
-  'þ' => 'Þ',
-  'ÿ' => 'Ÿ',
-  'ā' => 'Ā',
-  'ă' => 'Ă',
-  'ą' => 'Ą',
-  'ć' => 'Ć',
-  'ĉ' => 'Ĉ',
-  'ċ' => 'Ċ',
-  'č' => 'Č',
-  'ď' => 'Ď',
-  'đ' => 'Đ',
-  'ē' => 'Ē',
-  'ĕ' => 'Ĕ',
-  'ė' => 'Ė',
-  'ę' => 'Ę',
-  'ě' => 'Ě',
-  'ĝ' => 'Ĝ',
-  'ğ' => 'Ğ',
-  'ġ' => 'Ġ',
-  'ģ' => 'Ģ',
-  'ĥ' => 'Ĥ',
-  'ħ' => 'Ħ',
-  'ĩ' => 'Ĩ',
-  'ī' => 'Ī',
-  'ĭ' => 'Ĭ',
-  'į' => 'Į',
-  'ı' => 'I',
-  'ij' => 'IJ',
-  'ĵ' => 'Ĵ',
-  'ķ' => 'Ķ',
-  'ĺ' => 'Ĺ',
-  'ļ' => 'Ļ',
-  'ľ' => 'Ľ',
-  'ŀ' => 'Ŀ',
-  'ł' => 'Ł',
-  'ń' => 'Ń',
-  'ņ' => 'Ņ',
-  'ň' => 'Ň',
-  'ŋ' => 'Ŋ',
-  'ō' => 'Ō',
-  'ŏ' => 'Ŏ',
-  'ő' => 'Ő',
-  'œ' => 'Œ',
-  'ŕ' => 'Ŕ',
-  'ŗ' => 'Ŗ',
-  'ř' => 'Ř',
-  'ś' => 'Ś',
-  'ŝ' => 'Ŝ',
-  'ş' => 'Ş',
-  'š' => 'Š',
-  'ţ' => 'Ţ',
-  'ť' => 'Ť',
-  'ŧ' => 'Ŧ',
-  'ũ' => 'Ũ',
-  'ū' => 'Ū',
-  'ŭ' => 'Ŭ',
-  'ů' => 'Ů',
-  'ű' => 'Ű',
-  'ų' => 'Ų',
-  'ŵ' => 'Ŵ',
-  'ŷ' => 'Ŷ',
-  'ź' => 'Ź',
-  'ż' => 'Ż',
-  'ž' => 'Ž',
-  'ſ' => 'S',
-  'ƀ' => 'Ƀ',
-  'ƃ' => 'Ƃ',
-  'ƅ' => 'Ƅ',
-  'ƈ' => 'Ƈ',
-  'ƌ' => 'Ƌ',
-  'ƒ' => 'Ƒ',
-  'ƕ' => 'Ƕ',
-  'ƙ' => 'Ƙ',
-  'ƚ' => 'Ƚ',
-  'ƞ' => 'Ƞ',
-  'ơ' => 'Ơ',
-  'ƣ' => 'Ƣ',
-  'ƥ' => 'Ƥ',
-  'ƨ' => 'Ƨ',
-  'ƭ' => 'Ƭ',
-  'ư' => 'Ư',
-  'ƴ' => 'Ƴ',
-  'ƶ' => 'Ƶ',
-  'ƹ' => 'Ƹ',
-  'ƽ' => 'Ƽ',
-  'ƿ' => 'Ƿ',
-  'Dž' => 'DŽ',
-  'dž' => 'DŽ',
-  'Lj' => 'LJ',
-  'lj' => 'LJ',
-  'Nj' => 'NJ',
-  'nj' => 'NJ',
-  'ǎ' => 'Ǎ',
-  'ǐ' => 'Ǐ',
-  'ǒ' => 'Ǒ',
-  'ǔ' => 'Ǔ',
-  'ǖ' => 'Ǖ',
-  'ǘ' => 'Ǘ',
-  'ǚ' => 'Ǚ',
-  'ǜ' => 'Ǜ',
-  'ǝ' => 'Ǝ',
-  'ǟ' => 'Ǟ',
-  'ǡ' => 'Ǡ',
-  'ǣ' => 'Ǣ',
-  'ǥ' => 'Ǥ',
-  'ǧ' => 'Ǧ',
-  'ǩ' => 'Ǩ',
-  'ǫ' => 'Ǫ',
-  'ǭ' => 'Ǭ',
-  'ǯ' => 'Ǯ',
-  'Dz' => 'DZ',
-  'dz' => 'DZ',
-  'ǵ' => 'Ǵ',
-  'ǹ' => 'Ǹ',
-  'ǻ' => 'Ǻ',
-  'ǽ' => 'Ǽ',
-  'ǿ' => 'Ǿ',
-  'ȁ' => 'Ȁ',
-  'ȃ' => 'Ȃ',
-  'ȅ' => 'Ȅ',
-  'ȇ' => 'Ȇ',
-  'ȉ' => 'Ȉ',
-  'ȋ' => 'Ȋ',
-  'ȍ' => 'Ȍ',
-  'ȏ' => 'Ȏ',
-  'ȑ' => 'Ȑ',
-  'ȓ' => 'Ȓ',
-  'ȕ' => 'Ȕ',
-  'ȗ' => 'Ȗ',
-  'ș' => 'Ș',
-  'ț' => 'Ț',
-  'ȝ' => 'Ȝ',
-  'ȟ' => 'Ȟ',
-  'ȣ' => 'Ȣ',
-  'ȥ' => 'Ȥ',
-  'ȧ' => 'Ȧ',
-  'ȩ' => 'Ȩ',
-  'ȫ' => 'Ȫ',
-  'ȭ' => 'Ȭ',
-  'ȯ' => 'Ȯ',
-  'ȱ' => 'Ȱ',
-  'ȳ' => 'Ȳ',
-  'ȼ' => 'Ȼ',
-  'ȿ' => 'Ȿ',
-  'ɀ' => 'Ɀ',
-  'ɂ' => 'Ɂ',
-  'ɇ' => 'Ɇ',
-  'ɉ' => 'Ɉ',
-  'ɋ' => 'Ɋ',
-  'ɍ' => 'Ɍ',
-  'ɏ' => 'Ɏ',
-  'ɐ' => 'Ɐ',
-  'ɑ' => 'Ɑ',
-  'ɒ' => 'Ɒ',
-  'ɓ' => 'Ɓ',
-  'ɔ' => 'Ɔ',
-  'ɖ' => 'Ɖ',
-  'ɗ' => 'Ɗ',
-  'ə' => 'Ə',
-  'ɛ' => 'Ɛ',
-  'ɜ' => 'Ɜ',
-  'ɠ' => 'Ɠ',
-  'ɡ' => 'Ɡ',
-  'ɣ' => 'Ɣ',
-  'ɥ' => 'Ɥ',
-  'ɦ' => 'Ɦ',
-  'ɨ' => 'Ɨ',
-  'ɩ' => 'Ɩ',
-  'ɪ' => 'Ɪ',
-  'ɫ' => 'Ɫ',
-  'ɬ' => 'Ɬ',
-  'ɯ' => 'Ɯ',
-  'ɱ' => 'Ɱ',
-  'ɲ' => 'Ɲ',
-  'ɵ' => 'Ɵ',
-  'ɽ' => 'Ɽ',
-  'ʀ' => 'Ʀ',
-  'ʂ' => 'Ʂ',
-  'ʃ' => 'Ʃ',
-  'ʇ' => 'Ʇ',
-  'ʈ' => 'Ʈ',
-  'ʉ' => 'Ʉ',
-  'ʊ' => 'Ʊ',
-  'ʋ' => 'Ʋ',
-  'ʌ' => 'Ʌ',
-  'ʒ' => 'Ʒ',
-  'ʝ' => 'Ʝ',
-  'ʞ' => 'Ʞ',
-  'ͅ' => 'Ι',
-  'ͱ' => 'Ͱ',
-  'ͳ' => 'Ͳ',
-  'ͷ' => 'Ͷ',
-  'ͻ' => 'Ͻ',
-  'ͼ' => 'Ͼ',
-  'ͽ' => 'Ͽ',
-  'ά' => 'Ά',
-  'έ' => 'Έ',
-  'ή' => 'Ή',
-  'ί' => 'Ί',
-  'α' => 'Α',
-  'β' => 'Β',
-  'γ' => 'Γ',
-  'δ' => 'Δ',
-  'ε' => 'Ε',
-  'ζ' => 'Ζ',
-  'η' => 'Η',
-  'θ' => 'Θ',
-  'ι' => 'Ι',
-  'κ' => 'Κ',
-  'λ' => 'Λ',
-  'μ' => 'Μ',
-  'ν' => 'Ν',
-  'ξ' => 'Ξ',
-  'ο' => 'Ο',
-  'π' => 'Π',
-  'ρ' => 'Ρ',
-  'ς' => 'Σ',
-  'σ' => 'Σ',
-  'τ' => 'Τ',
-  'υ' => 'Υ',
-  'φ' => 'Φ',
-  'χ' => 'Χ',
-  'ψ' => 'Ψ',
-  'ω' => 'Ω',
-  'ϊ' => 'Ϊ',
-  'ϋ' => 'Ϋ',
-  'ό' => 'Ό',
-  'ύ' => 'Ύ',
-  'ώ' => 'Ώ',
-  'ϐ' => 'Β',
-  'ϑ' => 'Θ',
-  'ϕ' => 'Φ',
-  'ϖ' => 'Π',
-  'ϗ' => 'Ϗ',
-  'ϙ' => 'Ϙ',
-  'ϛ' => 'Ϛ',
-  'ϝ' => 'Ϝ',
-  'ϟ' => 'Ϟ',
-  'ϡ' => 'Ϡ',
-  'ϣ' => 'Ϣ',
-  'ϥ' => 'Ϥ',
-  'ϧ' => 'Ϧ',
-  'ϩ' => 'Ϩ',
-  'ϫ' => 'Ϫ',
-  'ϭ' => 'Ϭ',
-  'ϯ' => 'Ϯ',
-  'ϰ' => 'Κ',
-  'ϱ' => 'Ρ',
-  'ϲ' => 'Ϲ',
-  'ϳ' => 'Ϳ',
-  'ϵ' => 'Ε',
-  'ϸ' => 'Ϸ',
-  'ϻ' => 'Ϻ',
-  'а' => 'А',
-  'б' => 'Б',
-  'в' => 'В',
-  'г' => 'Г',
-  'д' => 'Д',
-  'е' => 'Е',
-  'ж' => 'Ж',
-  'з' => 'З',
-  'и' => 'И',
-  'й' => 'Й',
-  'к' => 'К',
-  'л' => 'Л',
-  'м' => 'М',
-  'н' => 'Н',
-  'о' => 'О',
-  'п' => 'П',
-  'р' => 'Р',
-  'с' => 'С',
-  'т' => 'Т',
-  'у' => 'У',
-  'ф' => 'Ф',
-  'х' => 'Х',
-  'ц' => 'Ц',
-  'ч' => 'Ч',
-  'ш' => 'Ш',
-  'щ' => 'Щ',
-  'ъ' => 'Ъ',
-  'ы' => 'Ы',
-  'ь' => 'Ь',
-  'э' => 'Э',
-  'ю' => 'Ю',
-  'я' => 'Я',
-  'ѐ' => 'Ѐ',
-  'ё' => 'Ё',
-  'ђ' => 'Ђ',
-  'ѓ' => 'Ѓ',
-  'є' => 'Є',
-  'ѕ' => 'Ѕ',
-  'і' => 'І',
-  'ї' => 'Ї',
-  'ј' => 'Ј',
-  'љ' => 'Љ',
-  'њ' => 'Њ',
-  'ћ' => 'Ћ',
-  'ќ' => 'Ќ',
-  'ѝ' => 'Ѝ',
-  'ў' => 'Ў',
-  'џ' => 'Џ',
-  'ѡ' => 'Ѡ',
-  'ѣ' => 'Ѣ',
-  'ѥ' => 'Ѥ',
-  'ѧ' => 'Ѧ',
-  'ѩ' => 'Ѩ',
-  'ѫ' => 'Ѫ',
-  'ѭ' => 'Ѭ',
-  'ѯ' => 'Ѯ',
-  'ѱ' => 'Ѱ',
-  'ѳ' => 'Ѳ',
-  'ѵ' => 'Ѵ',
-  'ѷ' => 'Ѷ',
-  'ѹ' => 'Ѹ',
-  'ѻ' => 'Ѻ',
-  'ѽ' => 'Ѽ',
-  'ѿ' => 'Ѿ',
-  'ҁ' => 'Ҁ',
-  'ҋ' => 'Ҋ',
-  'ҍ' => 'Ҍ',
-  'ҏ' => 'Ҏ',
-  'ґ' => 'Ґ',
-  'ғ' => 'Ғ',
-  'ҕ' => 'Ҕ',
-  'җ' => 'Җ',
-  'ҙ' => 'Ҙ',
-  'қ' => 'Қ',
-  'ҝ' => 'Ҝ',
-  'ҟ' => 'Ҟ',
-  'ҡ' => 'Ҡ',
-  'ң' => 'Ң',
-  'ҥ' => 'Ҥ',
-  'ҧ' => 'Ҧ',
-  'ҩ' => 'Ҩ',
-  'ҫ' => 'Ҫ',
-  'ҭ' => 'Ҭ',
-  'ү' => 'Ү',
-  'ұ' => 'Ұ',
-  'ҳ' => 'Ҳ',
-  'ҵ' => 'Ҵ',
-  'ҷ' => 'Ҷ',
-  'ҹ' => 'Ҹ',
-  'һ' => 'Һ',
-  'ҽ' => 'Ҽ',
-  'ҿ' => 'Ҿ',
-  'ӂ' => 'Ӂ',
-  'ӄ' => 'Ӄ',
-  'ӆ' => 'Ӆ',
-  'ӈ' => 'Ӈ',
-  'ӊ' => 'Ӊ',
-  'ӌ' => 'Ӌ',
-  'ӎ' => 'Ӎ',
-  'ӏ' => 'Ӏ',
-  'ӑ' => 'Ӑ',
-  'ӓ' => 'Ӓ',
-  'ӕ' => 'Ӕ',
-  'ӗ' => 'Ӗ',
-  'ә' => 'Ә',
-  'ӛ' => 'Ӛ',
-  'ӝ' => 'Ӝ',
-  'ӟ' => 'Ӟ',
-  'ӡ' => 'Ӡ',
-  'ӣ' => 'Ӣ',
-  'ӥ' => 'Ӥ',
-  'ӧ' => 'Ӧ',
-  'ө' => 'Ө',
-  'ӫ' => 'Ӫ',
-  'ӭ' => 'Ӭ',
-  'ӯ' => 'Ӯ',
-  'ӱ' => 'Ӱ',
-  'ӳ' => 'Ӳ',
-  'ӵ' => 'Ӵ',
-  'ӷ' => 'Ӷ',
-  'ӹ' => 'Ӹ',
-  'ӻ' => 'Ӻ',
-  'ӽ' => 'Ӽ',
-  'ӿ' => 'Ӿ',
-  'ԁ' => 'Ԁ',
-  'ԃ' => 'Ԃ',
-  'ԅ' => 'Ԅ',
-  'ԇ' => 'Ԇ',
-  'ԉ' => 'Ԉ',
-  'ԋ' => 'Ԋ',
-  'ԍ' => 'Ԍ',
-  'ԏ' => 'Ԏ',
-  'ԑ' => 'Ԑ',
-  'ԓ' => 'Ԓ',
-  'ԕ' => 'Ԕ',
-  'ԗ' => 'Ԗ',
-  'ԙ' => 'Ԙ',
-  'ԛ' => 'Ԛ',
-  'ԝ' => 'Ԝ',
-  'ԟ' => 'Ԟ',
-  'ԡ' => 'Ԡ',
-  'ԣ' => 'Ԣ',
-  'ԥ' => 'Ԥ',
-  'ԧ' => 'Ԧ',
-  'ԩ' => 'Ԩ',
-  'ԫ' => 'Ԫ',
-  'ԭ' => 'Ԭ',
-  'ԯ' => 'Ԯ',
-  'ա' => 'Ա',
-  'բ' => 'Բ',
-  'գ' => 'Գ',
-  'դ' => 'Դ',
-  'ե' => 'Ե',
-  'զ' => 'Զ',
-  'է' => 'Է',
-  'ը' => 'Ը',
-  'թ' => 'Թ',
-  'ժ' => 'Ժ',
-  'ի' => 'Ի',
-  'լ' => 'Լ',
-  'խ' => 'Խ',
-  'ծ' => 'Ծ',
-  'կ' => 'Կ',
-  'հ' => 'Հ',
-  'ձ' => 'Ձ',
-  'ղ' => 'Ղ',
-  'ճ' => 'Ճ',
-  'մ' => 'Մ',
-  'յ' => 'Յ',
-  'ն' => 'Ն',
-  'շ' => 'Շ',
-  'ո' => 'Ո',
-  'չ' => 'Չ',
-  'պ' => 'Պ',
-  'ջ' => 'Ջ',
-  'ռ' => 'Ռ',
-  'ս' => 'Ս',
-  'վ' => 'Վ',
-  'տ' => 'Տ',
-  'ր' => 'Ր',
-  'ց' => 'Ց',
-  'ւ' => 'Ւ',
-  'փ' => 'Փ',
-  'ք' => 'Ք',
-  'օ' => 'Օ',
-  'ֆ' => 'Ֆ',
-  'ა' => 'Ა',
-  'ბ' => 'Ბ',
-  'გ' => 'Გ',
-  'დ' => 'Დ',
-  'ე' => 'Ე',
-  'ვ' => 'Ვ',
-  'ზ' => 'Ზ',
-  'თ' => 'Თ',
-  'ი' => 'Ი',
-  'კ' => 'Კ',
-  'ლ' => 'Ლ',
-  'მ' => 'Მ',
-  'ნ' => 'Ნ',
-  'ო' => 'Ო',
-  'პ' => 'Პ',
-  'ჟ' => 'Ჟ',
-  'რ' => 'Რ',
-  'ს' => 'Ს',
-  'ტ' => 'Ტ',
-  'უ' => 'Უ',
-  'ფ' => 'Ფ',
-  'ქ' => 'Ქ',
-  'ღ' => 'Ღ',
-  'ყ' => 'Ყ',
-  'შ' => 'Შ',
-  'ჩ' => 'Ჩ',
-  'ც' => 'Ც',
-  'ძ' => 'Ძ',
-  'წ' => 'Წ',
-  'ჭ' => 'Ჭ',
-  'ხ' => 'Ხ',
-  'ჯ' => 'Ჯ',
-  'ჰ' => 'Ჰ',
-  'ჱ' => 'Ჱ',
-  'ჲ' => 'Ჲ',
-  'ჳ' => 'Ჳ',
-  'ჴ' => 'Ჴ',
-  'ჵ' => 'Ჵ',
-  'ჶ' => 'Ჶ',
-  'ჷ' => 'Ჷ',
-  'ჸ' => 'Ჸ',
-  'ჹ' => 'Ჹ',
-  'ჺ' => 'Ჺ',
-  'ჽ' => 'Ჽ',
-  'ჾ' => 'Ჾ',
-  'ჿ' => 'Ჿ',
-  'ᏸ' => 'Ᏸ',
-  'ᏹ' => 'Ᏹ',
-  'ᏺ' => 'Ᏺ',
-  'ᏻ' => 'Ᏻ',
-  'ᏼ' => 'Ᏼ',
-  'ᏽ' => 'Ᏽ',
-  'ᲀ' => 'В',
-  'ᲁ' => 'Д',
-  'ᲂ' => 'О',
-  'ᲃ' => 'С',
-  'ᲄ' => 'Т',
-  'ᲅ' => 'Т',
-  'ᲆ' => 'Ъ',
-  'ᲇ' => 'Ѣ',
-  'ᲈ' => 'Ꙋ',
-  'ᵹ' => 'Ᵹ',
-  'ᵽ' => 'Ᵽ',
-  'ᶎ' => 'Ᶎ',
-  'ḁ' => 'Ḁ',
-  'ḃ' => 'Ḃ',
-  'ḅ' => 'Ḅ',
-  'ḇ' => 'Ḇ',
-  'ḉ' => 'Ḉ',
-  'ḋ' => 'Ḋ',
-  'ḍ' => 'Ḍ',
-  'ḏ' => 'Ḏ',
-  'ḑ' => 'Ḑ',
-  'ḓ' => 'Ḓ',
-  'ḕ' => 'Ḕ',
-  'ḗ' => 'Ḗ',
-  'ḙ' => 'Ḙ',
-  'ḛ' => 'Ḛ',
-  'ḝ' => 'Ḝ',
-  'ḟ' => 'Ḟ',
-  'ḡ' => 'Ḡ',
-  'ḣ' => 'Ḣ',
-  'ḥ' => 'Ḥ',
-  'ḧ' => 'Ḧ',
-  'ḩ' => 'Ḩ',
-  'ḫ' => 'Ḫ',
-  'ḭ' => 'Ḭ',
-  'ḯ' => 'Ḯ',
-  'ḱ' => 'Ḱ',
-  'ḳ' => 'Ḳ',
-  'ḵ' => 'Ḵ',
-  'ḷ' => 'Ḷ',
-  'ḹ' => 'Ḹ',
-  'ḻ' => 'Ḻ',
-  'ḽ' => 'Ḽ',
-  'ḿ' => 'Ḿ',
-  'ṁ' => 'Ṁ',
-  'ṃ' => 'Ṃ',
-  'ṅ' => 'Ṅ',
-  'ṇ' => 'Ṇ',
-  'ṉ' => 'Ṉ',
-  'ṋ' => 'Ṋ',
-  'ṍ' => 'Ṍ',
-  'ṏ' => 'Ṏ',
-  'ṑ' => 'Ṑ',
-  'ṓ' => 'Ṓ',
-  'ṕ' => 'Ṕ',
-  'ṗ' => 'Ṗ',
-  'ṙ' => 'Ṙ',
-  'ṛ' => 'Ṛ',
-  'ṝ' => 'Ṝ',
-  'ṟ' => 'Ṟ',
-  'ṡ' => 'Ṡ',
-  'ṣ' => 'Ṣ',
-  'ṥ' => 'Ṥ',
-  'ṧ' => 'Ṧ',
-  'ṩ' => 'Ṩ',
-  'ṫ' => 'Ṫ',
-  'ṭ' => 'Ṭ',
-  'ṯ' => 'Ṯ',
-  'ṱ' => 'Ṱ',
-  'ṳ' => 'Ṳ',
-  'ṵ' => 'Ṵ',
-  'ṷ' => 'Ṷ',
-  'ṹ' => 'Ṹ',
-  'ṻ' => 'Ṻ',
-  'ṽ' => 'Ṽ',
-  'ṿ' => 'Ṿ',
-  'ẁ' => 'Ẁ',
-  'ẃ' => 'Ẃ',
-  'ẅ' => 'Ẅ',
-  'ẇ' => 'Ẇ',
-  'ẉ' => 'Ẉ',
-  'ẋ' => 'Ẋ',
-  'ẍ' => 'Ẍ',
-  'ẏ' => 'Ẏ',
-  'ẑ' => 'Ẑ',
-  'ẓ' => 'Ẓ',
-  'ẕ' => 'Ẕ',
-  'ẛ' => 'Ṡ',
-  'ạ' => 'Ạ',
-  'ả' => 'Ả',
-  'ấ' => 'Ấ',
-  'ầ' => 'Ầ',
-  'ẩ' => 'Ẩ',
-  'ẫ' => 'Ẫ',
-  'ậ' => 'Ậ',
-  'ắ' => 'Ắ',
-  'ằ' => 'Ằ',
-  'ẳ' => 'Ẳ',
-  'ẵ' => 'Ẵ',
-  'ặ' => 'Ặ',
-  'ẹ' => 'Ẹ',
-  'ẻ' => 'Ẻ',
-  'ẽ' => 'Ẽ',
-  'ế' => 'Ế',
-  'ề' => 'Ề',
-  'ể' => 'Ể',
-  'ễ' => 'Ễ',
-  'ệ' => 'Ệ',
-  'ỉ' => 'Ỉ',
-  'ị' => 'Ị',
-  'ọ' => 'Ọ',
-  'ỏ' => 'Ỏ',
-  'ố' => 'Ố',
-  'ồ' => 'Ồ',
-  'ổ' => 'Ổ',
-  'ỗ' => 'Ỗ',
-  'ộ' => 'Ộ',
-  'ớ' => 'Ớ',
-  'ờ' => 'Ờ',
-  'ở' => 'Ở',
-  'ỡ' => 'Ỡ',
-  'ợ' => 'Ợ',
-  'ụ' => 'Ụ',
-  'ủ' => 'Ủ',
-  'ứ' => 'Ứ',
-  'ừ' => 'Ừ',
-  'ử' => 'Ử',
-  'ữ' => 'Ữ',
-  'ự' => 'Ự',
-  'ỳ' => 'Ỳ',
-  'ỵ' => 'Ỵ',
-  'ỷ' => 'Ỷ',
-  'ỹ' => 'Ỹ',
-  'ỻ' => 'Ỻ',
-  'ỽ' => 'Ỽ',
-  'ỿ' => 'Ỿ',
-  'ἀ' => 'Ἀ',
-  'ἁ' => 'Ἁ',
-  'ἂ' => 'Ἂ',
-  'ἃ' => 'Ἃ',
-  'ἄ' => 'Ἄ',
-  'ἅ' => 'Ἅ',
-  'ἆ' => 'Ἆ',
-  'ἇ' => 'Ἇ',
-  'ἐ' => 'Ἐ',
-  'ἑ' => 'Ἑ',
-  'ἒ' => 'Ἒ',
-  'ἓ' => 'Ἓ',
-  'ἔ' => 'Ἔ',
-  'ἕ' => 'Ἕ',
-  'ἠ' => 'Ἠ',
-  'ἡ' => 'Ἡ',
-  'ἢ' => 'Ἢ',
-  'ἣ' => 'Ἣ',
-  'ἤ' => 'Ἤ',
-  'ἥ' => 'Ἥ',
-  'ἦ' => 'Ἦ',
-  'ἧ' => 'Ἧ',
-  'ἰ' => 'Ἰ',
-  'ἱ' => 'Ἱ',
-  'ἲ' => 'Ἲ',
-  'ἳ' => 'Ἳ',
-  'ἴ' => 'Ἴ',
-  'ἵ' => 'Ἵ',
-  'ἶ' => 'Ἶ',
-  'ἷ' => 'Ἷ',
-  'ὀ' => 'Ὀ',
-  'ὁ' => 'Ὁ',
-  'ὂ' => 'Ὂ',
-  'ὃ' => 'Ὃ',
-  'ὄ' => 'Ὄ',
-  'ὅ' => 'Ὅ',
-  'ὑ' => 'Ὑ',
-  'ὓ' => 'Ὓ',
-  'ὕ' => 'Ὕ',
-  'ὗ' => 'Ὗ',
-  'ὠ' => 'Ὠ',
-  'ὡ' => 'Ὡ',
-  'ὢ' => 'Ὢ',
-  'ὣ' => 'Ὣ',
-  'ὤ' => 'Ὤ',
-  'ὥ' => 'Ὥ',
-  'ὦ' => 'Ὦ',
-  'ὧ' => 'Ὧ',
-  'ὰ' => 'Ὰ',
-  'ά' => 'Ά',
-  'ὲ' => 'Ὲ',
-  'έ' => 'Έ',
-  'ὴ' => 'Ὴ',
-  'ή' => 'Ή',
-  'ὶ' => 'Ὶ',
-  'ί' => 'Ί',
-  'ὸ' => 'Ὸ',
-  'ό' => 'Ό',
-  'ὺ' => 'Ὺ',
-  'ύ' => 'Ύ',
-  'ὼ' => 'Ὼ',
-  'ώ' => 'Ώ',
-  'ᾀ' => 'ᾈ',
-  'ᾁ' => 'ᾉ',
-  'ᾂ' => 'ᾊ',
-  'ᾃ' => 'ᾋ',
-  'ᾄ' => 'ᾌ',
-  'ᾅ' => 'ᾍ',
-  'ᾆ' => 'ᾎ',
-  'ᾇ' => 'ᾏ',
-  'ᾐ' => 'ᾘ',
-  'ᾑ' => 'ᾙ',
-  'ᾒ' => 'ᾚ',
-  'ᾓ' => 'ᾛ',
-  'ᾔ' => 'ᾜ',
-  'ᾕ' => 'ᾝ',
-  'ᾖ' => 'ᾞ',
-  'ᾗ' => 'ᾟ',
-  'ᾠ' => 'ᾨ',
-  'ᾡ' => 'ᾩ',
-  'ᾢ' => 'ᾪ',
-  'ᾣ' => 'ᾫ',
-  'ᾤ' => 'ᾬ',
-  'ᾥ' => 'ᾭ',
-  'ᾦ' => 'ᾮ',
-  'ᾧ' => 'ᾯ',
-  'ᾰ' => 'Ᾰ',
-  'ᾱ' => 'Ᾱ',
-  'ᾳ' => 'ᾼ',
-  'ι' => 'Ι',
-  'ῃ' => 'ῌ',
-  'ῐ' => 'Ῐ',
-  'ῑ' => 'Ῑ',
-  'ῠ' => 'Ῠ',
-  'ῡ' => 'Ῡ',
-  'ῥ' => 'Ῥ',
-  'ῳ' => 'ῼ',
-  'ⅎ' => 'Ⅎ',
-  'ⅰ' => 'Ⅰ',
-  'ⅱ' => 'Ⅱ',
-  'ⅲ' => 'Ⅲ',
-  'ⅳ' => 'Ⅳ',
-  'ⅴ' => 'Ⅴ',
-  'ⅵ' => 'Ⅵ',
-  'ⅶ' => 'Ⅶ',
-  'ⅷ' => 'Ⅷ',
-  'ⅸ' => 'Ⅸ',
-  'ⅹ' => 'Ⅹ',
-  'ⅺ' => 'Ⅺ',
-  'ⅻ' => 'Ⅻ',
-  'ⅼ' => 'Ⅼ',
-  'ⅽ' => 'Ⅽ',
-  'ⅾ' => 'Ⅾ',
-  'ⅿ' => 'Ⅿ',
-  'ↄ' => 'Ↄ',
-  'ⓐ' => 'Ⓐ',
-  'ⓑ' => 'Ⓑ',
-  'ⓒ' => 'Ⓒ',
-  'ⓓ' => 'Ⓓ',
-  'ⓔ' => 'Ⓔ',
-  'ⓕ' => 'Ⓕ',
-  'ⓖ' => 'Ⓖ',
-  'ⓗ' => 'Ⓗ',
-  'ⓘ' => 'Ⓘ',
-  'ⓙ' => 'Ⓙ',
-  'ⓚ' => 'Ⓚ',
-  'ⓛ' => 'Ⓛ',
-  'ⓜ' => 'Ⓜ',
-  'ⓝ' => 'Ⓝ',
-  'ⓞ' => 'Ⓞ',
-  'ⓟ' => 'Ⓟ',
-  'ⓠ' => 'Ⓠ',
-  'ⓡ' => 'Ⓡ',
-  'ⓢ' => 'Ⓢ',
-  'ⓣ' => 'Ⓣ',
-  'ⓤ' => 'Ⓤ',
-  'ⓥ' => 'Ⓥ',
-  'ⓦ' => 'Ⓦ',
-  'ⓧ' => 'Ⓧ',
-  'ⓨ' => 'Ⓨ',
-  'ⓩ' => 'Ⓩ',
-  'ⰰ' => 'Ⰰ',
-  'ⰱ' => 'Ⰱ',
-  'ⰲ' => 'Ⰲ',
-  'ⰳ' => 'Ⰳ',
-  'ⰴ' => 'Ⰴ',
-  'ⰵ' => 'Ⰵ',
-  'ⰶ' => 'Ⰶ',
-  'ⰷ' => 'Ⰷ',
-  'ⰸ' => 'Ⰸ',
-  'ⰹ' => 'Ⰹ',
-  'ⰺ' => 'Ⰺ',
-  'ⰻ' => 'Ⰻ',
-  'ⰼ' => 'Ⰼ',
-  'ⰽ' => 'Ⰽ',
-  'ⰾ' => 'Ⰾ',
-  'ⰿ' => 'Ⰿ',
-  'ⱀ' => 'Ⱀ',
-  'ⱁ' => 'Ⱁ',
-  'ⱂ' => 'Ⱂ',
-  'ⱃ' => 'Ⱃ',
-  'ⱄ' => 'Ⱄ',
-  'ⱅ' => 'Ⱅ',
-  'ⱆ' => 'Ⱆ',
-  'ⱇ' => 'Ⱇ',
-  'ⱈ' => 'Ⱈ',
-  'ⱉ' => 'Ⱉ',
-  'ⱊ' => 'Ⱊ',
-  'ⱋ' => 'Ⱋ',
-  'ⱌ' => 'Ⱌ',
-  'ⱍ' => 'Ⱍ',
-  'ⱎ' => 'Ⱎ',
-  'ⱏ' => 'Ⱏ',
-  'ⱐ' => 'Ⱐ',
-  'ⱑ' => 'Ⱑ',
-  'ⱒ' => 'Ⱒ',
-  'ⱓ' => 'Ⱓ',
-  'ⱔ' => 'Ⱔ',
-  'ⱕ' => 'Ⱕ',
-  'ⱖ' => 'Ⱖ',
-  'ⱗ' => 'Ⱗ',
-  'ⱘ' => 'Ⱘ',
-  'ⱙ' => 'Ⱙ',
-  'ⱚ' => 'Ⱚ',
-  'ⱛ' => 'Ⱛ',
-  'ⱜ' => 'Ⱜ',
-  'ⱝ' => 'Ⱝ',
-  'ⱞ' => 'Ⱞ',
-  'ⱡ' => 'Ⱡ',
-  'ⱥ' => 'Ⱥ',
-  'ⱦ' => 'Ⱦ',
-  'ⱨ' => 'Ⱨ',
-  'ⱪ' => 'Ⱪ',
-  'ⱬ' => 'Ⱬ',
-  'ⱳ' => 'Ⱳ',
-  'ⱶ' => 'Ⱶ',
-  'ⲁ' => 'Ⲁ',
-  'ⲃ' => 'Ⲃ',
-  'ⲅ' => 'Ⲅ',
-  'ⲇ' => 'Ⲇ',
-  'ⲉ' => 'Ⲉ',
-  'ⲋ' => 'Ⲋ',
-  'ⲍ' => 'Ⲍ',
-  'ⲏ' => 'Ⲏ',
-  'ⲑ' => 'Ⲑ',
-  'ⲓ' => 'Ⲓ',
-  'ⲕ' => 'Ⲕ',
-  'ⲗ' => 'Ⲗ',
-  'ⲙ' => 'Ⲙ',
-  'ⲛ' => 'Ⲛ',
-  'ⲝ' => 'Ⲝ',
-  'ⲟ' => 'Ⲟ',
-  'ⲡ' => 'Ⲡ',
-  'ⲣ' => 'Ⲣ',
-  'ⲥ' => 'Ⲥ',
-  'ⲧ' => 'Ⲧ',
-  'ⲩ' => 'Ⲩ',
-  'ⲫ' => 'Ⲫ',
-  'ⲭ' => 'Ⲭ',
-  'ⲯ' => 'Ⲯ',
-  'ⲱ' => 'Ⲱ',
-  'ⲳ' => 'Ⲳ',
-  'ⲵ' => 'Ⲵ',
-  'ⲷ' => 'Ⲷ',
-  'ⲹ' => 'Ⲹ',
-  'ⲻ' => 'Ⲻ',
-  'ⲽ' => 'Ⲽ',
-  'ⲿ' => 'Ⲿ',
-  'ⳁ' => 'Ⳁ',
-  'ⳃ' => 'Ⳃ',
-  'ⳅ' => 'Ⳅ',
-  'ⳇ' => 'Ⳇ',
-  'ⳉ' => 'Ⳉ',
-  'ⳋ' => 'Ⳋ',
-  'ⳍ' => 'Ⳍ',
-  'ⳏ' => 'Ⳏ',
-  'ⳑ' => 'Ⳑ',
-  'ⳓ' => 'Ⳓ',
-  'ⳕ' => 'Ⳕ',
-  'ⳗ' => 'Ⳗ',
-  'ⳙ' => 'Ⳙ',
-  'ⳛ' => 'Ⳛ',
-  'ⳝ' => 'Ⳝ',
-  'ⳟ' => 'Ⳟ',
-  'ⳡ' => 'Ⳡ',
-  'ⳣ' => 'Ⳣ',
-  'ⳬ' => 'Ⳬ',
-  'ⳮ' => 'Ⳮ',
-  'ⳳ' => 'Ⳳ',
-  'ⴀ' => 'Ⴀ',
-  'ⴁ' => 'Ⴁ',
-  'ⴂ' => 'Ⴂ',
-  'ⴃ' => 'Ⴃ',
-  'ⴄ' => 'Ⴄ',
-  'ⴅ' => 'Ⴅ',
-  'ⴆ' => 'Ⴆ',
-  'ⴇ' => 'Ⴇ',
-  'ⴈ' => 'Ⴈ',
-  'ⴉ' => 'Ⴉ',
-  'ⴊ' => 'Ⴊ',
-  'ⴋ' => 'Ⴋ',
-  'ⴌ' => 'Ⴌ',
-  'ⴍ' => 'Ⴍ',
-  'ⴎ' => 'Ⴎ',
-  'ⴏ' => 'Ⴏ',
-  'ⴐ' => 'Ⴐ',
-  'ⴑ' => 'Ⴑ',
-  'ⴒ' => 'Ⴒ',
-  'ⴓ' => 'Ⴓ',
-  'ⴔ' => 'Ⴔ',
-  'ⴕ' => 'Ⴕ',
-  'ⴖ' => 'Ⴖ',
-  'ⴗ' => 'Ⴗ',
-  'ⴘ' => 'Ⴘ',
-  'ⴙ' => 'Ⴙ',
-  'ⴚ' => 'Ⴚ',
-  'ⴛ' => 'Ⴛ',
-  'ⴜ' => 'Ⴜ',
-  'ⴝ' => 'Ⴝ',
-  'ⴞ' => 'Ⴞ',
-  'ⴟ' => 'Ⴟ',
-  'ⴠ' => 'Ⴠ',
-  'ⴡ' => 'Ⴡ',
-  'ⴢ' => 'Ⴢ',
-  'ⴣ' => 'Ⴣ',
-  'ⴤ' => 'Ⴤ',
-  'ⴥ' => 'Ⴥ',
-  'ⴧ' => 'Ⴧ',
-  'ⴭ' => 'Ⴭ',
-  'ꙁ' => 'Ꙁ',
-  'ꙃ' => 'Ꙃ',
-  'ꙅ' => 'Ꙅ',
-  'ꙇ' => 'Ꙇ',
-  'ꙉ' => 'Ꙉ',
-  'ꙋ' => 'Ꙋ',
-  'ꙍ' => 'Ꙍ',
-  'ꙏ' => 'Ꙏ',
-  'ꙑ' => 'Ꙑ',
-  'ꙓ' => 'Ꙓ',
-  'ꙕ' => 'Ꙕ',
-  'ꙗ' => 'Ꙗ',
-  'ꙙ' => 'Ꙙ',
-  'ꙛ' => 'Ꙛ',
-  'ꙝ' => 'Ꙝ',
-  'ꙟ' => 'Ꙟ',
-  'ꙡ' => 'Ꙡ',
-  'ꙣ' => 'Ꙣ',
-  'ꙥ' => 'Ꙥ',
-  'ꙧ' => 'Ꙧ',
-  'ꙩ' => 'Ꙩ',
-  'ꙫ' => 'Ꙫ',
-  'ꙭ' => 'Ꙭ',
-  'ꚁ' => 'Ꚁ',
-  'ꚃ' => 'Ꚃ',
-  'ꚅ' => 'Ꚅ',
-  'ꚇ' => 'Ꚇ',
-  'ꚉ' => 'Ꚉ',
-  'ꚋ' => 'Ꚋ',
-  'ꚍ' => 'Ꚍ',
-  'ꚏ' => 'Ꚏ',
-  'ꚑ' => 'Ꚑ',
-  'ꚓ' => 'Ꚓ',
-  'ꚕ' => 'Ꚕ',
-  'ꚗ' => 'Ꚗ',
-  'ꚙ' => 'Ꚙ',
-  'ꚛ' => 'Ꚛ',
-  'ꜣ' => 'Ꜣ',
-  'ꜥ' => 'Ꜥ',
-  'ꜧ' => 'Ꜧ',
-  'ꜩ' => 'Ꜩ',
-  'ꜫ' => 'Ꜫ',
-  'ꜭ' => 'Ꜭ',
-  'ꜯ' => 'Ꜯ',
-  'ꜳ' => 'Ꜳ',
-  'ꜵ' => 'Ꜵ',
-  'ꜷ' => 'Ꜷ',
-  'ꜹ' => 'Ꜹ',
-  'ꜻ' => 'Ꜻ',
-  'ꜽ' => 'Ꜽ',
-  'ꜿ' => 'Ꜿ',
-  'ꝁ' => 'Ꝁ',
-  'ꝃ' => 'Ꝃ',
-  'ꝅ' => 'Ꝅ',
-  'ꝇ' => 'Ꝇ',
-  'ꝉ' => 'Ꝉ',
-  'ꝋ' => 'Ꝋ',
-  'ꝍ' => 'Ꝍ',
-  'ꝏ' => 'Ꝏ',
-  'ꝑ' => 'Ꝑ',
-  'ꝓ' => 'Ꝓ',
-  'ꝕ' => 'Ꝕ',
-  'ꝗ' => 'Ꝗ',
-  'ꝙ' => 'Ꝙ',
-  'ꝛ' => 'Ꝛ',
-  'ꝝ' => 'Ꝝ',
-  'ꝟ' => 'Ꝟ',
-  'ꝡ' => 'Ꝡ',
-  'ꝣ' => 'Ꝣ',
-  'ꝥ' => 'Ꝥ',
-  'ꝧ' => 'Ꝧ',
-  'ꝩ' => 'Ꝩ',
-  'ꝫ' => 'Ꝫ',
-  'ꝭ' => 'Ꝭ',
-  'ꝯ' => 'Ꝯ',
-  'ꝺ' => 'Ꝺ',
-  'ꝼ' => 'Ꝼ',
-  'ꝿ' => 'Ꝿ',
-  'ꞁ' => 'Ꞁ',
-  'ꞃ' => 'Ꞃ',
-  'ꞅ' => 'Ꞅ',
-  'ꞇ' => 'Ꞇ',
-  'ꞌ' => 'Ꞌ',
-  'ꞑ' => 'Ꞑ',
-  'ꞓ' => 'Ꞓ',
-  'ꞔ' => 'Ꞔ',
-  'ꞗ' => 'Ꞗ',
-  'ꞙ' => 'Ꞙ',
-  'ꞛ' => 'Ꞛ',
-  'ꞝ' => 'Ꞝ',
-  'ꞟ' => 'Ꞟ',
-  'ꞡ' => 'Ꞡ',
-  'ꞣ' => 'Ꞣ',
-  'ꞥ' => 'Ꞥ',
-  'ꞧ' => 'Ꞧ',
-  'ꞩ' => 'Ꞩ',
-  'ꞵ' => 'Ꞵ',
-  'ꞷ' => 'Ꞷ',
-  'ꞹ' => 'Ꞹ',
-  'ꞻ' => 'Ꞻ',
-  'ꞽ' => 'Ꞽ',
-  'ꞿ' => 'Ꞿ',
-  'ꟃ' => 'Ꟃ',
-  'ꟈ' => 'Ꟈ',
-  'ꟊ' => 'Ꟊ',
-  'ꟶ' => 'Ꟶ',
-  'ꭓ' => 'Ꭓ',
-  'ꭰ' => 'Ꭰ',
-  'ꭱ' => 'Ꭱ',
-  'ꭲ' => 'Ꭲ',
-  'ꭳ' => 'Ꭳ',
-  'ꭴ' => 'Ꭴ',
-  'ꭵ' => 'Ꭵ',
-  'ꭶ' => 'Ꭶ',
-  'ꭷ' => 'Ꭷ',
-  'ꭸ' => 'Ꭸ',
-  'ꭹ' => 'Ꭹ',
-  'ꭺ' => 'Ꭺ',
-  'ꭻ' => 'Ꭻ',
-  'ꭼ' => 'Ꭼ',
-  'ꭽ' => 'Ꭽ',
-  'ꭾ' => 'Ꭾ',
-  'ꭿ' => 'Ꭿ',
-  'ꮀ' => 'Ꮀ',
-  'ꮁ' => 'Ꮁ',
-  'ꮂ' => 'Ꮂ',
-  'ꮃ' => 'Ꮃ',
-  'ꮄ' => 'Ꮄ',
-  'ꮅ' => 'Ꮅ',
-  'ꮆ' => 'Ꮆ',
-  'ꮇ' => 'Ꮇ',
-  'ꮈ' => 'Ꮈ',
-  'ꮉ' => 'Ꮉ',
-  'ꮊ' => 'Ꮊ',
-  'ꮋ' => 'Ꮋ',
-  'ꮌ' => 'Ꮌ',
-  'ꮍ' => 'Ꮍ',
-  'ꮎ' => 'Ꮎ',
-  'ꮏ' => 'Ꮏ',
-  'ꮐ' => 'Ꮐ',
-  'ꮑ' => 'Ꮑ',
-  'ꮒ' => 'Ꮒ',
-  'ꮓ' => 'Ꮓ',
-  'ꮔ' => 'Ꮔ',
-  'ꮕ' => 'Ꮕ',
-  'ꮖ' => 'Ꮖ',
-  'ꮗ' => 'Ꮗ',
-  'ꮘ' => 'Ꮘ',
-  'ꮙ' => 'Ꮙ',
-  'ꮚ' => 'Ꮚ',
-  'ꮛ' => 'Ꮛ',
-  'ꮜ' => 'Ꮜ',
-  'ꮝ' => 'Ꮝ',
-  'ꮞ' => 'Ꮞ',
-  'ꮟ' => 'Ꮟ',
-  'ꮠ' => 'Ꮠ',
-  'ꮡ' => 'Ꮡ',
-  'ꮢ' => 'Ꮢ',
-  'ꮣ' => 'Ꮣ',
-  'ꮤ' => 'Ꮤ',
-  'ꮥ' => 'Ꮥ',
-  'ꮦ' => 'Ꮦ',
-  'ꮧ' => 'Ꮧ',
-  'ꮨ' => 'Ꮨ',
-  'ꮩ' => 'Ꮩ',
-  'ꮪ' => 'Ꮪ',
-  'ꮫ' => 'Ꮫ',
-  'ꮬ' => 'Ꮬ',
-  'ꮭ' => 'Ꮭ',
-  'ꮮ' => 'Ꮮ',
-  'ꮯ' => 'Ꮯ',
-  'ꮰ' => 'Ꮰ',
-  'ꮱ' => 'Ꮱ',
-  'ꮲ' => 'Ꮲ',
-  'ꮳ' => 'Ꮳ',
-  'ꮴ' => 'Ꮴ',
-  'ꮵ' => 'Ꮵ',
-  'ꮶ' => 'Ꮶ',
-  'ꮷ' => 'Ꮷ',
-  'ꮸ' => 'Ꮸ',
-  'ꮹ' => 'Ꮹ',
-  'ꮺ' => 'Ꮺ',
-  'ꮻ' => 'Ꮻ',
-  'ꮼ' => 'Ꮼ',
-  'ꮽ' => 'Ꮽ',
-  'ꮾ' => 'Ꮾ',
-  'ꮿ' => 'Ꮿ',
-  'a' => 'A',
-  'b' => 'B',
-  'c' => 'C',
-  'd' => 'D',
-  'e' => 'E',
-  'f' => 'F',
-  'g' => 'G',
-  'h' => 'H',
-  'i' => 'I',
-  'j' => 'J',
-  'k' => 'K',
-  'l' => 'L',
-  'm' => 'M',
-  'n' => 'N',
-  'o' => 'O',
-  'p' => 'P',
-  'q' => 'Q',
-  'r' => 'R',
-  's' => 'S',
-  't' => 'T',
-  'u' => 'U',
-  'v' => 'V',
-  'w' => 'W',
-  'x' => 'X',
-  'y' => 'Y',
-  'z' => 'Z',
-  '𐐨' => '𐐀',
-  '𐐩' => '𐐁',
-  '𐐪' => '𐐂',
-  '𐐫' => '𐐃',
-  '𐐬' => '𐐄',
-  '𐐭' => '𐐅',
-  '𐐮' => '𐐆',
-  '𐐯' => '𐐇',
-  '𐐰' => '𐐈',
-  '𐐱' => '𐐉',
-  '𐐲' => '𐐊',
-  '𐐳' => '𐐋',
-  '𐐴' => '𐐌',
-  '𐐵' => '𐐍',
-  '𐐶' => '𐐎',
-  '𐐷' => '𐐏',
-  '𐐸' => '𐐐',
-  '𐐹' => '𐐑',
-  '𐐺' => '𐐒',
-  '𐐻' => '𐐓',
-  '𐐼' => '𐐔',
-  '𐐽' => '𐐕',
-  '𐐾' => '𐐖',
-  '𐐿' => '𐐗',
-  '𐑀' => '𐐘',
-  '𐑁' => '𐐙',
-  '𐑂' => '𐐚',
-  '𐑃' => '𐐛',
-  '𐑄' => '𐐜',
-  '𐑅' => '𐐝',
-  '𐑆' => '𐐞',
-  '𐑇' => '𐐟',
-  '𐑈' => '𐐠',
-  '𐑉' => '𐐡',
-  '𐑊' => '𐐢',
-  '𐑋' => '𐐣',
-  '𐑌' => '𐐤',
-  '𐑍' => '𐐥',
-  '𐑎' => '𐐦',
-  '𐑏' => '𐐧',
-  '𐓘' => '𐒰',
-  '𐓙' => '𐒱',
-  '𐓚' => '𐒲',
-  '𐓛' => '𐒳',
-  '𐓜' => '𐒴',
-  '𐓝' => '𐒵',
-  '𐓞' => '𐒶',
-  '𐓟' => '𐒷',
-  '𐓠' => '𐒸',
-  '𐓡' => '𐒹',
-  '𐓢' => '𐒺',
-  '𐓣' => '𐒻',
-  '𐓤' => '𐒼',
-  '𐓥' => '𐒽',
-  '𐓦' => '𐒾',
-  '𐓧' => '𐒿',
-  '𐓨' => '𐓀',
-  '𐓩' => '𐓁',
-  '𐓪' => '𐓂',
-  '𐓫' => '𐓃',
-  '𐓬' => '𐓄',
-  '𐓭' => '𐓅',
-  '𐓮' => '𐓆',
-  '𐓯' => '𐓇',
-  '𐓰' => '𐓈',
-  '𐓱' => '𐓉',
-  '𐓲' => '𐓊',
-  '𐓳' => '𐓋',
-  '𐓴' => '𐓌',
-  '𐓵' => '𐓍',
-  '𐓶' => '𐓎',
-  '𐓷' => '𐓏',
-  '𐓸' => '𐓐',
-  '𐓹' => '𐓑',
-  '𐓺' => '𐓒',
-  '𐓻' => '𐓓',
-  '𐳀' => '𐲀',
-  '𐳁' => '𐲁',
-  '𐳂' => '𐲂',
-  '𐳃' => '𐲃',
-  '𐳄' => '𐲄',
-  '𐳅' => '𐲅',
-  '𐳆' => '𐲆',
-  '𐳇' => '𐲇',
-  '𐳈' => '𐲈',
-  '𐳉' => '𐲉',
-  '𐳊' => '𐲊',
-  '𐳋' => '𐲋',
-  '𐳌' => '𐲌',
-  '𐳍' => '𐲍',
-  '𐳎' => '𐲎',
-  '𐳏' => '𐲏',
-  '𐳐' => '𐲐',
-  '𐳑' => '𐲑',
-  '𐳒' => '𐲒',
-  '𐳓' => '𐲓',
-  '𐳔' => '𐲔',
-  '𐳕' => '𐲕',
-  '𐳖' => '𐲖',
-  '𐳗' => '𐲗',
-  '𐳘' => '𐲘',
-  '𐳙' => '𐲙',
-  '𐳚' => '𐲚',
-  '𐳛' => '𐲛',
-  '𐳜' => '𐲜',
-  '𐳝' => '𐲝',
-  '𐳞' => '𐲞',
-  '𐳟' => '𐲟',
-  '𐳠' => '𐲠',
-  '𐳡' => '𐲡',
-  '𐳢' => '𐲢',
-  '𐳣' => '𐲣',
-  '𐳤' => '𐲤',
-  '𐳥' => '𐲥',
-  '𐳦' => '𐲦',
-  '𐳧' => '𐲧',
-  '𐳨' => '𐲨',
-  '𐳩' => '𐲩',
-  '𐳪' => '𐲪',
-  '𐳫' => '𐲫',
-  '𐳬' => '𐲬',
-  '𐳭' => '𐲭',
-  '𐳮' => '𐲮',
-  '𐳯' => '𐲯',
-  '𐳰' => '𐲰',
-  '𐳱' => '𐲱',
-  '𐳲' => '𐲲',
-  '𑣀' => '𑢠',
-  '𑣁' => '𑢡',
-  '𑣂' => '𑢢',
-  '𑣃' => '𑢣',
-  '𑣄' => '𑢤',
-  '𑣅' => '𑢥',
-  '𑣆' => '𑢦',
-  '𑣇' => '𑢧',
-  '𑣈' => '𑢨',
-  '𑣉' => '𑢩',
-  '𑣊' => '𑢪',
-  '𑣋' => '𑢫',
-  '𑣌' => '𑢬',
-  '𑣍' => '𑢭',
-  '𑣎' => '𑢮',
-  '𑣏' => '𑢯',
-  '𑣐' => '𑢰',
-  '𑣑' => '𑢱',
-  '𑣒' => '𑢲',
-  '𑣓' => '𑢳',
-  '𑣔' => '𑢴',
-  '𑣕' => '𑢵',
-  '𑣖' => '𑢶',
-  '𑣗' => '𑢷',
-  '𑣘' => '𑢸',
-  '𑣙' => '𑢹',
-  '𑣚' => '𑢺',
-  '𑣛' => '𑢻',
-  '𑣜' => '𑢼',
-  '𑣝' => '𑢽',
-  '𑣞' => '𑢾',
-  '𑣟' => '𑢿',
-  '𖹠' => '𖹀',
-  '𖹡' => '𖹁',
-  '𖹢' => '𖹂',
-  '𖹣' => '𖹃',
-  '𖹤' => '𖹄',
-  '𖹥' => '𖹅',
-  '𖹦' => '𖹆',
-  '𖹧' => '𖹇',
-  '𖹨' => '𖹈',
-  '𖹩' => '𖹉',
-  '𖹪' => '𖹊',
-  '𖹫' => '𖹋',
-  '𖹬' => '𖹌',
-  '𖹭' => '𖹍',
-  '𖹮' => '𖹎',
-  '𖹯' => '𖹏',
-  '𖹰' => '𖹐',
-  '𖹱' => '𖹑',
-  '𖹲' => '𖹒',
-  '𖹳' => '𖹓',
-  '𖹴' => '𖹔',
-  '𖹵' => '𖹕',
-  '𖹶' => '𖹖',
-  '𖹷' => '𖹗',
-  '𖹸' => '𖹘',
-  '𖹹' => '𖹙',
-  '𖹺' => '𖹚',
-  '𖹻' => '𖹛',
-  '𖹼' => '𖹜',
-  '𖹽' => '𖹝',
-  '𖹾' => '𖹞',
-  '𖹿' => '𖹟',
-  '𞤢' => '𞤀',
-  '𞤣' => '𞤁',
-  '𞤤' => '𞤂',
-  '𞤥' => '𞤃',
-  '𞤦' => '𞤄',
-  '𞤧' => '𞤅',
-  '𞤨' => '𞤆',
-  '𞤩' => '𞤇',
-  '𞤪' => '𞤈',
-  '𞤫' => '𞤉',
-  '𞤬' => '𞤊',
-  '𞤭' => '𞤋',
-  '𞤮' => '𞤌',
-  '𞤯' => '𞤍',
-  '𞤰' => '𞤎',
-  '𞤱' => '𞤏',
-  '𞤲' => '𞤐',
-  '𞤳' => '𞤑',
-  '𞤴' => '𞤒',
-  '𞤵' => '𞤓',
-  '𞤶' => '𞤔',
-  '𞤷' => '𞤕',
-  '𞤸' => '𞤖',
-  '𞤹' => '𞤗',
-  '𞤺' => '𞤘',
-  '𞤻' => '𞤙',
-  '𞤼' => '𞤚',
-  '𞤽' => '𞤛',
-  '𞤾' => '𞤜',
-  '𞤿' => '𞤝',
-  '𞥀' => '𞤞',
-  '𞥁' => '𞤟',
-  '𞥂' => '𞤠',
-  '𞥃' => '𞤡',
-);
diff --git a/vendor/symfony/polyfill-mbstring/bootstrap.php b/vendor/symfony/polyfill-mbstring/bootstrap.php
deleted file mode 100644
index b36a0926f..000000000
--- a/vendor/symfony/polyfill-mbstring/bootstrap.php
+++ /dev/null
@@ -1,141 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-use Symfony\Polyfill\Mbstring as p;
-
-if (!function_exists('mb_convert_encoding')) {
-    function mb_convert_encoding($s, $to, $from = null) { return p\Mbstring::mb_convert_encoding($s, $to, $from); }
-}
-if (!function_exists('mb_decode_mimeheader')) {
-    function mb_decode_mimeheader($s) { return p\Mbstring::mb_decode_mimeheader($s); }
-}
-if (!function_exists('mb_encode_mimeheader')) {
-    function mb_encode_mimeheader($s, $charset = null, $transferEnc = null, $lf = null, $indent = null) { return p\Mbstring::mb_encode_mimeheader($s, $charset, $transferEnc, $lf, $indent); }
-}
-if (!function_exists('mb_decode_numericentity')) {
-    function mb_decode_numericentity($s, $convmap, $enc = null) { return p\Mbstring::mb_decode_numericentity($s, $convmap, $enc); }
-}
-if (!function_exists('mb_encode_numericentity')) {
-    function mb_encode_numericentity($s, $convmap, $enc = null, $is_hex = false) { return p\Mbstring::mb_encode_numericentity($s, $convmap, $enc, $is_hex); }
-}
-if (!function_exists('mb_convert_case')) {
-    function mb_convert_case($s, $mode, $enc = null) { return p\Mbstring::mb_convert_case($s, $mode, $enc); }
-}
-if (!function_exists('mb_internal_encoding')) {
-    function mb_internal_encoding($enc = null) { return p\Mbstring::mb_internal_encoding($enc); }
-}
-if (!function_exists('mb_language')) {
-    function mb_language($lang = null) { return p\Mbstring::mb_language($lang); }
-}
-if (!function_exists('mb_list_encodings')) {
-    function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); }
-}
-if (!function_exists('mb_encoding_aliases')) {
-    function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); }
-}
-if (!function_exists('mb_check_encoding')) {
-    function mb_check_encoding($var = null, $encoding = null) { return p\Mbstring::mb_check_encoding($var, $encoding); }
-}
-if (!function_exists('mb_detect_encoding')) {
-    function mb_detect_encoding($str, $encodingList = null, $strict = false) { return p\Mbstring::mb_detect_encoding($str, $encodingList, $strict); }
-}
-if (!function_exists('mb_detect_order')) {
-    function mb_detect_order($encodingList = null) { return p\Mbstring::mb_detect_order($encodingList); }
-}
-if (!function_exists('mb_parse_str')) {
-    function mb_parse_str($s, &$result = array()) { parse_str($s, $result); }
-}
-if (!function_exists('mb_strlen')) {
-    function mb_strlen($s, $enc = null) { return p\Mbstring::mb_strlen($s, $enc); }
-}
-if (!function_exists('mb_strpos')) {
-    function mb_strpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strpos($s, $needle, $offset, $enc); }
-}
-if (!function_exists('mb_strtolower')) {
-    function mb_strtolower($s, $enc = null) { return p\Mbstring::mb_strtolower($s, $enc); }
-}
-if (!function_exists('mb_strtoupper')) {
-    function mb_strtoupper($s, $enc = null) { return p\Mbstring::mb_strtoupper($s, $enc); }
-}
-if (!function_exists('mb_substitute_character')) {
-    function mb_substitute_character($char = null) { return p\Mbstring::mb_substitute_character($char); }
-}
-if (!function_exists('mb_substr')) {
-    function mb_substr($s, $start, $length = 2147483647, $enc = null) { return p\Mbstring::mb_substr($s, $start, $length, $enc); }
-}
-if (!function_exists('mb_stripos')) {
-    function mb_stripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_stripos($s, $needle, $offset, $enc); }
-}
-if (!function_exists('mb_stristr')) {
-    function mb_stristr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_stristr($s, $needle, $part, $enc); }
-}
-if (!function_exists('mb_strrchr')) {
-    function mb_strrchr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrchr($s, $needle, $part, $enc); }
-}
-if (!function_exists('mb_strrichr')) {
-    function mb_strrichr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrichr($s, $needle, $part, $enc); }
-}
-if (!function_exists('mb_strripos')) {
-    function mb_strripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strripos($s, $needle, $offset, $enc); }
-}
-if (!function_exists('mb_strrpos')) {
-    function mb_strrpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strrpos($s, $needle, $offset, $enc); }
-}
-if (!function_exists('mb_strstr')) {
-    function mb_strstr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strstr($s, $needle, $part, $enc); }
-}
-if (!function_exists('mb_get_info')) {
-    function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); }
-}
-if (!function_exists('mb_http_output')) {
-    function mb_http_output($enc = null) { return p\Mbstring::mb_http_output($enc); }
-}
-if (!function_exists('mb_strwidth')) {
-    function mb_strwidth($s, $enc = null) { return p\Mbstring::mb_strwidth($s, $enc); }
-}
-if (!function_exists('mb_substr_count')) {
-    function mb_substr_count($haystack, $needle, $enc = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $enc); }
-}
-if (!function_exists('mb_output_handler')) {
-    function mb_output_handler($contents, $status) { return p\Mbstring::mb_output_handler($contents, $status); }
-}
-if (!function_exists('mb_http_input')) {
-    function mb_http_input($type = '') { return p\Mbstring::mb_http_input($type); }
-}
-if (!function_exists('mb_convert_variables')) {
-    function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) { return p\Mbstring::mb_convert_variables($toEncoding, $fromEncoding, $a, $b, $c, $d, $e, $f); }
-}
-if (!function_exists('mb_ord')) {
-    function mb_ord($s, $enc = null) { return p\Mbstring::mb_ord($s, $enc); }
-}
-if (!function_exists('mb_chr')) {
-    function mb_chr($code, $enc = null) { return p\Mbstring::mb_chr($code, $enc); }
-}
-if (!function_exists('mb_scrub')) {
-    function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); }
-}
-if (!function_exists('mb_str_split')) {
-    function mb_str_split($string, $split_length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $split_length, $encoding); }
-}
-
-if (extension_loaded('mbstring')) {
-    return;
-}
-
-if (!defined('MB_CASE_UPPER')) {
-    define('MB_CASE_UPPER', 0);
-}
-if (!defined('MB_CASE_LOWER')) {
-    define('MB_CASE_LOWER', 1);
-}
-if (!defined('MB_CASE_TITLE')) {
-    define('MB_CASE_TITLE', 2);
-}
diff --git a/vendor/symfony/polyfill-php72/Php72.php b/vendor/symfony/polyfill-php72/Php72.php
index 9b3edc7c7..2b706d42b 100644
--- a/vendor/symfony/polyfill-php72/Php72.php
+++ b/vendor/symfony/polyfill-php72/Php72.php
@@ -73,7 +73,7 @@ public static function php_os_family()
             return 'Windows';
         }
 
-        $map = array(
+        $map = [
             'Darwin' => 'Darwin',
             'DragonFly' => 'BSD',
             'FreeBSD' => 'BSD',
@@ -81,9 +81,9 @@ public static function php_os_family()
             'OpenBSD' => 'BSD',
             'Linux' => 'Linux',
             'SunOS' => 'Solaris',
-        );
+        ];
 
-        return isset($map[PHP_OS]) ? $map[PHP_OS] : 'Unknown';
+        return isset($map[\PHP_OS]) ? $map[\PHP_OS] : 'Unknown';
     }
 
     public static function spl_object_id($object)
@@ -102,7 +102,7 @@ public static function spl_object_id($object)
     public static function sapi_windows_vt100_support($stream, $enable = null)
     {
         if (!\is_resource($stream)) {
-            trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, '.\gettype($stream).' given', E_USER_WARNING);
+            trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, '.\gettype($stream).' given', \E_USER_WARNING);
 
             return false;
         }
@@ -110,7 +110,7 @@ public static function sapi_windows_vt100_support($stream, $enable = null)
         $meta = stream_get_meta_data($stream);
 
         if ('STDIO' !== $meta['stream_type']) {
-            trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', E_USER_WARNING);
+            trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', \E_USER_WARNING);
 
             return false;
         }
@@ -134,7 +134,7 @@ public static function sapi_windows_vt100_support($stream, $enable = null)
     public static function stream_isatty($stream)
     {
         if (!\is_resource($stream)) {
-            trigger_error('stream_isatty() expects parameter 1 to be resource, '.\gettype($stream).' given', E_USER_WARNING);
+            trigger_error('stream_isatty() expects parameter 1 to be resource, '.\gettype($stream).' given', \E_USER_WARNING);
 
             return false;
         }
@@ -150,12 +150,12 @@ public static function stream_isatty($stream)
 
     private static function initHashMask()
     {
-        $obj = (object) array();
+        $obj = (object) [];
         self::$hashMask = -1;
 
         // check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below
-        $obFuncs = array('ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush');
-        foreach (debug_backtrace(\PHP_VERSION_ID >= 50400 ? DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) {
+        $obFuncs = ['ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush'];
+        foreach (debug_backtrace(\PHP_VERSION_ID >= 50400 ? \DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) {
             if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && \in_array($frame['function'], $obFuncs)) {
                 $frame['line'] = 0;
                 break;
@@ -191,7 +191,7 @@ public static function mb_chr($code, $encoding = null)
 
     public static function mb_ord($s, $encoding = null)
     {
-        if (null == $encoding) {
+        if (null === $encoding) {
             $s = mb_convert_encoding($s, 'UTF-8');
         } elseif ('UTF-8' !== $encoding) {
             $s = mb_convert_encoding($s, 'UTF-8', $encoding);
diff --git a/vendor/symfony/polyfill-php72/bootstrap.php b/vendor/symfony/polyfill-php72/bootstrap.php
index a27a900a4..b5c92d4c7 100644
--- a/vendor/symfony/polyfill-php72/bootstrap.php
+++ b/vendor/symfony/polyfill-php72/bootstrap.php
@@ -11,7 +11,7 @@
 
 use Symfony\Polyfill\Php72 as p;
 
-if (PHP_VERSION_ID >= 70200) {
+if (\PHP_VERSION_ID >= 70200) {
     return;
 }
 
@@ -31,27 +31,27 @@
     define('PHP_OS_FAMILY', p\Php72::php_os_family());
 }
 
-if ('\\' === DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) {
+if ('\\' === \DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) {
     function sapi_windows_vt100_support($stream, $enable = null) { return p\Php72::sapi_windows_vt100_support($stream, $enable); }
 }
 if (!function_exists('stream_isatty')) {
     function stream_isatty($stream) { return p\Php72::stream_isatty($stream); }
 }
 if (!function_exists('utf8_encode')) {
-    function utf8_encode($s) { return p\Php72::utf8_encode($s); }
+    function utf8_encode($string) { return p\Php72::utf8_encode($string); }
 }
 if (!function_exists('utf8_decode')) {
-    function utf8_decode($s) { return p\Php72::utf8_decode($s); }
+    function utf8_decode($string) { return p\Php72::utf8_decode($string); }
 }
 if (!function_exists('spl_object_id')) {
-    function spl_object_id($s) { return p\Php72::spl_object_id($s); }
+    function spl_object_id($object) { return p\Php72::spl_object_id($object); }
 }
 if (!function_exists('mb_ord')) {
-    function mb_ord($s, $enc = null) { return p\Php72::mb_ord($s, $enc); }
+    function mb_ord($string, $encoding = null) { return p\Php72::mb_ord($string, $encoding); }
 }
 if (!function_exists('mb_chr')) {
-    function mb_chr($code, $enc = null) { return p\Php72::mb_chr($code, $enc); }
+    function mb_chr($codepoint, $encoding = null) { return p\Php72::mb_chr($codepoint, $encoding); }
 }
 if (!function_exists('mb_scrub')) {
-    function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); }
+    function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); }
 }
diff --git a/vendor/symfony/polyfill-php72/composer.json b/vendor/symfony/polyfill-php72/composer.json
index efca01048..7946892c3 100644
--- a/vendor/symfony/polyfill-php72/composer.json
+++ b/vendor/symfony/polyfill-php72/composer.json
@@ -16,7 +16,7 @@
         }
     ],
     "require": {
-        "php": ">=5.3.3"
+        "php": ">=7.1"
     },
     "autoload": {
         "psr-4": { "Symfony\\Polyfill\\Php72\\": "" },
@@ -25,7 +25,7 @@
     "minimum-stability": "dev",
     "extra": {
         "branch-alias": {
-            "dev-master": "1.17-dev"
+            "dev-main": "1.22-dev"
         },
         "thanks": {
             "name": "symfony/polyfill",
diff --git a/vendor/topthink/think-installer/composer.json b/vendor/topthink/think-installer/composer.json
index 4005de224..08bc72b9b 100644
--- a/vendor/topthink/think-installer/composer.json
+++ b/vendor/topthink/think-installer/composer.json
@@ -2,10 +2,10 @@
     "name": "topthink/think-installer",
     "type": "composer-plugin",
     "require": {
-        "composer-plugin-api": "^1.0"
+        "composer-plugin-api": "^1.0||^2.0"
     },
     "require-dev": {
-        "composer/composer": "1.0.*@dev"
+        "composer/composer": "^1.0||^2.0"
     },
     "license": "Apache-2.0",
     "authors": [
diff --git a/vendor/topthink/think-installer/src/LibraryInstaller.php b/vendor/topthink/think-installer/src/LibraryInstaller.php
new file mode 100644
index 000000000..45c05bcaa
--- /dev/null
+++ b/vendor/topthink/think-installer/src/LibraryInstaller.php
@@ -0,0 +1,28 @@
+makePromise(parent::install($repo, $package));
+    }
+
+    public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
+    {
+        return $this->makePromise(parent::update($repo, $initial, $target));
+    }
+
+    protected function makePromise($promise)
+    {
+        if ($promise instanceof PromiseInterface) {
+            return $promise;
+        }
+        return new Promise();
+    }
+}
diff --git a/vendor/topthink/think-installer/src/Plugin.php b/vendor/topthink/think-installer/src/Plugin.php
index 757c30fff..441523200 100644
--- a/vendor/topthink/think-installer/src/Plugin.php
+++ b/vendor/topthink/think-installer/src/Plugin.php
@@ -3,7 +3,6 @@
 namespace think\composer;
 
 use Composer\Composer;
-use Composer\Installer;
 use Composer\IO\IOInterface;
 use Composer\Plugin\PluginInterface;
 
@@ -21,6 +20,15 @@ public function activate(Composer $composer, IOInterface $io)
 
         //扩展
         $manager->addInstaller(new ThinkExtend($io, $composer));
+    }
+
+    public function deactivate(Composer $composer, IOInterface $io)
+    {
+
+    }
+
+    public function uninstall(Composer $composer, IOInterface $io)
+    {
 
     }
-}
\ No newline at end of file
+}
diff --git a/vendor/topthink/think-installer/src/Promise.php b/vendor/topthink/think-installer/src/Promise.php
new file mode 100644
index 000000000..6bfed5d3f
--- /dev/null
+++ b/vendor/topthink/think-installer/src/Promise.php
@@ -0,0 +1,11 @@
+copyExtraFiles($package);
+        return parent::install($repo, $package)
+            ->then(function () use ($package) {
+                $this->copyExtraFiles($package);
+            });
     }
 
     public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
     {
-        parent::update($repo, $initial, $target);
-        $this->copyExtraFiles($target);
-
+        return parent::update($repo, $initial, $target)
+            ->then(function () use ($target) {
+                $this->copyExtraFiles($target);
+            });
     }
 
     protected function copyExtraFiles(PackageInterface $package)
@@ -60,7 +61,6 @@ protected function copyExtraFiles(PackageInterface $package)
 
                     copy($source, $target);
                 }
-
             }
         }
     }
@@ -69,4 +69,4 @@ public function supports($packageType)
     {
         return 'think-extend' === $packageType;
     }
-}
\ No newline at end of file
+}
diff --git a/vendor/topthink/think-installer/src/ThinkFramework.php b/vendor/topthink/think-installer/src/ThinkFramework.php
index cdb7d8434..2a7cc0380 100644
--- a/vendor/topthink/think-installer/src/ThinkFramework.php
+++ b/vendor/topthink/think-installer/src/ThinkFramework.php
@@ -2,20 +2,12 @@
 
 namespace think\composer;
 
-use Composer\Installer\LibraryInstaller;
 use Composer\Package\PackageInterface;
 use Composer\Repository\InstalledRepositoryInterface;
+use InvalidArgumentException;
 
 class ThinkFramework extends LibraryInstaller
 {
-    public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
-    {
-        parent::install($repo, $package);
-        if ($this->composer->getPackage()->getType() == 'project' && $package->getInstallationSource() != 'source') {
-            //remove tests dir
-            $this->filesystem->removeDirectory($this->getInstallPath($package) . DIRECTORY_SEPARATOR . 'tests');
-        }
-    }
 
     /**
      * {@inheritDoc}
@@ -23,7 +15,7 @@ public function install(InstalledRepositoryInterface $repo, PackageInterface $pa
     public function getInstallPath(PackageInterface $package)
     {
         if ('topthink/framework' !== $package->getPrettyName()) {
-            throw new \InvalidArgumentException('Unable to install this library!');
+            throw new InvalidArgumentException('Unable to install this library!');
         }
 
         if ($this->composer->getPackage()->getType() !== 'project') {
@@ -40,9 +32,24 @@ public function getInstallPath(PackageInterface $package)
         return 'thinkphp';
     }
 
+    public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
+    {
+        return parent::install($repo, $package)
+            ->then(function () use ($package) {
+                $this->removeTestDir($package);
+            });
+    }
+
     public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
     {
-        parent::update($repo, $initial, $target);
+        return parent::update($repo, $initial, $target)
+            ->then(function () use ($target) {
+                $this->removeTestDir($target);
+            });
+    }
+
+    protected function removeTestDir(PackageInterface $target)
+    {
         if ($this->composer->getPackage()->getType() == 'project' && $target->getInstallationSource() != 'source') {
             //remove tests dir
             $this->filesystem->removeDirectory($this->getInstallPath($target) . DIRECTORY_SEPARATOR . 'tests');
@@ -56,4 +63,4 @@ public function supports($packageType)
     {
         return 'think-framework' === $packageType;
     }
-}
\ No newline at end of file
+}
diff --git a/vendor/topthink/think-installer/src/ThinkTesting.php b/vendor/topthink/think-installer/src/ThinkTesting.php
index bf27f7276..af74d20e7 100644
--- a/vendor/topthink/think-installer/src/ThinkTesting.php
+++ b/vendor/topthink/think-installer/src/ThinkTesting.php
@@ -11,10 +11,9 @@
 
 namespace think\composer;
 
-
-use Composer\Installer\LibraryInstaller;
 use Composer\Package\PackageInterface;
 use Composer\Repository\InstalledRepositoryInterface;
+use InvalidArgumentException;
 
 class ThinkTesting extends LibraryInstaller
 {
@@ -24,7 +23,7 @@ class ThinkTesting extends LibraryInstaller
     public function getInstallPath(PackageInterface $package)
     {
         if ('topthink/think-testing' !== $package->getPrettyName()) {
-            throw new \InvalidArgumentException('Unable to install this library!');
+            throw new InvalidArgumentException('Unable to install this library!');
         }
 
         return parent::getInstallPath($package);
@@ -32,19 +31,18 @@ public function getInstallPath(PackageInterface $package)
 
     public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
     {
-        parent::install($repo, $package);
-
-        $this->copyTestDir($package);
-
-
+        return parent::install($repo, $package)
+            ->then(function () use ($package) {
+                $this->copyTestDir($package);
+            });
     }
 
     public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
     {
-        parent::update($repo, $initial, $target);
-
-        $this->copyTestDir($target);
-
+        return parent::update($repo, $initial, $target)
+            ->then(function () use ($target) {
+                $this->copyTestDir($target);
+            });
     }
 
     private function copyTestDir(PackageInterface $package)
@@ -65,4 +63,4 @@ public function supports($packageType)
     {
         return 'think-testing' === $packageType;
     }
-}
\ No newline at end of file
+}