From d5d8b101fd0bde7402d077c4de88471cd898d21f Mon Sep 17 00:00:00 2001 From: Repellent Date: Thu, 2 Oct 2025 18:09:57 +0500 Subject: [PATCH] =?UTF-8?q?=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20,=20=D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=81=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=D0=BC=20=D1=83=D1=81=D1=82=D0=B0=D1=80=D0=B5=D0=B2?= =?UTF-8?q?=D1=88=D0=B5=D0=B3=D0=BE=20SwiftMailer=20=D0=B8=20=D0=B8=D0=BD?= =?UTF-8?q?=D1=82=D0=B5=D0=B3=D1=80=D0=B0=D1=86=D0=B8=D0=B5=D0=B9=20Symfon?= =?UTF-8?q?yMailer,=20UP=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D0=B8=20=D0=B4?= =?UTF-8?q?=D0=BE=20v3.29=20ALT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +- admin/lang/ru/settings.txt | 6 +- admin/templates/settings/settings_main.tpl | 6 +- functions/func.mail.php | 521 +- inc/config.php | 2 +- lib/SwiftMailer/classes/Swift.php | 80 - lib/SwiftMailer/classes/Swift/Attachment.php | 71 - .../AbstractFilterableInputStream.php | 181 - .../Swift/ByteStream/ArrayByteStream.php | 182 - .../Swift/ByteStream/FileByteStream.php | 231 - .../ByteStream/TemporaryFileByteStream.php | 42 - .../classes/Swift/CharacterReader.php | 67 - .../GenericFixedWidthReader.php | 97 - .../Swift/CharacterReader/UsAsciiReader.php | 84 - .../Swift/CharacterReader/Utf8Reader.php | 176 - .../classes/Swift/CharacterReaderFactory.php | 26 - .../SimpleCharacterReaderFactory.php | 124 - .../classes/Swift/CharacterStream.php | 89 - .../CharacterStream/ArrayCharacterStream.php | 293 - .../CharacterStream/NgCharacterStream.php | 267 - .../classes/Swift/ConfigurableSpool.php | 63 - .../classes/Swift/DependencyContainer.php | 373 -- .../classes/Swift/DependencyException.php | 27 - .../classes/Swift/EmbeddedFile.php | 69 - lib/SwiftMailer/classes/Swift/Encoder.php | 28 - .../classes/Swift/Encoder/Base64Encoder.php | 58 - .../classes/Swift/Encoder/Rfc2231Encoder.php | 92 - lib/SwiftMailer/classes/Swift/Encoding.php | 64 - .../classes/Swift/Events/CommandEvent.php | 65 - .../classes/Swift/Events/CommandListener.php | 24 - .../classes/Swift/Events/Event.php | 38 - .../classes/Swift/Events/EventDispatcher.php | 83 - .../classes/Swift/Events/EventListener.php | 18 - .../classes/Swift/Events/EventObject.php | 63 - .../classes/Swift/Events/ResponseEvent.php | 65 - .../classes/Swift/Events/ResponseListener.php | 24 - .../classes/Swift/Events/SendEvent.php | 129 - .../classes/Swift/Events/SendListener.php | 31 - .../Swift/Events/SimpleEventDispatcher.php | 156 - .../Swift/Events/TransportChangeEvent.php | 27 - .../Swift/Events/TransportChangeListener.php | 45 - .../Swift/Events/TransportExceptionEvent.php | 46 - .../Events/TransportExceptionListener.php | 24 - .../classes/Swift/FailoverTransport.php | 45 - lib/SwiftMailer/classes/Swift/FileSpool.php | 208 - lib/SwiftMailer/classes/Swift/FileStream.php | 24 - lib/SwiftMailer/classes/Swift/Filterable.php | 32 - lib/SwiftMailer/classes/Swift/Image.php | 61 - .../classes/Swift/InputByteStream.php | 75 - lib/SwiftMailer/classes/Swift/IoException.php | 29 - lib/SwiftMailer/classes/Swift/KeyCache.php | 105 - .../classes/Swift/KeyCache/ArrayKeyCache.php | 206 - .../classes/Swift/KeyCache/DiskKeyCache.php | 321 - .../Swift/KeyCache/KeyCacheInputStream.php | 51 - .../classes/Swift/KeyCache/NullKeyCache.php | 115 - .../KeyCache/SimpleKeyCacheInputStream.php | 127 - .../classes/Swift/LoadBalancedTransport.php | 45 - .../classes/Swift/MailTransport.php | 45 - lib/SwiftMailer/classes/Swift/Mailer.php | 114 - .../Swift/Mailer/ArrayRecipientIterator.php | 55 - .../Swift/Mailer/RecipientIterator.php | 32 - lib/SwiftMailer/classes/Swift/MemorySpool.php | 110 - lib/SwiftMailer/classes/Swift/Message.php | 291 - .../classes/Swift/Mime/Attachment.php | 149 - .../classes/Swift/Mime/CharsetObserver.php | 24 - .../classes/Swift/Mime/ContentEncoder.php | 34 - .../ContentEncoder/Base64ContentEncoder.php | 104 - .../ContentEncoder/NativeQpContentEncoder.php | 123 - .../ContentEncoder/PlainContentEncoder.php | 162 - .../Mime/ContentEncoder/QpContentEncoder.php | 134 - .../ContentEncoder/QpContentEncoderProxy.php | 98 - .../Mime/ContentEncoder/RawContentEncoder.php | 64 - .../classes/Swift/Mime/EmbeddedFile.php | 45 - .../classes/Swift/Mime/EncodingObserver.php | 24 - .../classes/Swift/Mime/Grammar.php | 176 - lib/SwiftMailer/classes/Swift/Mime/Header.php | 93 - .../HeaderEncoder/Base64HeaderEncoder.php | 55 - .../Mime/HeaderEncoder/QpHeaderEncoder.php | 65 - .../classes/Swift/Mime/HeaderFactory.php | 78 - .../classes/Swift/Mime/HeaderSet.php | 169 - .../Swift/Mime/Headers/AbstractHeader.php | 503 -- .../classes/Swift/Mime/Headers/DateHeader.php | 125 - .../Mime/Headers/IdentificationHeader.php | 180 - .../Swift/Mime/Headers/MailboxHeader.php | 353 - .../Swift/Mime/Headers/OpenDKIMHeader.php | 133 - .../Mime/Headers/ParameterizedHeader.php | 258 - .../classes/Swift/Mime/Headers/PathHeader.php | 143 - .../Swift/Mime/Headers/UnstructuredHeader.php | 112 - .../classes/Swift/Mime/Message.php | 223 - .../classes/Swift/Mime/MimeEntity.php | 117 - .../classes/Swift/Mime/MimePart.php | 212 - .../Swift/Mime/ParameterizedHeader.php | 34 - .../Swift/Mime/SimpleHeaderFactory.php | 193 - .../classes/Swift/Mime/SimpleHeaderSet.php | 414 -- .../classes/Swift/Mime/SimpleMessage.php | 649 -- .../classes/Swift/Mime/SimpleMimeEntity.php | 843 --- lib/SwiftMailer/classes/Swift/MimePart.php | 59 - .../classes/Swift/NullTransport.php | 39 - .../classes/Swift/OutputByteStream.php | 46 - .../classes/Swift/Plugins/AntiFloodPlugin.php | 141 - .../Swift/Plugins/BandwidthMonitorPlugin.php | 164 - .../Swift/Plugins/Decorator/Replacements.php | 31 - .../classes/Swift/Plugins/DecoratorPlugin.php | 204 - .../Swift/Plugins/ImpersonatePlugin.php | 69 - .../classes/Swift/Plugins/Logger.php | 36 - .../classes/Swift/Plugins/LoggerPlugin.php | 142 - .../Swift/Plugins/Loggers/ArrayLogger.php | 72 - .../Swift/Plugins/Loggers/EchoLogger.php | 58 - .../classes/Swift/Plugins/MessageLogger.php | 74 - .../Swift/Plugins/Pop/Pop3Connection.php | 31 - .../Swift/Plugins/Pop/Pop3Exception.php | 27 - .../Swift/Plugins/PopBeforeSmtpPlugin.php | 273 - .../Swift/Plugins/RedirectingPlugin.php | 213 - .../classes/Swift/Plugins/Reporter.php | 32 - .../classes/Swift/Plugins/ReporterPlugin.php | 61 - .../Swift/Plugins/Reporters/HitReporter.php | 59 - .../Swift/Plugins/Reporters/HtmlReporter.php | 39 - .../classes/Swift/Plugins/Sleeper.php | 24 - .../classes/Swift/Plugins/ThrottlerPlugin.php | 200 - .../classes/Swift/Plugins/Timer.php | 24 - lib/SwiftMailer/classes/Swift/Preferences.php | 103 - .../Swift/ReplacementFilterFactory.php | 27 - .../classes/Swift/RfcComplianceException.php | 27 - .../classes/Swift/SendmailTransport.php | 45 - .../classes/Swift/SignedMessage.php | 23 - lib/SwiftMailer/classes/Swift/Signer.php | 20 - .../classes/Swift/Signers/BodySigner.php | 33 - .../classes/Swift/Signers/DKIMSigner.php | 698 -- .../classes/Swift/Signers/DomainKeySigner.php | 525 -- .../classes/Swift/Signers/HeaderSigner.php | 65 - .../classes/Swift/Signers/OpenDKIMSigner.php | 190 - .../classes/Swift/Signers/SMimeSigner.php | 436 -- .../classes/Swift/SmtpTransport.php | 58 - lib/SwiftMailer/classes/Swift/Spool.php | 53 - .../classes/Swift/SpoolTransport.php | 47 - .../classes/Swift/StreamFilter.php | 35 - .../ByteArrayReplacementFilter.php | 170 - .../StreamFilters/StringReplacementFilter.php | 66 - .../StringReplacementFilterFactory.php | 45 - .../classes/Swift/SwiftException.php | 29 - lib/SwiftMailer/classes/Swift/Transport.php | 54 - .../Swift/Transport/AbstractSmtpTransport.php | 496 -- .../Esmtp/Auth/CramMd5Authenticator.php | 81 - .../Esmtp/Auth/LoginAuthenticator.php | 51 - .../Esmtp/Auth/NTLMAuthenticator.php | 720 -- .../Esmtp/Auth/PlainAuthenticator.php | 50 - .../Esmtp/Auth/XOAuth2Authenticator.php | 70 - .../Swift/Transport/Esmtp/AuthHandler.php | 263 - .../Swift/Transport/Esmtp/Authenticator.php | 35 - .../classes/Swift/Transport/EsmtpHandler.php | 86 - .../Swift/Transport/EsmtpTransport.php | 413 -- .../Swift/Transport/FailoverTransport.php | 88 - .../classes/Swift/Transport/IoBuffer.php | 67 - .../Swift/Transport/LoadBalancedTransport.php | 183 - .../classes/Swift/Transport/MailInvoker.php | 32 - .../classes/Swift/Transport/MailTransport.php | 257 - .../classes/Swift/Transport/NullTransport.php | 93 - .../Swift/Transport/SendmailTransport.php | 160 - .../Swift/Transport/SimpleMailInvoker.php | 39 - .../classes/Swift/Transport/SmtpAgent.php | 36 - .../Swift/Transport/SpoolTransport.php | 117 - .../classes/Swift/Transport/StreamBuffer.php | 334 - .../classes/Swift/TransportException.php | 29 - lib/SwiftMailer/classes/Swift/Validate.php | 43 - .../dependency_maps/cache_deps.php | 23 - .../dependency_maps/message_deps.php | 9 - lib/SwiftMailer/dependency_maps/mime_deps.php | 123 - .../dependency_maps/transport_deps.php | 76 - lib/SwiftMailer/mime_types.php | 1007 --- lib/SwiftMailer/preferences.php | 25 - lib/SwiftMailer/swift_init.php | 28 - lib/SwiftMailer/swift_required.php | 30 - lib/SwiftMailer/swift_required_pear.php | 30 - .../swiftmailer_generate_mimes_config.php | 193 - lib/SwiftMailer/version.txt | 1 - lib/SymfonyMailer/composer.json | 5 + lib/SymfonyMailer/composer.lock | 1055 +++ lib/SymfonyMailer/vendor/autoload.php | 22 + .../vendor/composer/ClassLoader.php | 579 ++ .../vendor/composer/InstalledVersions.php | 396 ++ lib/SymfonyMailer/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 11 + .../vendor/composer/autoload_files.php | 13 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 22 + .../vendor/composer/autoload_real.php | 50 + .../vendor/composer/autoload_static.php | 113 + .../vendor/composer/installed.json | 1084 ++++ .../vendor/composer/installed.php | 161 + .../vendor/composer/platform_check.php | 26 + .../vendor/doctrine/lexer/LICENSE | 19 + .../vendor/doctrine/lexer/README.md | 9 + .../vendor/doctrine/lexer/UPGRADE.md | 22 + .../vendor/doctrine/lexer/composer.json | 55 + .../doctrine/lexer/src/AbstractLexer.php | 328 + .../vendor/doctrine/lexer/src/Token.php | 56 + .../egulias/email-validator/CONTRIBUTING.md | 153 + .../vendor/egulias/email-validator/LICENSE | 19 + .../egulias/email-validator/composer.json | 37 + .../email-validator/src/EmailLexer.php | 329 + .../email-validator/src/EmailParser.php | 90 + .../email-validator/src/EmailValidator.php | 67 + .../email-validator/src/MessageIDParser.php | 91 + .../egulias/email-validator/src/Parser.php | 78 + .../email-validator/src/Parser/Comment.php | 102 + .../CommentStrategy/CommentStrategy.php | 22 + .../Parser/CommentStrategy/DomainComment.php | 33 + .../Parser/CommentStrategy/LocalComment.php | 38 + .../src/Parser/DomainLiteral.php | 210 + .../email-validator/src/Parser/DomainPart.php | 327 + .../src/Parser/DoubleQuote.php | 91 + .../src/Parser/FoldingWhiteSpace.php | 87 + .../email-validator/src/Parser/IDLeftPart.php | 15 + .../src/Parser/IDRightPart.php | 29 + .../email-validator/src/Parser/LocalPart.php | 163 + .../email-validator/src/Parser/PartParser.php | 63 + .../src/Result/InvalidEmail.php | 49 + .../src/Result/MultipleErrors.php | 56 + .../src/Result/Reason/AtextAfterCFWS.php | 16 + .../src/Result/Reason/CRLFAtTheEnd.php | 19 + .../src/Result/Reason/CRLFX2.php | 16 + .../src/Result/Reason/CRNoLF.php | 16 + .../src/Result/Reason/CharNotAllowed.php | 16 + .../src/Result/Reason/CommaInDomain.php | 16 + .../src/Result/Reason/CommentsInIDRight.php | 16 + .../src/Result/Reason/ConsecutiveAt.php | 17 + .../src/Result/Reason/ConsecutiveDot.php | 16 + .../src/Result/Reason/DetailedReason.php | 13 + .../src/Result/Reason/DomainAcceptsNoMail.php | 16 + .../src/Result/Reason/DomainHyphened.php | 16 + .../src/Result/Reason/DomainTooLong.php | 16 + .../src/Result/Reason/DotAtEnd.php | 16 + .../src/Result/Reason/DotAtStart.php | 16 + .../src/Result/Reason/EmptyReason.php | 16 + .../src/Result/Reason/ExceptionFound.php | 26 + .../src/Result/Reason/ExpectingATEXT.php | 16 + .../src/Result/Reason/ExpectingCTEXT.php | 16 + .../src/Result/Reason/ExpectingDTEXT.php | 16 + .../Reason/ExpectingDomainLiteralClose.php | 16 + .../src/Result/Reason/LabelTooLong.php | 16 + .../Result/Reason/LocalOrReservedDomain.php | 16 + .../src/Result/Reason/NoDNSRecord.php | 16 + .../src/Result/Reason/NoDomainPart.php | 16 + .../src/Result/Reason/NoLocalPart.php | 16 + .../src/Result/Reason/RFCWarnings.php | 16 + .../src/Result/Reason/Reason.php | 16 + .../src/Result/Reason/SpoofEmail.php | 17 + .../src/Result/Reason/UnOpenedComment.php | 16 + .../Result/Reason/UnableToGetDNSRecord.php | 19 + .../src/Result/Reason/UnclosedComment.php | 16 + .../Result/Reason/UnclosedQuotedString.php | 16 + .../src/Result/Reason/UnusualElements.php | 26 + .../email-validator/src/Result/Result.php | 31 + .../email-validator/src/Result/SpoofEmail.php | 13 + .../email-validator/src/Result/ValidEmail.php | 27 + .../src/Validation/DNSCheckValidation.php | 211 + .../src/Validation/DNSGetRecordWrapper.php | 30 + .../src/Validation/DNSRecords.php | 27 + .../src/Validation/EmailValidation.php | 34 + .../Exception/EmptyValidationList.php | 16 + .../Validation/Extra/SpoofCheckValidation.php | 46 + .../src/Validation/MessageIDValidation.php | 55 + .../Validation/MultipleValidationWithAnd.php | 105 + .../Validation/NoRFCWarningsValidation.php | 41 + .../src/Validation/RFCValidation.php | 54 + .../src/Warning/AddressLiteral.php | 14 + .../src/Warning/CFWSNearAt.php | 13 + .../src/Warning/CFWSWithFWS.php | 13 + .../email-validator/src/Warning/Comment.php | 13 + .../src/Warning/DeprecatedComment.php | 13 + .../src/Warning/DomainLiteral.php | 14 + .../src/Warning/EmailTooLong.php | 15 + .../src/Warning/IPV6BadChar.php | 14 + .../src/Warning/IPV6ColonEnd.php | 14 + .../src/Warning/IPV6ColonStart.php | 14 + .../src/Warning/IPV6Deprecated.php | 14 + .../src/Warning/IPV6DoubleColon.php | 14 + .../src/Warning/IPV6GroupCount.php | 14 + .../src/Warning/IPV6MaxGroups.php | 14 + .../src/Warning/LocalTooLong.php | 15 + .../src/Warning/NoDNSMXRecord.php | 14 + .../src/Warning/ObsoleteDTEXT.php | 14 + .../src/Warning/QuotedPart.php | 27 + .../src/Warning/QuotedString.php | 17 + .../email-validator/src/Warning/TLD.php | 13 + .../email-validator/src/Warning/Warning.php | 53 + .../vendor/psr/container/.gitignore | 3 + .../vendor/psr/container/LICENSE | 21 + .../vendor/psr/container/README.md | 13 + .../vendor/psr/container/composer.json | 27 + .../src/ContainerExceptionInterface.php | 12 + .../psr/container/src/ContainerInterface.php | 36 + .../src/NotFoundExceptionInterface.php | 10 + .../vendor/psr/event-dispatcher/.editorconfig | 15 + .../vendor/psr/event-dispatcher/.gitignore | 2 + .../vendor/psr/event-dispatcher/LICENSE | 21 + .../vendor/psr/event-dispatcher/README.md | 6 + .../vendor/psr/event-dispatcher/composer.json | 26 + .../src/EventDispatcherInterface.php | 21 + .../src/ListenerProviderInterface.php | 19 + .../src/StoppableEventInterface.php | 26 + lib/SymfonyMailer/vendor/psr/log/LICENSE | 19 + lib/SymfonyMailer/vendor/psr/log/README.md | 58 + .../vendor/psr/log/composer.json | 26 + .../vendor/psr/log/src/AbstractLogger.php | 15 + .../psr/log/src/InvalidArgumentException.php | 7 + .../vendor/psr/log/src/LogLevel.php | 18 + .../psr/log/src/LoggerAwareInterface.php | 14 + .../vendor/psr/log/src/LoggerAwareTrait.php | 22 + .../vendor/psr/log/src/LoggerInterface.php | 98 + .../vendor/psr/log/src/LoggerTrait.php | 98 + .../vendor/psr/log/src/NullLogger.php | 26 + .../deprecation-contracts/CHANGELOG.md | 5 + .../symfony/deprecation-contracts/LICENSE | 19 + .../symfony/deprecation-contracts/README.md | 26 + .../deprecation-contracts/composer.json | 35 + .../deprecation-contracts/function.php | 27 + .../event-dispatcher-contracts/CHANGELOG.md | 5 + .../event-dispatcher-contracts/Event.php | 51 + .../EventDispatcherInterface.php | 33 + .../event-dispatcher-contracts/LICENSE | 19 + .../event-dispatcher-contracts/README.md | 9 + .../event-dispatcher-contracts/composer.json | 35 + .../Attribute/AsEventListener.php | 35 + .../symfony/event-dispatcher/CHANGELOG.md | 96 + .../Debug/TraceableEventDispatcher.php | 355 + .../Debug/WrappedListener.php | 143 + .../AddEventAliasesPass.php | 38 + .../RegisterListenersPass.php | 213 + .../event-dispatcher/EventDispatcher.php | 256 + .../EventDispatcherInterface.php | 66 + .../EventSubscriberInterface.php | 49 + .../symfony/event-dispatcher/GenericEvent.php | 155 + .../ImmutableEventDispatcher.php | 65 + .../vendor/symfony/event-dispatcher/LICENSE | 19 + .../vendor/symfony/event-dispatcher/README.md | 15 + .../symfony/event-dispatcher/composer.json | 47 + .../vendor/symfony/mailer/CHANGELOG.md | 130 + .../mailer/Command/MailerTestCommand.php | 73 + .../DataCollector/MessageDataCollector.php | 59 + .../vendor/symfony/mailer/DelayedEnvelope.php | 97 + .../vendor/symfony/mailer/Envelope.php | 117 + .../mailer/Event/FailedMessageEvent.php | 37 + .../symfony/mailer/Event/MessageEvent.php | 101 + .../symfony/mailer/Event/MessageEvents.php | 74 + .../symfony/mailer/Event/SentMessageEvent.php | 30 + .../DkimSignedMessageListener.php | 46 + .../mailer/EventListener/EnvelopeListener.php | 96 + .../mailer/EventListener/MessageListener.php | 133 + .../EventListener/MessageLoggerListener.php | 59 + .../MessengerTransportListener.php | 49 + .../SmimeCertificateRepositoryInterface.php | 25 + .../SmimeEncryptedMessageListener.php | 64 + .../SmimeSignedMessageListener.php | 47 + .../mailer/Exception/ExceptionInterface.php | 21 + .../Exception/HttpTransportException.php | 34 + .../Exception/IncompleteDsnException.php | 19 + .../Exception/InvalidArgumentException.php | 19 + .../mailer/Exception/LogicException.php | 19 + .../mailer/Exception/RuntimeException.php | 19 + .../mailer/Exception/TransportException.php | 30 + .../Exception/TransportExceptionInterface.php | 22 + .../Exception/UnexpectedResponseException.php | 16 + .../Exception/UnsupportedSchemeException.php | 121 + .../symfony/mailer/Header/MetadataHeader.php | 32 + .../symfony/mailer/Header/TagHeader.php | 25 + .../vendor/symfony/mailer/LICENSE | 19 + .../vendor/symfony/mailer/Mailer.php | 72 + .../vendor/symfony/mailer/MailerInterface.php | 30 + .../mailer/Messenger/MessageHandler.php | 31 + .../mailer/Messenger/SendEmailMessage.php | 37 + .../vendor/symfony/mailer/README.md | 87 + .../vendor/symfony/mailer/SentMessage.php | 95 + .../Test/AbstractTransportFactoryTestCase.php | 83 + .../mailer/Test/Constraint/EmailCount.php | 61 + .../mailer/Test/Constraint/EmailIsQueued.php | 39 + .../mailer/Test/IncompleteDsnTestTrait.php | 36 + .../mailer/Test/TransportFactoryTestCase.php | 64 + .../vendor/symfony/mailer/Transport.php | 201 + .../mailer/Transport/AbstractApiTransport.php | 47 + .../Transport/AbstractHttpTransport.php | 79 + .../mailer/Transport/AbstractTransport.php | 136 + .../Transport/AbstractTransportFactory.php | 47 + .../vendor/symfony/mailer/Transport/Dsn.php | 87 + .../mailer/Transport/FailoverTransport.php | 41 + .../Transport/NativeTransportFactory.php | 63 + .../mailer/Transport/NullTransport.php | 31 + .../mailer/Transport/NullTransportFactory.php | 34 + .../mailer/Transport/RoundRobinTransport.php | 123 + .../mailer/Transport/SendmailTransport.php | 124 + .../Transport/SendmailTransportFactory.php | 34 + .../Smtp/Auth/AuthenticatorInterface.php | 35 + .../Smtp/Auth/CramMd5Authenticator.php | 64 + .../Smtp/Auth/LoginAuthenticator.php | 37 + .../Smtp/Auth/PlainAuthenticator.php | 35 + .../Smtp/Auth/XOAuth2Authenticator.php | 37 + .../mailer/Transport/Smtp/EsmtpTransport.php | 271 + .../Transport/Smtp/EsmtpTransportFactory.php | 89 + .../mailer/Transport/Smtp/SmtpTransport.php | 393 ++ .../Transport/Smtp/Stream/AbstractStream.php | 145 + .../Transport/Smtp/Stream/ProcessStream.php | 81 + .../Transport/Smtp/Stream/SocketStream.php | 193 + .../Transport/TransportFactoryInterface.php | 29 + .../mailer/Transport/TransportInterface.php | 33 + .../symfony/mailer/Transport/Transports.php | 75 + .../vendor/symfony/mailer/composer.json | 47 + .../vendor/symfony/mime/Address.php | 140 + .../symfony/mime/BodyRendererInterface.php | 20 + .../vendor/symfony/mime/CHANGELOG.md | 57 + .../vendor/symfony/mime/CharacterStream.php | 211 + .../symfony/mime/Crypto/DkimOptions.php | 97 + .../vendor/symfony/mime/Crypto/DkimSigner.php | 217 + .../vendor/symfony/mime/Crypto/SMime.php | 111 + .../symfony/mime/Crypto/SMimeEncrypter.php | 63 + .../symfony/mime/Crypto/SMimeSigner.php | 65 + .../AddMimeTypeGuesserPass.php | 34 + .../vendor/symfony/mime/DraftEmail.php | 45 + .../vendor/symfony/mime/Email.php | 576 ++ .../mime/Encoder/AddressEncoderInterface.php | 28 + .../mime/Encoder/Base64ContentEncoder.php | 45 + .../symfony/mime/Encoder/Base64Encoder.php | 41 + .../mime/Encoder/Base64MimeHeaderEncoder.php | 43 + .../mime/Encoder/ContentEncoderInterface.php | 30 + .../mime/Encoder/EightBitContentEncoder.php | 35 + .../symfony/mime/Encoder/EncoderInterface.php | 26 + .../mime/Encoder/IdnAddressEncoder.php | 44 + .../Encoder/MimeHeaderEncoderInterface.php} | 15 +- .../symfony/mime/Encoder/QpContentEncoder.php | 55 + .../symfony/mime}/Encoder/QpEncoder.php | 188 +- .../mime/Encoder/QpMimeHeaderEncoder.php | 40 + .../symfony/mime/Encoder/Rfc2231Encoder.php | 50 + .../Exception/AddressEncoderException.php | 19 + .../mime/Exception/ExceptionInterface.php | 19 + .../Exception/InvalidArgumentException.php | 19 + .../symfony/mime/Exception/LogicException.php | 19 + .../mime/Exception/RfcComplianceException.php | 19 + .../mime/Exception/RuntimeException.php | 19 + .../mime/FileBinaryMimeTypeGuesser.php | 85 + .../symfony/mime/FileinfoMimeTypeGuesser.php | 69 + .../symfony/mime/Header/AbstractHeader.php | 294 + .../vendor/symfony/mime/Header/DateHeader.php | 62 + .../symfony/mime/Header/HeaderInterface.php | 61 + .../vendor/symfony/mime/Header/Headers.php | 316 + .../mime/Header/IdentificationHeader.php | 107 + .../symfony/mime/Header/MailboxHeader.php | 85 + .../symfony/mime/Header/MailboxListHeader.php | 136 + .../mime/Header/ParameterizedHeader.php | 191 + .../vendor/symfony/mime/Header/PathHeader.php | 62 + .../mime/Header/UnstructuredHeader.php | 66 + .../DefaultHtmlToTextConverter.php | 23 + .../HtmlToTextConverterInterface.php | 25 + .../LeagueHtmlToMarkdownConverter.php | 35 + lib/SymfonyMailer/vendor/symfony/mime/LICENSE | 19 + .../vendor/symfony/mime/Message.php | 163 + .../vendor/symfony/mime/MessageConverter.php | 122 + .../symfony/mime/MimeTypeGuesserInterface.php | 33 + .../vendor/symfony/mime/MimeTypes.php | 3789 +++++++++++ .../symfony/mime/MimeTypesInterface.php | 32 + .../mime/Part/AbstractMultipartPart.php | 95 + .../vendor/symfony/mime/Part/AbstractPart.php | 65 + .../vendor/symfony/mime/Part/DataPart.php | 165 + .../vendor/symfony/mime/Part/File.php | 51 + .../vendor/symfony/mime/Part/MessagePart.php | 71 + .../mime/Part/Multipart/AlternativePart.php | 25 + .../mime/Part/Multipart/DigestPart.php | 31 + .../mime/Part/Multipart/FormDataPart.php | 104 + .../symfony/mime/Part/Multipart/MixedPart.php | 25 + .../mime/Part/Multipart/RelatedPart.php | 55 + .../vendor/symfony/mime/Part/SMimePart.php | 105 + .../vendor/symfony/mime/Part/TextPart.php | 260 + .../vendor/symfony/mime/README.md | 13 + .../vendor/symfony/mime/RawMessage.php | 110 + .../Test/Constraint/EmailAddressContains.php | 64 + .../Test/Constraint/EmailAttachmentCount.php | 49 + .../mime/Test/Constraint/EmailHasHeader.php | 48 + .../mime/Test/Constraint/EmailHeaderSame.php | 59 + .../Test/Constraint/EmailHtmlBodyContains.php | 49 + .../Test/Constraint/EmailSubjectContains.php | 47 + .../Test/Constraint/EmailTextBodyContains.php | 49 + .../vendor/symfony/mime/composer.json | 47 + .../vendor/symfony/polyfill-intl-idn/Idn.php | 941 +++ .../vendor/symfony/polyfill-intl-idn/Info.php | 23 + .../vendor/symfony/polyfill-intl-idn/LICENSE | 19 + .../symfony/polyfill-intl-idn/README.md | 12 + .../Resources/unidata/DisallowedRanges.php | 384 ++ .../Resources/unidata/Regex.php | 33 + .../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 | 145 + .../symfony/polyfill-intl-idn/bootstrap80.php | 125 + .../symfony/polyfill-intl-idn/composer.json | 40 + .../symfony/polyfill-intl-normalizer/LICENSE | 19 + .../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 + .../polyfill-intl-normalizer/composer.json | 36 + .../vendor/symfony/polyfill-mbstring/LICENSE | 19 + .../symfony/polyfill-mbstring/Mbstring.php | 1045 +++ .../symfony/polyfill-mbstring/README.md | 13 + .../Resources/unidata/caseFolding.php | 119 + .../Resources/unidata/lowerCase.php | 1397 ++++ .../Resources/unidata/titleCaseRegexp.php | 5 + .../Resources/unidata/upperCase.php | 1489 +++++ .../symfony/polyfill-mbstring/bootstrap.php | 172 + .../symfony/polyfill-mbstring/bootstrap80.php | 167 + .../symfony/polyfill-mbstring/composer.json | 39 + .../service-contracts/Attribute/Required.php | 25 + .../Attribute/SubscribedService.php | 47 + .../symfony/service-contracts/CHANGELOG.md | 5 + .../vendor/symfony/service-contracts/LICENSE | 19 + .../symfony/service-contracts/README.md | 9 + .../service-contracts/ResetInterface.php | 33 + .../ServiceCollectionInterface.php | 26 + .../service-contracts/ServiceLocatorTrait.php | 114 + .../ServiceMethodsSubscriberTrait.php | 80 + .../ServiceProviderInterface.php | 45 + .../ServiceSubscriberInterface.php | 62 + .../ServiceSubscriberTrait.php | 84 + .../Test/ServiceLocatorTest.php | 23 + .../Test/ServiceLocatorTestCase.php | 97 + .../symfony/service-contracts/composer.json | 42 + 532 files changed, 49146 insertions(+), 22331 deletions(-) delete mode 100644 lib/SwiftMailer/classes/Swift.php delete mode 100644 lib/SwiftMailer/classes/Swift/Attachment.php delete mode 100644 lib/SwiftMailer/classes/Swift/ByteStream/AbstractFilterableInputStream.php delete mode 100644 lib/SwiftMailer/classes/Swift/ByteStream/ArrayByteStream.php delete mode 100644 lib/SwiftMailer/classes/Swift/ByteStream/FileByteStream.php delete mode 100644 lib/SwiftMailer/classes/Swift/ByteStream/TemporaryFileByteStream.php delete mode 100644 lib/SwiftMailer/classes/Swift/CharacterReader.php delete mode 100644 lib/SwiftMailer/classes/Swift/CharacterReader/GenericFixedWidthReader.php delete mode 100644 lib/SwiftMailer/classes/Swift/CharacterReader/UsAsciiReader.php delete mode 100644 lib/SwiftMailer/classes/Swift/CharacterReader/Utf8Reader.php delete mode 100644 lib/SwiftMailer/classes/Swift/CharacterReaderFactory.php delete mode 100644 lib/SwiftMailer/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php delete mode 100644 lib/SwiftMailer/classes/Swift/CharacterStream.php delete mode 100644 lib/SwiftMailer/classes/Swift/CharacterStream/ArrayCharacterStream.php delete mode 100644 lib/SwiftMailer/classes/Swift/CharacterStream/NgCharacterStream.php delete mode 100644 lib/SwiftMailer/classes/Swift/ConfigurableSpool.php delete mode 100644 lib/SwiftMailer/classes/Swift/DependencyContainer.php delete mode 100644 lib/SwiftMailer/classes/Swift/DependencyException.php delete mode 100644 lib/SwiftMailer/classes/Swift/EmbeddedFile.php delete mode 100644 lib/SwiftMailer/classes/Swift/Encoder.php delete mode 100644 lib/SwiftMailer/classes/Swift/Encoder/Base64Encoder.php delete mode 100644 lib/SwiftMailer/classes/Swift/Encoder/Rfc2231Encoder.php delete mode 100644 lib/SwiftMailer/classes/Swift/Encoding.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/CommandEvent.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/CommandListener.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/Event.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/EventDispatcher.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/EventListener.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/EventObject.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/ResponseEvent.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/ResponseListener.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/SendEvent.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/SendListener.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/SimpleEventDispatcher.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/TransportChangeEvent.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/TransportChangeListener.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/TransportExceptionEvent.php delete mode 100644 lib/SwiftMailer/classes/Swift/Events/TransportExceptionListener.php delete mode 100644 lib/SwiftMailer/classes/Swift/FailoverTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/FileSpool.php delete mode 100644 lib/SwiftMailer/classes/Swift/FileStream.php delete mode 100644 lib/SwiftMailer/classes/Swift/Filterable.php delete mode 100644 lib/SwiftMailer/classes/Swift/Image.php delete mode 100644 lib/SwiftMailer/classes/Swift/InputByteStream.php delete mode 100644 lib/SwiftMailer/classes/Swift/IoException.php delete mode 100644 lib/SwiftMailer/classes/Swift/KeyCache.php delete mode 100644 lib/SwiftMailer/classes/Swift/KeyCache/ArrayKeyCache.php delete mode 100644 lib/SwiftMailer/classes/Swift/KeyCache/DiskKeyCache.php delete mode 100644 lib/SwiftMailer/classes/Swift/KeyCache/KeyCacheInputStream.php delete mode 100644 lib/SwiftMailer/classes/Swift/KeyCache/NullKeyCache.php delete mode 100644 lib/SwiftMailer/classes/Swift/KeyCache/SimpleKeyCacheInputStream.php delete mode 100644 lib/SwiftMailer/classes/Swift/LoadBalancedTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/MailTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mailer.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mailer/ArrayRecipientIterator.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mailer/RecipientIterator.php delete mode 100644 lib/SwiftMailer/classes/Swift/MemorySpool.php delete mode 100644 lib/SwiftMailer/classes/Swift/Message.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/Attachment.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/CharsetObserver.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/ContentEncoder.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/RawContentEncoder.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/EmbeddedFile.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/EncodingObserver.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/Grammar.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/Header.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/HeaderEncoder/Base64HeaderEncoder.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/HeaderFactory.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/HeaderSet.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/Headers/AbstractHeader.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/Headers/DateHeader.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/Headers/IdentificationHeader.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/Headers/OpenDKIMHeader.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/Headers/ParameterizedHeader.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/Headers/PathHeader.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/Headers/UnstructuredHeader.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/Message.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/MimeEntity.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/MimePart.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/ParameterizedHeader.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/SimpleHeaderFactory.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/SimpleHeaderSet.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/SimpleMessage.php delete mode 100644 lib/SwiftMailer/classes/Swift/Mime/SimpleMimeEntity.php delete mode 100644 lib/SwiftMailer/classes/Swift/MimePart.php delete mode 100644 lib/SwiftMailer/classes/Swift/NullTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/OutputByteStream.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/AntiFloodPlugin.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/BandwidthMonitorPlugin.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/Decorator/Replacements.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/DecoratorPlugin.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/ImpersonatePlugin.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/Logger.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/LoggerPlugin.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/Loggers/ArrayLogger.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/Loggers/EchoLogger.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/MessageLogger.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/Pop/Pop3Connection.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/Pop/Pop3Exception.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/PopBeforeSmtpPlugin.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/RedirectingPlugin.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/Reporter.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/ReporterPlugin.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/Reporters/HitReporter.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/Reporters/HtmlReporter.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/Sleeper.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/ThrottlerPlugin.php delete mode 100644 lib/SwiftMailer/classes/Swift/Plugins/Timer.php delete mode 100644 lib/SwiftMailer/classes/Swift/Preferences.php delete mode 100644 lib/SwiftMailer/classes/Swift/ReplacementFilterFactory.php delete mode 100644 lib/SwiftMailer/classes/Swift/RfcComplianceException.php delete mode 100644 lib/SwiftMailer/classes/Swift/SendmailTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/SignedMessage.php delete mode 100644 lib/SwiftMailer/classes/Swift/Signer.php delete mode 100644 lib/SwiftMailer/classes/Swift/Signers/BodySigner.php delete mode 100644 lib/SwiftMailer/classes/Swift/Signers/DKIMSigner.php delete mode 100644 lib/SwiftMailer/classes/Swift/Signers/DomainKeySigner.php delete mode 100644 lib/SwiftMailer/classes/Swift/Signers/HeaderSigner.php delete mode 100644 lib/SwiftMailer/classes/Swift/Signers/OpenDKIMSigner.php delete mode 100644 lib/SwiftMailer/classes/Swift/Signers/SMimeSigner.php delete mode 100644 lib/SwiftMailer/classes/Swift/SmtpTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/Spool.php delete mode 100644 lib/SwiftMailer/classes/Swift/SpoolTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/StreamFilter.php delete mode 100644 lib/SwiftMailer/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php delete mode 100644 lib/SwiftMailer/classes/Swift/StreamFilters/StringReplacementFilter.php delete mode 100644 lib/SwiftMailer/classes/Swift/StreamFilters/StringReplacementFilterFactory.php delete mode 100644 lib/SwiftMailer/classes/Swift/SwiftException.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/AbstractSmtpTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/XOAuth2Authenticator.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/Esmtp/AuthHandler.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/Esmtp/Authenticator.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/EsmtpHandler.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/EsmtpTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/FailoverTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/IoBuffer.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/LoadBalancedTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/MailInvoker.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/MailTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/NullTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/SendmailTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/SimpleMailInvoker.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/SmtpAgent.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/SpoolTransport.php delete mode 100644 lib/SwiftMailer/classes/Swift/Transport/StreamBuffer.php delete mode 100644 lib/SwiftMailer/classes/Swift/TransportException.php delete mode 100644 lib/SwiftMailer/classes/Swift/Validate.php delete mode 100644 lib/SwiftMailer/dependency_maps/cache_deps.php delete mode 100644 lib/SwiftMailer/dependency_maps/message_deps.php delete mode 100644 lib/SwiftMailer/dependency_maps/mime_deps.php delete mode 100644 lib/SwiftMailer/dependency_maps/transport_deps.php delete mode 100644 lib/SwiftMailer/mime_types.php delete mode 100644 lib/SwiftMailer/preferences.php delete mode 100644 lib/SwiftMailer/swift_init.php delete mode 100644 lib/SwiftMailer/swift_required.php delete mode 100644 lib/SwiftMailer/swift_required_pear.php delete mode 100644 lib/SwiftMailer/swiftmailer_generate_mimes_config.php delete mode 100644 lib/SwiftMailer/version.txt create mode 100644 lib/SymfonyMailer/composer.json create mode 100644 lib/SymfonyMailer/composer.lock create mode 100644 lib/SymfonyMailer/vendor/autoload.php create mode 100644 lib/SymfonyMailer/vendor/composer/ClassLoader.php create mode 100644 lib/SymfonyMailer/vendor/composer/InstalledVersions.php create mode 100644 lib/SymfonyMailer/vendor/composer/LICENSE create mode 100644 lib/SymfonyMailer/vendor/composer/autoload_classmap.php create mode 100644 lib/SymfonyMailer/vendor/composer/autoload_files.php create mode 100644 lib/SymfonyMailer/vendor/composer/autoload_namespaces.php create mode 100644 lib/SymfonyMailer/vendor/composer/autoload_psr4.php create mode 100644 lib/SymfonyMailer/vendor/composer/autoload_real.php create mode 100644 lib/SymfonyMailer/vendor/composer/autoload_static.php create mode 100644 lib/SymfonyMailer/vendor/composer/installed.json create mode 100644 lib/SymfonyMailer/vendor/composer/installed.php create mode 100644 lib/SymfonyMailer/vendor/composer/platform_check.php create mode 100644 lib/SymfonyMailer/vendor/doctrine/lexer/LICENSE create mode 100644 lib/SymfonyMailer/vendor/doctrine/lexer/README.md create mode 100644 lib/SymfonyMailer/vendor/doctrine/lexer/UPGRADE.md create mode 100644 lib/SymfonyMailer/vendor/doctrine/lexer/composer.json create mode 100644 lib/SymfonyMailer/vendor/doctrine/lexer/src/AbstractLexer.php create mode 100644 lib/SymfonyMailer/vendor/doctrine/lexer/src/Token.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/CONTRIBUTING.md create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/LICENSE create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/composer.json create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/EmailLexer.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/EmailParser.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/EmailValidator.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/MessageIDParser.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/Comment.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/CommentStrategy/CommentStrategy.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/CommentStrategy/DomainComment.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/CommentStrategy/LocalComment.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/DomainLiteral.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/DomainPart.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/DoubleQuote.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/FoldingWhiteSpace.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/IDLeftPart.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/IDRightPart.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/LocalPart.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/PartParser.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/InvalidEmail.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/MultipleErrors.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/AtextAfterCFWS.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/CRLFAtTheEnd.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/CRLFX2.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/CRNoLF.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/CharNotAllowed.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/CommaInDomain.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/CommentsInIDRight.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/ConsecutiveAt.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/ConsecutiveDot.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/DetailedReason.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/DomainAcceptsNoMail.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/DomainHyphened.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/DomainTooLong.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/DotAtEnd.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/DotAtStart.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/EmptyReason.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/ExceptionFound.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/ExpectingATEXT.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/ExpectingCTEXT.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/ExpectingDTEXT.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/ExpectingDomainLiteralClose.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/LabelTooLong.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/LocalOrReservedDomain.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/NoDNSRecord.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/NoDomainPart.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/NoLocalPart.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/RFCWarnings.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/Reason.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/SpoofEmail.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/UnOpenedComment.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/UnableToGetDNSRecord.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/UnclosedComment.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/UnclosedQuotedString.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/UnusualElements.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Result.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/SpoofEmail.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/ValidEmail.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/DNSCheckValidation.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/DNSGetRecordWrapper.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/DNSRecords.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/EmailValidation.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/Exception/EmptyValidationList.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/Extra/SpoofCheckValidation.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/MessageIDValidation.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/RFCValidation.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/AddressLiteral.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/CFWSNearAt.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/CFWSWithFWS.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/Comment.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/DeprecatedComment.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/DomainLiteral.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/EmailTooLong.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6BadChar.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6ColonEnd.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6ColonStart.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6Deprecated.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6DoubleColon.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6GroupCount.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6MaxGroups.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/LocalTooLong.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/NoDNSMXRecord.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/ObsoleteDTEXT.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/QuotedPart.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/QuotedString.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/TLD.php create mode 100644 lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/Warning.php create mode 100644 lib/SymfonyMailer/vendor/psr/container/.gitignore create mode 100644 lib/SymfonyMailer/vendor/psr/container/LICENSE create mode 100644 lib/SymfonyMailer/vendor/psr/container/README.md create mode 100644 lib/SymfonyMailer/vendor/psr/container/composer.json create mode 100644 lib/SymfonyMailer/vendor/psr/container/src/ContainerExceptionInterface.php create mode 100644 lib/SymfonyMailer/vendor/psr/container/src/ContainerInterface.php create mode 100644 lib/SymfonyMailer/vendor/psr/container/src/NotFoundExceptionInterface.php create mode 100644 lib/SymfonyMailer/vendor/psr/event-dispatcher/.editorconfig create mode 100644 lib/SymfonyMailer/vendor/psr/event-dispatcher/.gitignore create mode 100644 lib/SymfonyMailer/vendor/psr/event-dispatcher/LICENSE create mode 100644 lib/SymfonyMailer/vendor/psr/event-dispatcher/README.md create mode 100644 lib/SymfonyMailer/vendor/psr/event-dispatcher/composer.json create mode 100644 lib/SymfonyMailer/vendor/psr/event-dispatcher/src/EventDispatcherInterface.php create mode 100644 lib/SymfonyMailer/vendor/psr/event-dispatcher/src/ListenerProviderInterface.php create mode 100644 lib/SymfonyMailer/vendor/psr/event-dispatcher/src/StoppableEventInterface.php create mode 100644 lib/SymfonyMailer/vendor/psr/log/LICENSE create mode 100644 lib/SymfonyMailer/vendor/psr/log/README.md create mode 100644 lib/SymfonyMailer/vendor/psr/log/composer.json create mode 100644 lib/SymfonyMailer/vendor/psr/log/src/AbstractLogger.php create mode 100644 lib/SymfonyMailer/vendor/psr/log/src/InvalidArgumentException.php create mode 100644 lib/SymfonyMailer/vendor/psr/log/src/LogLevel.php create mode 100644 lib/SymfonyMailer/vendor/psr/log/src/LoggerAwareInterface.php create mode 100644 lib/SymfonyMailer/vendor/psr/log/src/LoggerAwareTrait.php create mode 100644 lib/SymfonyMailer/vendor/psr/log/src/LoggerInterface.php create mode 100644 lib/SymfonyMailer/vendor/psr/log/src/LoggerTrait.php create mode 100644 lib/SymfonyMailer/vendor/psr/log/src/NullLogger.php create mode 100644 lib/SymfonyMailer/vendor/symfony/deprecation-contracts/CHANGELOG.md create mode 100644 lib/SymfonyMailer/vendor/symfony/deprecation-contracts/LICENSE create mode 100644 lib/SymfonyMailer/vendor/symfony/deprecation-contracts/README.md create mode 100644 lib/SymfonyMailer/vendor/symfony/deprecation-contracts/composer.json create mode 100644 lib/SymfonyMailer/vendor/symfony/deprecation-contracts/function.php create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/CHANGELOG.md create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/Event.php create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/EventDispatcherInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/LICENSE create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/README.md create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/composer.json create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/Attribute/AsEventListener.php create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/CHANGELOG.md create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/Debug/WrappedListener.php create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/DependencyInjection/AddEventAliasesPass.php create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/EventDispatcher.php create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/EventDispatcherInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/EventSubscriberInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/GenericEvent.php create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/LICENSE create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/README.md create mode 100644 lib/SymfonyMailer/vendor/symfony/event-dispatcher/composer.json create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/CHANGELOG.md create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Command/MailerTestCommand.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/DataCollector/MessageDataCollector.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/DelayedEnvelope.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Envelope.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Event/FailedMessageEvent.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Event/MessageEvent.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Event/MessageEvents.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Event/SentMessageEvent.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/EventListener/DkimSignedMessageListener.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/EventListener/EnvelopeListener.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/EventListener/MessageListener.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/EventListener/MessageLoggerListener.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/EventListener/MessengerTransportListener.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/EventListener/SmimeCertificateRepositoryInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/EventListener/SmimeEncryptedMessageListener.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/EventListener/SmimeSignedMessageListener.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Exception/ExceptionInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Exception/HttpTransportException.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Exception/IncompleteDsnException.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Exception/InvalidArgumentException.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Exception/LogicException.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Exception/RuntimeException.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Exception/TransportException.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Exception/TransportExceptionInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Exception/UnexpectedResponseException.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Exception/UnsupportedSchemeException.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Header/MetadataHeader.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Header/TagHeader.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/LICENSE create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Mailer.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/MailerInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Messenger/MessageHandler.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Messenger/SendEmailMessage.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/README.md create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/SentMessage.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Test/AbstractTransportFactoryTestCase.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Test/Constraint/EmailCount.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Test/Constraint/EmailIsQueued.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Test/IncompleteDsnTestTrait.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Test/TransportFactoryTestCase.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractApiTransport.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractHttpTransport.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractTransport.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractTransportFactory.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/Dsn.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/FailoverTransport.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/NativeTransportFactory.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/NullTransport.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/NullTransportFactory.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/RoundRobinTransport.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/SendmailTransport.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/SendmailTransportFactory.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/AuthenticatorInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/CramMd5Authenticator.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/LoginAuthenticator.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/PlainAuthenticator.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/XOAuth2Authenticator.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/EsmtpTransport.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/EsmtpTransportFactory.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/SmtpTransport.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Stream/AbstractStream.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Stream/ProcessStream.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Stream/SocketStream.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/TransportFactoryInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/TransportInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/Transport/Transports.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mailer/composer.json create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Address.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/BodyRendererInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/CHANGELOG.md create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/CharacterStream.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Crypto/DkimOptions.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Crypto/DkimSigner.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Crypto/SMime.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Crypto/SMimeEncrypter.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Crypto/SMimeSigner.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/DraftEmail.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Email.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Encoder/AddressEncoderInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Encoder/Base64ContentEncoder.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Encoder/Base64Encoder.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Encoder/Base64MimeHeaderEncoder.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Encoder/ContentEncoderInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Encoder/EightBitContentEncoder.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Encoder/EncoderInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Encoder/IdnAddressEncoder.php rename lib/{SwiftMailer/classes/Swift/Mime/HeaderEncoder.php => SymfonyMailer/vendor/symfony/mime/Encoder/MimeHeaderEncoderInterface.php} (52%) create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Encoder/QpContentEncoder.php rename lib/{SwiftMailer/classes/Swift => SymfonyMailer/vendor/symfony/mime}/Encoder/QpEncoder.php (55%) create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Encoder/QpMimeHeaderEncoder.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Encoder/Rfc2231Encoder.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Exception/AddressEncoderException.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Exception/ExceptionInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Exception/InvalidArgumentException.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Exception/LogicException.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Exception/RfcComplianceException.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Exception/RuntimeException.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/FileBinaryMimeTypeGuesser.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/FileinfoMimeTypeGuesser.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Header/AbstractHeader.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Header/DateHeader.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Header/HeaderInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Header/Headers.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Header/IdentificationHeader.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Header/MailboxHeader.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Header/MailboxListHeader.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Header/ParameterizedHeader.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Header/PathHeader.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Header/UnstructuredHeader.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/HtmlToTextConverter/DefaultHtmlToTextConverter.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/HtmlToTextConverter/HtmlToTextConverterInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/HtmlToTextConverter/LeagueHtmlToMarkdownConverter.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/LICENSE create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Message.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/MessageConverter.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/MimeTypeGuesserInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/MimeTypes.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/MimeTypesInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Part/AbstractMultipartPart.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Part/AbstractPart.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Part/DataPart.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Part/File.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Part/MessagePart.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/AlternativePart.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/DigestPart.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/FormDataPart.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/MixedPart.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/RelatedPart.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Part/SMimePart.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Part/TextPart.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/README.md create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/RawMessage.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailAddressContains.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailAttachmentCount.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailHasHeader.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailHeaderSame.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailHtmlBodyContains.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailSubjectContains.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailTextBodyContains.php create mode 100644 lib/SymfonyMailer/vendor/symfony/mime/composer.json create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Idn.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Info.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/LICENSE create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/README.md create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/deviation.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/ignored.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/mapped.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/virama.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/bootstrap.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/bootstrap80.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/composer.json create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/LICENSE create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Normalizer.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/README.md create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalComposition.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/bootstrap.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/composer.json create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/LICENSE create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Mbstring.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/README.md create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/bootstrap.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/bootstrap80.php create mode 100644 lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/composer.json create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/Attribute/Required.php create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/Attribute/SubscribedService.php create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/CHANGELOG.md create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/LICENSE create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/README.md create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/ResetInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceCollectionInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceLocatorTrait.php create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceMethodsSubscriberTrait.php create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceProviderInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceSubscriberInterface.php create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceSubscriberTrait.php create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/Test/ServiceLocatorTestCase.php create mode 100644 lib/SymfonyMailer/vendor/symfony/service-contracts/composer.json diff --git a/README.md b/README.md index 11cce92..41655f5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,13 @@ -### Альтернативная версия AVE.CMS v3.28 ALT +### Альтернативная версия AVE.CMS v3.29 ALT #### Основное отличие: #### Удалены оригинальные запросы. На замену им вернулись запросы из старой доброй AVE.CMS ver 2.09RC1 с полным рефакторингом кода под текущие среды и задачи. Теперь снова доступен выпадающий список в качестве панели управления условиями запроса из публичной части сайта, создавать фильтры стало как никогда легко и просто, а условия, созданные в админке, полностью работоспособны. -#### Работает в программной среде: PHP-8.4 MySQL-8.4 +#### Работает в программной среде: PHP-8.4.x MySQL-8.4.x #### Добавлена поддержка графических файлов изображений в формате .webp #### Обновлены библиотеки + +### Changelog: + +#### Версия v3.29 ALT - удален устаревший Swift Mailer, на замену ему интегрирован Symfony Mailer; +#### В Системных настройках, при выборе метода отправки почты: SMTP --> Шифрование, добавлены новые пункты: TLS (без проверки сертификата) и SSL (без проверки сертификата). Это дает возможность полноценно настраивать почту на локальном хосте. +#### + diff --git a/admin/lang/ru/settings.txt b/admin/lang/ru/settings.txt index bee7f45..f3afa1e 100644 --- a/admin/lang/ru/settings.txt +++ b/admin/lang/ru/settings.txt @@ -30,7 +30,11 @@ SETTINGS_MAIL_PORT = "Порт SMTP:" SETTINGS_SMTP_NAME = "Пользователь:" SETTINGS_SMTP_PASS = "Пароль:" SETTINGS_SMTP_ENCRYPT = "Шифрование" -SETTINGS_SMTP_NOENCRYPT = "нет" +SETTINGS_SMTP_NOENCRYPT = "Нет" +SETTINGS_SMTP_TLS_CHECK = "TLS" +SETTINGS_SMTP_TLS_NO_CHECK = "TLS (без проверки сертификата)" +SETTINGS_SMTP_SSL_CHECK = "SSL" +SETTINGS_SMTP_SSL_NO_CHECK = "SSL (без проверки сертификата)" SETTINGS_MAIL_PATH = "Путь до папки sendmail:" SETTINGS_SYMBOL_BREAK = "Принудительный перенос после (знаков):" SETTINGS_SYMBOL_BREAK_INFO = "Не более 1000 согласно RFC 2822" diff --git a/admin/templates/settings/settings_main.tpl b/admin/templates/settings/settings_main.tpl index 2265ce6..184a312 100644 --- a/admin/templates/settings/settings_main.tpl +++ b/admin/templates/settings/settings_main.tpl @@ -254,8 +254,10 @@
diff --git a/functions/func.mail.php b/functions/func.mail.php index b1ddd09..152087d 100644 --- a/functions/func.mail.php +++ b/functions/func.mail.php @@ -1,252 +1,349 @@
' . nl2br(get_settings('mail_signature')); + } + else + { + $signature = "\r\n\r\n" . get_settings('mail_signature'); + } + } + else $signature = ''; - // Добавляем подпись, если просили - if ($signature) - { - if ($type == 'text/html') - { - $signature = '

' . nl2br(get_settings('mail_signature')); - } - else - { - $signature = "\r\n\r\n" . get_settings('mail_signature'); - } - } - else $signature = ''; + // Составляем тело письма + $body = stripslashes($body) . $signature; - // Составляем тело письма - $body = stripslashes($body) . $signature; + if ($type == 'text/html') + { + $body = str_replace(array("\t","\r","\n"),'',$body); + $body = str_replace(array(' ','> <'),array(' ','><'),$body); + } - if ($type == 'text/html') - { - $body = str_replace(array("\t","\r","\n"),'',$body); - $body = str_replace(array(' ','> <'),array(' ','><'),$body); - } + // ---------------------------------------------------- + // БЛОК SYMFONY MAILER: Инициализация и настройка письма + // ---------------------------------------------------- - // Формируем письмо - $message = Swift_Message::newInstance($subject) - -> setFrom(array($from_email => $from_name)) - -> setTo($to) - -> setContentType($type) - -> setBody($body) - -> setMaxLineLength((int)get_settings('mail_word_wrap')); + $message = new Email(); + $message->getHeaders()->addTextHeader('X-Mailer', 'AVE.cms Symfony Mailer'); + $message->subject($subject); - // Прикрепляем вложения - if ($attach) - { - foreach ($attach as $attach_file) - { - $message -> attach(Swift_Attachment::fromPath(trim($attach_file))); - } - } + // Отправитель + $message->from(new Address($from_email, $from_name)); - // Выбираем метод отправки и формируем транспорт - switch (get_settings('mail_type')) - { - default: - case 'mail': - $transport = Swift_MailTransport::newInstance(); - break; + // Получатель (разбиваем строку $to на массив адресов) + $to_addresses = array_map('trim', explode(',', $to)); + $message->to(...$to_addresses); - case 'smtp': - $transport = Swift_SmtpTransport::newInstance(stripslashes(get_settings('mail_host')), (int)get_settings('mail_port')); + // Тело письма + if ($type == 'text/html') { + $message->html($body); + $message->text(strip_tags($body)); // AltBody + } else { + $message->text($body); + } - // Добавляем шифрование - $smtp_encrypt = get_settings('mail_smtp_encrypt'); - if($smtp_encrypt) - $transport - ->setEncryption(strtolower(stripslashes($smtp_encrypt))); + // ---------------------------------------------------- + // БЛОК SYMFONY MAILER: Прикрепление вложений + // ---------------------------------------------------- - // Имя пользователя/пароль - $smtp_user = get_settings('mail_smtp_login'); - $smtp_pass = get_settings('mail_smtp_pass'); - if($smtp_user) - $transport - ->setUsername(stripslashes($smtp_user)) - ->setPassword(stripslashes($smtp_pass)); - break; + if ($attach) + { + foreach ($attach as $attach_file) + { + $file_path = trim($attach_file); + if ($file_path && file_exists($file_path)) { + $message->attachFromPath($file_path); + } + } + } - case 'sendmail': - $transport = Swift_SendmailTransport::newInstance(get_settings('mail_sendmail_path')); - break; - } + // ---------------------------------------------------- + // БЛОК SYMFONY MAILER: Формирование DSN + // ---------------------------------------------------- - // Сохраняем вложения в ATTACH_DIR, если просили - if ($attach && $saveattach) - { - $attach_dir = BASE_DIR . '/tmp/' . ATTACH_DIR . '/'; - foreach ($attach as $file_path) - { - if ($file_path && file_exists($file_path)) - { - $file_name = basename($file_path); - $file_name = str_replace(' ','',mb_strtolower(trim($file_name))); - if (file_exists($attach_dir . $file_name)) - { - $file_name = rand(1000, 9999) . '_' . $file_name; - } - $file_path_new = $attach_dir . $file_name; - if (!@move_uploaded_file($file_path,$file_path_new)) - { - copy($file_path,$file_path_new); - } - } - } - } + $transport_dsn = ''; + $mail_type = get_settings('mail_type'); - // Отправляем письмо - /** @var $transport TYPE_NAME */ - $mailer = Swift_Mailer::newInstance($transport); + switch ($mail_type) { + // Резервный DSN (если выбрано что-то неизвестное) + default: + $transport_dsn = 'native://default'; + break; - if (!@$mailer -> send($message, $failures)) - { - reportLog('Не удалось отправить письма следующим адресатам: ' . implode(',',$failures)); - return $failures; - } + // МЕТОД 'mail' (Самый простой и надежный) + case 'mail': + // DSN 'sendmail://default' использует внутреннюю, стабильную функцию PHP mail(). + $transport_dsn = 'sendmail://default'; + break; - } - } + // 2. МЕТОД 'sendmail' (Использует путь из настроек, но только если он работает, проверяйте на VDS командой # systemctl status sendmail) + case 'sendmail': + $path = get_settings('mail_sendmail_path'); // Берем путь из настроек + + // DSN для прямого вызова исполняемого файла + $transport_dsn = 'sendmail://default?command=' . urlencode($path); + break; - if ( ! function_exists('safe_mailto')) - { - function safe_mailto($email, $title = '', $attributes = '') - { - $title = (string) $title; + case 'smtp': + $host = stripslashes(get_settings('mail_host')); + $port = (int)get_settings('mail_port'); + $user = stripslashes(get_settings('mail_smtp_login')); + $pass = stripslashes(get_settings('mail_smtp_pass')); + + // Получаем значение шифрования, которое теперь может быть 'tls_insecure' или 'ssl_insecure' + $encrypt_setting = strtolower(stripslashes(get_settings('mail_smtp_encrypt'))); - if ($title == "") - { - $title = $email; - } + $scheme = 'smtp'; + $encryption = ''; + $extra_params = ''; - for ($i = 0; $i < 16; $i++) - { - $x[] = substr(' $val) - { - $x[] = ' '.$key.'="'; - for ($i = 0; $i < strlen($val); $i++) - { - $x[] = "|".ord(substr($val, $i, 1)); - } - $x[] = '"'; - } - } - else - { - for ($i = 0; $i < strlen($attributes); $i++) - { - $x[] = substr($attributes, $i, 1); - } - } - } + // Сохраняем вложения в ATTACH_DIR, если просили + if ($attach && $saveattach) + { + $attach_dir = BASE_DIR . '/tmp/' . ATTACH_DIR . '/'; + foreach ($attach as $file_path) + { + if ($file_path && file_exists($file_path)) + { + $file_name = basename($file_path); + $file_name = str_replace(' ','',mb_strtolower(trim($file_name))); + if (file_exists($attach_dir . $file_name)) + { + $file_name = rand(1000, 9999) . '_' . $file_name; + } + $file_path_new = $attach_dir . $file_name; + if (!@move_uploaded_file($file_path,$file_path_new)) + { + copy($file_path,$file_path_new); + } + } + } + } - $x[] = '>'; + // ---------------------------------------------------- + // БЛОК SYMFONY MAILER: Отправка и обработка ошибок + // ---------------------------------------------------- - $temp = array(); + try { + // 1. Создаем транспорт из DSN + $transport = Transport::fromDsn($transport_dsn); - for ($i = 0; $i < strlen($title); $i++) - { - $ordinal = ord($title[$i]); + // 2. Создаем почтальона (Mailer) + $mailer = new Mailer($transport); - if ($ordinal < 128) - { - $x[] = "|".$ordinal; - } - else - { - if (count($temp) == 0) - { - $count = ($ordinal < 224) ? 2 : 3; - } + // 3. Отправляем сообщение + $mailer->send($message); - $temp[] = $ordinal; - if (count($temp) == $count) - { - $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64); - $x[] = "|".$number; - $count = 1; - $temp = array(); - } - } - } + return true; // Успех + } catch (TransportExceptionInterface $e) { + // Записываем специфические ошибки Symfony Mailer в лог + reportLog('Не удалось отправить письма. Symfony Mailer Transport Error: ' . $e->getMessage()); + return false; // Неудача + } catch (\Exception $e) { + // Общая ошибка (на всякий случай) + reportLog('Не удалось отправить письма. Symfony Mailer Fatal Error: ' . $e->getMessage()); + return false; + } + // ---------------------------------------------------- + // КОНЕЦ БЛОКА SYMFONY MAILER + // ---------------------------------------------------- - $x[] = '<'; $x[] = '/'; $x[] = 'a'; $x[] = '>'; + } + } - $x = array_reverse($x); - ob_start(); + if ( ! function_exists('safe_mailto')) + { + function safe_mailto($email, $title = '', $attributes = '') + { + $title = (string) $title; - ?> $val) + { + $x[] = ' '.$key.'="'; + for ($i = 0; $i < strlen($val); $i++) + { + $x[] = "|".ord(substr($val, $i, 1)); + } + $x[] = '"'; + } + } + else + { + for ($i = 0; $i < strlen($attributes); $i++) + { + $x[] = substr($attributes, $i, 1); + } + } + } + + $x[] = '>'; + + $temp = array(); + + for ($i = 0; $i < strlen($title); $i++) + { + $ordinal = ord($title[$i]); + + if ($ordinal < 128) + { + $x[] = "|".$ordinal; + } + else + { + if (count($temp) == 0) + { + $count = ($ordinal < 224) ? 2 : 3; + } + + $temp[] = $ordinal; + if (count($temp) == $count) + { + $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64); + $x[] = "|".$number; + $count = 1; + $temp = array(); + } + } + } + + $x[] = '<'; $x[] = '/'; $x[] = 'a'; $x[] = '>'; + + $x = array_reverse($x); + ob_start(); + + ?> \ No newline at end of file diff --git a/inc/config.php b/inc/config.php index b4f2cb1..a9ca5f3 100644 --- a/inc/config.php +++ b/inc/config.php @@ -12,7 +12,7 @@ */ define('APP_NAME', 'AVE.cms'); - define('APP_VERSION', '3.28 ALT'); + define('APP_VERSION', '3.29 ALT'); define('APP_INFO', 'Ave-Cms.Ru '.'© 2007-' . date('Y')); $themes = []; diff --git a/lib/SwiftMailer/classes/Swift.php b/lib/SwiftMailer/classes/Swift.php deleted file mode 100644 index 82c381b..0000000 --- a/lib/SwiftMailer/classes/Swift.php +++ /dev/null @@ -1,80 +0,0 @@ -createDependenciesFor('mime.attachment') - ); - - $this->setBody($data); - $this->setFilename($filename); - if ($contentType) { - $this->setContentType($contentType); - } - } - - /** - * Create a new Attachment. - * - * @param string|Swift_OutputByteStream $data - * @param string $filename - * @param string $contentType - * - * @return Swift_Mime_Attachment - */ - public static function newInstance($data = null, $filename = null, $contentType = null) - { - return new self($data, $filename, $contentType); - } - - /** - * Create a new Attachment from a filesystem path. - * - * @param string $path - * @param string $contentType optional - * - * @return Swift_Mime_Attachment - */ - public static function fromPath($path, $contentType = null) - { - return self::newInstance()->setFile( - new Swift_ByteStream_FileByteStream($path), - $contentType - ); - } -} diff --git a/lib/SwiftMailer/classes/Swift/ByteStream/AbstractFilterableInputStream.php b/lib/SwiftMailer/classes/Swift/ByteStream/AbstractFilterableInputStream.php deleted file mode 100644 index a7b0e3a..0000000 --- a/lib/SwiftMailer/classes/Swift/ByteStream/AbstractFilterableInputStream.php +++ /dev/null @@ -1,181 +0,0 @@ -_filters[$key] = $filter; - } - - /** - * Remove an already present StreamFilter based on its $key. - * - * @param string $key - */ - public function removeFilter($key) - { - unset($this->_filters[$key]); - } - - /** - * Writes $bytes to the end of the stream. - * - * @param string $bytes - * - * @throws Swift_IoException - * - * @return int - */ - public function write($bytes) - { - $this->_writeBuffer .= $bytes; - foreach ($this->_filters as $filter) { - if ($filter->shouldBuffer($this->_writeBuffer)) { - return; - } - } - $this->_doWrite($this->_writeBuffer); - - return ++$this->_sequence; - } - - /** - * For any bytes that are currently buffered inside the stream, force them - * off the buffer. - * - * @throws Swift_IoException - */ - public function commit() - { - $this->_doWrite($this->_writeBuffer); - } - - /** - * Attach $is to this stream. - * - * The stream acts as an observer, receiving all data that is written. - * All {@link write()} and {@link flushBuffers()} operations will be mirrored. - * - * @param Swift_InputByteStream $is - */ - public function bind(Swift_InputByteStream $is) - { - $this->_mirrors[] = $is; - } - - /** - * Remove an already bound stream. - * - * If $is is not bound, no errors will be raised. - * If the stream currently has any buffered data it will be written to $is - * before unbinding occurs. - * - * @param Swift_InputByteStream $is - */ - public function unbind(Swift_InputByteStream $is) - { - foreach ($this->_mirrors as $k => $stream) { - if ($is === $stream) { - if ($this->_writeBuffer !== '') { - $stream->write($this->_writeBuffer); - } - unset($this->_mirrors[$k]); - } - } - } - - /** - * Flush the contents of the stream (empty it) and set the internal pointer - * to the beginning. - * - * @throws Swift_IoException - */ - public function flushBuffers() - { - if ($this->_writeBuffer !== '') { - $this->_doWrite($this->_writeBuffer); - } - $this->_flush(); - - foreach ($this->_mirrors as $stream) { - $stream->flushBuffers(); - } - } - - /** Run $bytes through all filters */ - private function _filter($bytes) - { - foreach ($this->_filters as $filter) { - $bytes = $filter->filter($bytes); - } - - return $bytes; - } - - /** Just write the bytes to the stream */ - private function _doWrite($bytes) - { - $this->_commit($this->_filter($bytes)); - - foreach ($this->_mirrors as $stream) { - $stream->write($bytes); - } - - $this->_writeBuffer = ''; - } -} diff --git a/lib/SwiftMailer/classes/Swift/ByteStream/ArrayByteStream.php b/lib/SwiftMailer/classes/Swift/ByteStream/ArrayByteStream.php deleted file mode 100644 index ef05a6d..0000000 --- a/lib/SwiftMailer/classes/Swift/ByteStream/ArrayByteStream.php +++ /dev/null @@ -1,182 +0,0 @@ -_array = $stack; - $this->_arraySize = count($stack); - } elseif (is_string($stack)) { - $this->write($stack); - } else { - $this->_array = array(); - } - } - - /** - * Reads $length bytes from the stream into a string and moves the pointer - * through the stream by $length. - * - * If less bytes exist than are requested the - * remaining bytes are given instead. If no bytes are remaining at all, boolean - * false is returned. - * - * @param int $length - * - * @return string - */ - public function read($length) - { - if ($this->_offset == $this->_arraySize) { - return false; - } - - // Don't use array slice - $end = $length + $this->_offset; - $end = $this->_arraySize < $end ? $this->_arraySize : $end; - $ret = ''; - for (; $this->_offset < $end; ++$this->_offset) { - $ret .= $this->_array[$this->_offset]; - } - - return $ret; - } - - /** - * Writes $bytes to the end of the stream. - * - * @param string $bytes - */ - public function write($bytes) - { - $to_add = str_split($bytes); - foreach ($to_add as $value) { - $this->_array[] = $value; - } - $this->_arraySize = count($this->_array); - - foreach ($this->_mirrors as $stream) { - $stream->write($bytes); - } - } - - /** - * Not used. - */ - public function commit() - { - } - - /** - * Attach $is to this stream. - * - * The stream acts as an observer, receiving all data that is written. - * All {@link write()} and {@link flushBuffers()} operations will be mirrored. - * - * @param Swift_InputByteStream $is - */ - public function bind(Swift_InputByteStream $is) - { - $this->_mirrors[] = $is; - } - - /** - * Remove an already bound stream. - * - * If $is is not bound, no errors will be raised. - * If the stream currently has any buffered data it will be written to $is - * before unbinding occurs. - * - * @param Swift_InputByteStream $is - */ - public function unbind(Swift_InputByteStream $is) - { - foreach ($this->_mirrors as $k => $stream) { - if ($is === $stream) { - unset($this->_mirrors[$k]); - } - } - } - - /** - * Move the internal read pointer to $byteOffset in the stream. - * - * @param int $byteOffset - * - * @return bool - */ - public function setReadPointer($byteOffset) - { - if ($byteOffset > $this->_arraySize) { - $byteOffset = $this->_arraySize; - } elseif ($byteOffset < 0) { - $byteOffset = 0; - } - - $this->_offset = $byteOffset; - } - - /** - * Flush the contents of the stream (empty it) and set the internal pointer - * to the beginning. - */ - public function flushBuffers() - { - $this->_offset = 0; - $this->_array = array(); - $this->_arraySize = 0; - - foreach ($this->_mirrors as $stream) { - $stream->flushBuffers(); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/ByteStream/FileByteStream.php b/lib/SwiftMailer/classes/Swift/ByteStream/FileByteStream.php deleted file mode 100644 index 9ed8523..0000000 --- a/lib/SwiftMailer/classes/Swift/ByteStream/FileByteStream.php +++ /dev/null @@ -1,231 +0,0 @@ -_path = $path; - $this->_mode = $writable ? 'w+b' : 'rb'; - - if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) { - $this->_quotes = true; - } - } - - /** - * Get the complete path to the file. - * - * @return string - */ - public function getPath() - { - return $this->_path; - } - - /** - * Reads $length bytes from the stream into a string and moves the pointer - * through the stream by $length. - * - * If less bytes exist than are requested the - * remaining bytes are given instead. If no bytes are remaining at all, boolean - * false is returned. - * - * @param int $length - * - * @throws Swift_IoException - * - * @return string|bool - */ - public function read($length) - { - $fp = $this->_getReadHandle(); - if (!feof($fp)) { - if ($this->_quotes) { - ini_set('magic_quotes_runtime', 0); - } - $bytes = fread($fp, $length); - if ($this->_quotes) { - ini_set('magic_quotes_runtime', 1); - } - $this->_offset = ftell($fp); - - // If we read one byte after reaching the end of the file - // feof() will return false and an empty string is returned - if ($bytes === '' && feof($fp)) { - $this->_resetReadHandle(); - - return false; - } - - return $bytes; - } - - $this->_resetReadHandle(); - - return false; - } - - /** - * Move the internal read pointer to $byteOffset in the stream. - * - * @param int $byteOffset - * - * @return bool - */ - public function setReadPointer($byteOffset) - { - if (isset($this->_reader)) { - $this->_seekReadStreamToPosition($byteOffset); - } - $this->_offset = $byteOffset; - } - - /** Just write the bytes to the file */ - protected function _commit($bytes) - { - fwrite($this->_getWriteHandle(), $bytes); - $this->_resetReadHandle(); - } - - /** Not used */ - protected function _flush() - { - } - - /** Get the resource for reading */ - private function _getReadHandle() - { - if (!isset($this->_reader)) { - $pointer = @fopen($this->_path, 'rb'); - if (!$pointer) { - throw new Swift_IoException( - 'Unable to open file for reading ['.$this->_path.']' - ); - } - $this->_reader = $pointer; - if ($this->_offset != 0) { - $this->_getReadStreamSeekableStatus(); - $this->_seekReadStreamToPosition($this->_offset); - } - } - - return $this->_reader; - } - - /** Get the resource for writing */ - private function _getWriteHandle() - { - if (!isset($this->_writer)) { - if (!$this->_writer = fopen($this->_path, $this->_mode)) { - throw new Swift_IoException( - 'Unable to open file for writing ['.$this->_path.']' - ); - } - } - - return $this->_writer; - } - - /** Force a reload of the resource for reading */ - private function _resetReadHandle() - { - if (isset($this->_reader)) { - fclose($this->_reader); - $this->_reader = null; - } - } - - /** Check if ReadOnly Stream is seekable */ - private function _getReadStreamSeekableStatus() - { - $metas = stream_get_meta_data($this->_reader); - $this->_seekable = $metas['seekable']; - } - - /** Streams in a readOnly stream ensuring copy if needed */ - private function _seekReadStreamToPosition($offset) - { - if ($this->_seekable === null) { - $this->_getReadStreamSeekableStatus(); - } - if ($this->_seekable === false) { - $currentPos = ftell($this->_reader); - if ($currentPos < $offset) { - $toDiscard = $offset - $currentPos; - fread($this->_reader, $toDiscard); - - return; - } - $this->_copyReadStream(); - } - fseek($this->_reader, $offset, SEEK_SET); - } - - /** Copy a readOnly Stream to ensure seekability */ - private function _copyReadStream() - { - if ($tmpFile = fopen('php://temp/maxmemory:4096', 'w+b')) { - /* We have opened a php:// Stream Should work without problem */ - } elseif (function_exists('sys_get_temp_dir') && is_writable(sys_get_temp_dir()) && ($tmpFile = tmpfile())) { - /* We have opened a tmpfile */ - } else { - throw new Swift_IoException('Unable to copy the file to make it seekable, sys_temp_dir is not writable, php://memory not available'); - } - $currentPos = ftell($this->_reader); - fclose($this->_reader); - $source = fopen($this->_path, 'rb'); - if (!$source) { - throw new Swift_IoException('Unable to open file for copying ['.$this->_path.']'); - } - fseek($tmpFile, 0, SEEK_SET); - while (!feof($source)) { - fwrite($tmpFile, fread($source, 4096)); - } - fseek($tmpFile, $currentPos, SEEK_SET); - fclose($source); - $this->_reader = $tmpFile; - } -} diff --git a/lib/SwiftMailer/classes/Swift/ByteStream/TemporaryFileByteStream.php b/lib/SwiftMailer/classes/Swift/ByteStream/TemporaryFileByteStream.php deleted file mode 100644 index 1c9a80c..0000000 --- a/lib/SwiftMailer/classes/Swift/ByteStream/TemporaryFileByteStream.php +++ /dev/null @@ -1,42 +0,0 @@ -getPath())) === false) { - throw new Swift_IoException('Failed to get temporary file content.'); - } - - return $content; - } - - public function __destruct() - { - if (file_exists($this->getPath())) { - @unlink($this->getPath()); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/CharacterReader.php b/lib/SwiftMailer/classes/Swift/CharacterReader.php deleted file mode 100644 index 3d5e854..0000000 --- a/lib/SwiftMailer/classes/Swift/CharacterReader.php +++ /dev/null @@ -1,67 +0,0 @@ - - */ -interface Swift_CharacterReader -{ - const MAP_TYPE_INVALID = 0x01; - const MAP_TYPE_FIXED_LEN = 0x02; - const MAP_TYPE_POSITIONS = 0x03; - - /** - * Returns the complete character map. - * - * @param string $string - * @param int $startOffset - * @param array $currentMap - * @param mixed $ignoredChars - * - * @return int - */ - public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars); - - /** - * Returns the mapType, see constants. - * - * @return int - */ - public function getMapType(); - - /** - * Returns an integer which specifies how many more bytes to read. - * - * A positive integer indicates the number of more bytes to fetch before invoking - * this method again. - * - * A value of zero means this is already a valid character. - * A value of -1 means this cannot possibly be a valid character. - * - * @param integer[] $bytes - * @param int $size - * - * @return int - */ - public function validateByteSequence($bytes, $size); - - /** - * Returns the number of bytes which should be read to start each character. - * - * For fixed width character sets this should be the number of octets-per-character. - * For multibyte character sets this will probably be 1. - * - * @return int - */ - public function getInitialByteSize(); -} diff --git a/lib/SwiftMailer/classes/Swift/CharacterReader/GenericFixedWidthReader.php b/lib/SwiftMailer/classes/Swift/CharacterReader/GenericFixedWidthReader.php deleted file mode 100644 index 6a18e1d..0000000 --- a/lib/SwiftMailer/classes/Swift/CharacterReader/GenericFixedWidthReader.php +++ /dev/null @@ -1,97 +0,0 @@ - - */ -class Swift_CharacterReader_GenericFixedWidthReader implements Swift_CharacterReader -{ - /** - * The number of bytes in a single character. - * - * @var int - */ - private $_width; - - /** - * Creates a new GenericFixedWidthReader using $width bytes per character. - * - * @param int $width - */ - public function __construct($width) - { - $this->_width = $width; - } - - /** - * Returns the complete character map. - * - * @param string $string - * @param int $startOffset - * @param array $currentMap - * @param mixed $ignoredChars - * - * @return int - */ - public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars) - { - $strlen = strlen($string); - // % and / are CPU intensive, so, maybe find a better way - $ignored = $strlen % $this->_width; - $ignoredChars = $ignored ? substr($string, -$ignored) : ''; - $currentMap = $this->_width; - - return ($strlen - $ignored) / $this->_width; - } - - /** - * Returns the mapType. - * - * @return int - */ - public function getMapType() - { - return self::MAP_TYPE_FIXED_LEN; - } - - /** - * Returns an integer which specifies how many more bytes to read. - * - * A positive integer indicates the number of more bytes to fetch before invoking - * this method again. - * - * A value of zero means this is already a valid character. - * A value of -1 means this cannot possibly be a valid character. - * - * @param string $bytes - * @param int $size - * - * @return int - */ - public function validateByteSequence($bytes, $size) - { - $needed = $this->_width - $size; - - return $needed > -1 ? $needed : -1; - } - - /** - * Returns the number of bytes which should be read to start each character. - * - * @return int - */ - public function getInitialByteSize() - { - return $this->_width; - } -} diff --git a/lib/SwiftMailer/classes/Swift/CharacterReader/UsAsciiReader.php b/lib/SwiftMailer/classes/Swift/CharacterReader/UsAsciiReader.php deleted file mode 100644 index 67da48f..0000000 --- a/lib/SwiftMailer/classes/Swift/CharacterReader/UsAsciiReader.php +++ /dev/null @@ -1,84 +0,0 @@ - "\x07F") { - // Invalid char - $currentMap[$i + $startOffset] = $string[$i]; - } - } - - return $strlen; - } - - /** - * Returns mapType. - * - * @return int mapType - */ - public function getMapType() - { - return self::MAP_TYPE_INVALID; - } - - /** - * Returns an integer which specifies how many more bytes to read. - * - * A positive integer indicates the number of more bytes to fetch before invoking - * this method again. - * A value of zero means this is already a valid character. - * A value of -1 means this cannot possibly be a valid character. - * - * @param string $bytes - * @param int $size - * - * @return int - */ - public function validateByteSequence($bytes, $size) - { - $byte = reset($bytes); - if (1 == count($bytes) && $byte >= 0x00 && $byte <= 0x7F) { - return 0; - } - - return -1; - } - - /** - * Returns the number of bytes which should be read to start each character. - * - * @return int - */ - public function getInitialByteSize() - { - return 1; - } -} diff --git a/lib/SwiftMailer/classes/Swift/CharacterReader/Utf8Reader.php b/lib/SwiftMailer/classes/Swift/CharacterReader/Utf8Reader.php deleted file mode 100644 index 7379bda..0000000 --- a/lib/SwiftMailer/classes/Swift/CharacterReader/Utf8Reader.php +++ /dev/null @@ -1,176 +0,0 @@ - - */ -class Swift_CharacterReader_Utf8Reader implements Swift_CharacterReader -{ - /** Pre-computed for optimization */ - private static $length_map = array( - // N=0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x0N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x2N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x4N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x6N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7N - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x8N - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9N - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xAN - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBN - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xCN - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDN - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEN - 4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0, // 0xFN - ); - - private static $s_length_map = array( - "\x00" => 1, "\x01" => 1, "\x02" => 1, "\x03" => 1, "\x04" => 1, "\x05" => 1, "\x06" => 1, "\x07" => 1, - "\x08" => 1, "\x09" => 1, "\x0a" => 1, "\x0b" => 1, "\x0c" => 1, "\x0d" => 1, "\x0e" => 1, "\x0f" => 1, - "\x10" => 1, "\x11" => 1, "\x12" => 1, "\x13" => 1, "\x14" => 1, "\x15" => 1, "\x16" => 1, "\x17" => 1, - "\x18" => 1, "\x19" => 1, "\x1a" => 1, "\x1b" => 1, "\x1c" => 1, "\x1d" => 1, "\x1e" => 1, "\x1f" => 1, - "\x20" => 1, "\x21" => 1, "\x22" => 1, "\x23" => 1, "\x24" => 1, "\x25" => 1, "\x26" => 1, "\x27" => 1, - "\x28" => 1, "\x29" => 1, "\x2a" => 1, "\x2b" => 1, "\x2c" => 1, "\x2d" => 1, "\x2e" => 1, "\x2f" => 1, - "\x30" => 1, "\x31" => 1, "\x32" => 1, "\x33" => 1, "\x34" => 1, "\x35" => 1, "\x36" => 1, "\x37" => 1, - "\x38" => 1, "\x39" => 1, "\x3a" => 1, "\x3b" => 1, "\x3c" => 1, "\x3d" => 1, "\x3e" => 1, "\x3f" => 1, - "\x40" => 1, "\x41" => 1, "\x42" => 1, "\x43" => 1, "\x44" => 1, "\x45" => 1, "\x46" => 1, "\x47" => 1, - "\x48" => 1, "\x49" => 1, "\x4a" => 1, "\x4b" => 1, "\x4c" => 1, "\x4d" => 1, "\x4e" => 1, "\x4f" => 1, - "\x50" => 1, "\x51" => 1, "\x52" => 1, "\x53" => 1, "\x54" => 1, "\x55" => 1, "\x56" => 1, "\x57" => 1, - "\x58" => 1, "\x59" => 1, "\x5a" => 1, "\x5b" => 1, "\x5c" => 1, "\x5d" => 1, "\x5e" => 1, "\x5f" => 1, - "\x60" => 1, "\x61" => 1, "\x62" => 1, "\x63" => 1, "\x64" => 1, "\x65" => 1, "\x66" => 1, "\x67" => 1, - "\x68" => 1, "\x69" => 1, "\x6a" => 1, "\x6b" => 1, "\x6c" => 1, "\x6d" => 1, "\x6e" => 1, "\x6f" => 1, - "\x70" => 1, "\x71" => 1, "\x72" => 1, "\x73" => 1, "\x74" => 1, "\x75" => 1, "\x76" => 1, "\x77" => 1, - "\x78" => 1, "\x79" => 1, "\x7a" => 1, "\x7b" => 1, "\x7c" => 1, "\x7d" => 1, "\x7e" => 1, "\x7f" => 1, - "\x80" => 0, "\x81" => 0, "\x82" => 0, "\x83" => 0, "\x84" => 0, "\x85" => 0, "\x86" => 0, "\x87" => 0, - "\x88" => 0, "\x89" => 0, "\x8a" => 0, "\x8b" => 0, "\x8c" => 0, "\x8d" => 0, "\x8e" => 0, "\x8f" => 0, - "\x90" => 0, "\x91" => 0, "\x92" => 0, "\x93" => 0, "\x94" => 0, "\x95" => 0, "\x96" => 0, "\x97" => 0, - "\x98" => 0, "\x99" => 0, "\x9a" => 0, "\x9b" => 0, "\x9c" => 0, "\x9d" => 0, "\x9e" => 0, "\x9f" => 0, - "\xa0" => 0, "\xa1" => 0, "\xa2" => 0, "\xa3" => 0, "\xa4" => 0, "\xa5" => 0, "\xa6" => 0, "\xa7" => 0, - "\xa8" => 0, "\xa9" => 0, "\xaa" => 0, "\xab" => 0, "\xac" => 0, "\xad" => 0, "\xae" => 0, "\xaf" => 0, - "\xb0" => 0, "\xb1" => 0, "\xb2" => 0, "\xb3" => 0, "\xb4" => 0, "\xb5" => 0, "\xb6" => 0, "\xb7" => 0, - "\xb8" => 0, "\xb9" => 0, "\xba" => 0, "\xbb" => 0, "\xbc" => 0, "\xbd" => 0, "\xbe" => 0, "\xbf" => 0, - "\xc0" => 2, "\xc1" => 2, "\xc2" => 2, "\xc3" => 2, "\xc4" => 2, "\xc5" => 2, "\xc6" => 2, "\xc7" => 2, - "\xc8" => 2, "\xc9" => 2, "\xca" => 2, "\xcb" => 2, "\xcc" => 2, "\xcd" => 2, "\xce" => 2, "\xcf" => 2, - "\xd0" => 2, "\xd1" => 2, "\xd2" => 2, "\xd3" => 2, "\xd4" => 2, "\xd5" => 2, "\xd6" => 2, "\xd7" => 2, - "\xd8" => 2, "\xd9" => 2, "\xda" => 2, "\xdb" => 2, "\xdc" => 2, "\xdd" => 2, "\xde" => 2, "\xdf" => 2, - "\xe0" => 3, "\xe1" => 3, "\xe2" => 3, "\xe3" => 3, "\xe4" => 3, "\xe5" => 3, "\xe6" => 3, "\xe7" => 3, - "\xe8" => 3, "\xe9" => 3, "\xea" => 3, "\xeb" => 3, "\xec" => 3, "\xed" => 3, "\xee" => 3, "\xef" => 3, - "\xf0" => 4, "\xf1" => 4, "\xf2" => 4, "\xf3" => 4, "\xf4" => 4, "\xf5" => 4, "\xf6" => 4, "\xf7" => 4, - "\xf8" => 5, "\xf9" => 5, "\xfa" => 5, "\xfb" => 5, "\xfc" => 6, "\xfd" => 6, "\xfe" => 0, "\xff" => 0, - ); - - /** - * Returns the complete character map. - * - * @param string $string - * @param int $startOffset - * @param array $currentMap - * @param mixed $ignoredChars - * - * @return int - */ - public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars) - { - if (!isset($currentMap['i']) || !isset($currentMap['p'])) { - $currentMap['p'] = $currentMap['i'] = array(); - } - - $strlen = strlen($string); - $charPos = count($currentMap['p']); - $foundChars = 0; - $invalid = false; - for ($i = 0; $i < $strlen; ++$i) { - $char = $string[$i]; - $size = self::$s_length_map[$char]; - if ($size == 0) { - /* char is invalid, we must wait for a resync */ - $invalid = true; - continue; - } else { - if ($invalid == true) { - /* We mark the chars as invalid and start a new char */ - $currentMap['p'][$charPos + $foundChars] = $startOffset + $i; - $currentMap['i'][$charPos + $foundChars] = true; - ++$foundChars; - $invalid = false; - } - if (($i + $size) > $strlen) { - $ignoredChars = substr($string, $i); - break; - } - for ($j = 1; $j < $size; ++$j) { - $char = $string[$i + $j]; - if ($char > "\x7F" && $char < "\xC0") { - // Valid - continue parsing - } else { - /* char is invalid, we must wait for a resync */ - $invalid = true; - continue 2; - } - } - /* Ok we got a complete char here */ - $currentMap['p'][$charPos + $foundChars] = $startOffset + $i + $size; - $i += $j - 1; - ++$foundChars; - } - } - - return $foundChars; - } - - /** - * Returns mapType. - * - * @return int mapType - */ - public function getMapType() - { - return self::MAP_TYPE_POSITIONS; - } - - /** - * Returns an integer which specifies how many more bytes to read. - * - * A positive integer indicates the number of more bytes to fetch before invoking - * this method again. - * A value of zero means this is already a valid character. - * A value of -1 means this cannot possibly be a valid character. - * - * @param string $bytes - * @param int $size - * - * @return int - */ - public function validateByteSequence($bytes, $size) - { - if ($size < 1) { - return -1; - } - $needed = self::$length_map[$bytes[0]] - $size; - - return $needed > -1 ? $needed : -1; - } - - /** - * Returns the number of bytes which should be read to start each character. - * - * @return int - */ - public function getInitialByteSize() - { - return 1; - } -} diff --git a/lib/SwiftMailer/classes/Swift/CharacterReaderFactory.php b/lib/SwiftMailer/classes/Swift/CharacterReaderFactory.php deleted file mode 100644 index 15b6c69..0000000 --- a/lib/SwiftMailer/classes/Swift/CharacterReaderFactory.php +++ /dev/null @@ -1,26 +0,0 @@ -init(); - } - - public function __wakeup() - { - $this->init(); - } - - public function init() - { - if (count(self::$_map) > 0) { - return; - } - - $prefix = 'Swift_CharacterReader_'; - - $singleByte = array( - 'class' => $prefix.'GenericFixedWidthReader', - 'constructor' => array(1), - ); - - $doubleByte = array( - 'class' => $prefix.'GenericFixedWidthReader', - 'constructor' => array(2), - ); - - $fourBytes = array( - 'class' => $prefix.'GenericFixedWidthReader', - 'constructor' => array(4), - ); - - // Utf-8 - self::$_map['utf-?8'] = array( - 'class' => $prefix.'Utf8Reader', - 'constructor' => array(), - ); - - //7-8 bit charsets - self::$_map['(us-)?ascii'] = $singleByte; - self::$_map['(iso|iec)-?8859-?[0-9]+'] = $singleByte; - self::$_map['windows-?125[0-9]'] = $singleByte; - self::$_map['cp-?[0-9]+'] = $singleByte; - self::$_map['ansi'] = $singleByte; - self::$_map['macintosh'] = $singleByte; - self::$_map['koi-?7'] = $singleByte; - self::$_map['koi-?8-?.+'] = $singleByte; - self::$_map['mik'] = $singleByte; - self::$_map['(cork|t1)'] = $singleByte; - self::$_map['v?iscii'] = $singleByte; - - //16 bits - self::$_map['(ucs-?2|utf-?16)'] = $doubleByte; - - //32 bits - self::$_map['(ucs-?4|utf-?32)'] = $fourBytes; - - // Fallback - self::$_map['.*'] = $singleByte; - } - - /** - * Returns a CharacterReader suitable for the charset applied. - * - * @param string $charset - * - * @return Swift_CharacterReader - */ - public function getReaderFor($charset) - { - $charset = trim(strtolower($charset)); - foreach (self::$_map as $pattern => $spec) { - $re = '/^'.$pattern.'$/D'; - if (preg_match($re, $charset)) { - if (!array_key_exists($pattern, self::$_loaded)) { - $reflector = new ReflectionClass($spec['class']); - if ($reflector->getConstructor()) { - $reader = $reflector->newInstanceArgs($spec['constructor']); - } else { - $reader = $reflector->newInstance(); - } - self::$_loaded[$pattern] = $reader; - } - - return self::$_loaded[$pattern]; - } - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/CharacterStream.php b/lib/SwiftMailer/classes/Swift/CharacterStream.php deleted file mode 100644 index 717924f..0000000 --- a/lib/SwiftMailer/classes/Swift/CharacterStream.php +++ /dev/null @@ -1,89 +0,0 @@ -setCharacterReaderFactory($factory); - $this->setCharacterSet($charset); - } - - /** - * Set the character set used in this CharacterStream. - * - * @param string $charset - */ - public function setCharacterSet($charset) - { - $this->_charset = $charset; - $this->_charReader = null; - } - - /** - * Set the CharacterReaderFactory for multi charset support. - * - * @param Swift_CharacterReaderFactory $factory - */ - public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory) - { - $this->_charReaderFactory = $factory; - } - - /** - * Overwrite this character stream using the byte sequence in the byte stream. - * - * @param Swift_OutputByteStream $os output stream to read from - */ - public function importByteStream(Swift_OutputByteStream $os) - { - if (!isset($this->_charReader)) { - $this->_charReader = $this->_charReaderFactory - ->getReaderFor($this->_charset); - } - - $startLength = $this->_charReader->getInitialByteSize(); - while (false !== $bytes = $os->read($startLength)) { - $c = array(); - for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) { - $c[] = self::$_byteMap[$bytes[$i]]; - } - $size = count($c); - $need = $this->_charReader - ->validateByteSequence($c, $size); - if ($need > 0 && - false !== $bytes = $os->read($need)) { - for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) { - $c[] = self::$_byteMap[$bytes[$i]]; - } - } - $this->_array[] = $c; - ++$this->_array_size; - } - } - - /** - * Import a string a bytes into this CharacterStream, overwriting any existing - * data in the stream. - * - * @param string $string - */ - public function importString($string) - { - $this->flushContents(); - $this->write($string); - } - - /** - * Read $length characters from the stream and move the internal pointer - * $length further into the stream. - * - * @param int $length - * - * @return string - */ - public function read($length) - { - if ($this->_offset == $this->_array_size) { - return false; - } - - // Don't use array slice - $arrays = array(); - $end = $length + $this->_offset; - for ($i = $this->_offset; $i < $end; ++$i) { - if (!isset($this->_array[$i])) { - break; - } - $arrays[] = $this->_array[$i]; - } - $this->_offset += $i - $this->_offset; // Limit function calls - $chars = false; - foreach ($arrays as $array) { - $chars .= implode('', array_map('chr', $array)); - } - - return $chars; - } - - /** - * Read $length characters from the stream and return a 1-dimensional array - * containing there octet values. - * - * @param int $length - * - * @return integer[] - */ - public function readBytes($length) - { - if ($this->_offset == $this->_array_size) { - return false; - } - $arrays = array(); - $end = $length + $this->_offset; - for ($i = $this->_offset; $i < $end; ++$i) { - if (!isset($this->_array[$i])) { - break; - } - $arrays[] = $this->_array[$i]; - } - $this->_offset += ($i - $this->_offset); // Limit function calls - - return call_user_func_array('array_merge', $arrays); - } - - /** - * Write $chars to the end of the stream. - * - * @param string $chars - */ - public function write($chars) - { - if (!isset($this->_charReader)) { - $this->_charReader = $this->_charReaderFactory->getReaderFor( - $this->_charset); - } - - $startLength = $this->_charReader->getInitialByteSize(); - - $fp = fopen('php://memory', 'w+b'); - fwrite($fp, $chars); - unset($chars); - fseek($fp, 0, SEEK_SET); - - $buffer = array(0); - $buf_pos = 1; - $buf_len = 1; - $has_datas = true; - do { - $bytes = array(); - // Buffer Filing - if ($buf_len - $buf_pos < $startLength) { - $buf = array_splice($buffer, $buf_pos); - $new = $this->_reloadBuffer($fp, 100); - if ($new) { - $buffer = array_merge($buf, $new); - $buf_len = count($buffer); - $buf_pos = 0; - } else { - $has_datas = false; - } - } - if ($buf_len - $buf_pos > 0) { - $size = 0; - for ($i = 0; $i < $startLength && isset($buffer[$buf_pos]); ++$i) { - ++$size; - $bytes[] = $buffer[$buf_pos++]; - } - $need = $this->_charReader->validateByteSequence( - $bytes, $size); - if ($need > 0) { - if ($buf_len - $buf_pos < $need) { - $new = $this->_reloadBuffer($fp, $need); - - if ($new) { - $buffer = array_merge($buffer, $new); - $buf_len = count($buffer); - } - } - for ($i = 0; $i < $need && isset($buffer[$buf_pos]); ++$i) { - $bytes[] = $buffer[$buf_pos++]; - } - } - $this->_array[] = $bytes; - ++$this->_array_size; - } - } while ($has_datas); - - fclose($fp); - } - - /** - * Move the internal pointer to $charOffset in the stream. - * - * @param int $charOffset - */ - public function setPointer($charOffset) - { - if ($charOffset > $this->_array_size) { - $charOffset = $this->_array_size; - } elseif ($charOffset < 0) { - $charOffset = 0; - } - $this->_offset = $charOffset; - } - - /** - * Empty the stream and reset the internal pointer. - */ - public function flushContents() - { - $this->_offset = 0; - $this->_array = array(); - $this->_array_size = 0; - } - - private function _reloadBuffer($fp, $len) - { - if (!feof($fp) && ($bytes = fread($fp, $len)) !== false) { - $buf = array(); - for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) { - $buf[] = self::$_byteMap[$bytes[$i]]; - } - - return $buf; - } - - return false; - } - - private static function _initializeMaps() - { - if (!isset(self::$_charMap)) { - self::$_charMap = array(); - for ($byte = 0; $byte < 256; ++$byte) { - self::$_charMap[$byte] = chr($byte); - } - self::$_byteMap = array_flip(self::$_charMap); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/CharacterStream/NgCharacterStream.php b/lib/SwiftMailer/classes/Swift/CharacterStream/NgCharacterStream.php deleted file mode 100644 index 58bd140..0000000 --- a/lib/SwiftMailer/classes/Swift/CharacterStream/NgCharacterStream.php +++ /dev/null @@ -1,267 +0,0 @@ - - */ -class Swift_CharacterStream_NgCharacterStream implements Swift_CharacterStream -{ - /** - * The char reader (lazy-loaded) for the current charset. - * - * @var Swift_CharacterReader - */ - private $_charReader; - - /** - * A factory for creating CharacterReader instances. - * - * @var Swift_CharacterReaderFactory - */ - private $_charReaderFactory; - - /** - * The character set this stream is using. - * - * @var string - */ - private $_charset; - - /** - * The data's stored as-is. - * - * @var string - */ - private $_datas = ''; - - /** - * Number of bytes in the stream. - * - * @var int - */ - private $_datasSize = 0; - - /** - * Map. - * - * @var mixed - */ - private $_map; - - /** - * Map Type. - * - * @var int - */ - private $_mapType = 0; - - /** - * Number of characters in the stream. - * - * @var int - */ - private $_charCount = 0; - - /** - * Position in the stream. - * - * @var int - */ - private $_currentPos = 0; - - /** - * Constructor. - * - * @param Swift_CharacterReaderFactory $factory - * @param string $charset - */ - public function __construct(Swift_CharacterReaderFactory $factory, $charset) - { - $this->setCharacterReaderFactory($factory); - $this->setCharacterSet($charset); - } - - /* -- Changing parameters of the stream -- */ - - /** - * Set the character set used in this CharacterStream. - * - * @param string $charset - */ - public function setCharacterSet($charset) - { - $this->_charset = $charset; - $this->_charReader = null; - $this->_mapType = 0; - } - - /** - * Set the CharacterReaderFactory for multi charset support. - * - * @param Swift_CharacterReaderFactory $factory - */ - public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory) - { - $this->_charReaderFactory = $factory; - } - - /** - * @see Swift_CharacterStream::flushContents() - */ - public function flushContents() - { - $this->_datas = null; - $this->_map = null; - $this->_charCount = 0; - $this->_currentPos = 0; - $this->_datasSize = 0; - } - - /** - * @see Swift_CharacterStream::importByteStream() - * - * @param Swift_OutputByteStream $os - */ - public function importByteStream(Swift_OutputByteStream $os) - { - $this->flushContents(); - $blocks = 512; - $os->setReadPointer(0); - while (false !== ($read = $os->read($blocks))) { - $this->write($read); - } - } - - /** - * @see Swift_CharacterStream::importString() - * - * @param string $string - */ - public function importString($string) - { - $this->flushContents(); - $this->write($string); - } - - /** - * @see Swift_CharacterStream::read() - * - * @param int $length - * - * @return string - */ - public function read($length) - { - if ($this->_currentPos >= $this->_charCount) { - return false; - } - $ret = false; - $length = $this->_currentPos + $length > $this->_charCount ? $this->_charCount - $this->_currentPos : $length; - switch ($this->_mapType) { - case Swift_CharacterReader::MAP_TYPE_FIXED_LEN: - $len = $length * $this->_map; - $ret = substr($this->_datas, - $this->_currentPos * $this->_map, - $len); - $this->_currentPos += $length; - break; - - case Swift_CharacterReader::MAP_TYPE_INVALID: - $ret = ''; - for (; $this->_currentPos < $length; ++$this->_currentPos) { - if (isset($this->_map[$this->_currentPos])) { - $ret .= '?'; - } else { - $ret .= $this->_datas[$this->_currentPos]; - } - } - break; - - case Swift_CharacterReader::MAP_TYPE_POSITIONS: - $end = $this->_currentPos + $length; - $end = $end > $this->_charCount ? $this->_charCount : $end; - $ret = ''; - $start = 0; - if ($this->_currentPos > 0) { - $start = $this->_map['p'][$this->_currentPos - 1]; - } - $to = $start; - for (; $this->_currentPos < $end; ++$this->_currentPos) { - if (isset($this->_map['i'][$this->_currentPos])) { - $ret .= substr($this->_datas, $start, $to - $start).'?'; - $start = $this->_map['p'][$this->_currentPos]; - } else { - $to = $this->_map['p'][$this->_currentPos]; - } - } - $ret .= substr($this->_datas, $start, $to - $start); - break; - } - - return $ret; - } - - /** - * @see Swift_CharacterStream::readBytes() - * - * @param int $length - * - * @return int[] - */ - public function readBytes($length) - { - $read = $this->read($length); - if ($read !== false) { - $ret = array_map('ord', str_split($read, 1)); - - return $ret; - } - - return false; - } - - /** - * @see Swift_CharacterStream::setPointer() - * - * @param int $charOffset - */ - public function setPointer($charOffset) - { - if ($this->_charCount < $charOffset) { - $charOffset = $this->_charCount; - } - $this->_currentPos = $charOffset; - } - - /** - * @see Swift_CharacterStream::write() - * - * @param string $chars - */ - public function write($chars) - { - if (!isset($this->_charReader)) { - $this->_charReader = $this->_charReaderFactory->getReaderFor( - $this->_charset); - $this->_map = array(); - $this->_mapType = $this->_charReader->getMapType(); - } - $ignored = ''; - $this->_datas .= $chars; - $this->_charCount += $this->_charReader->getCharPositions(substr($this->_datas, $this->_datasSize), $this->_datasSize, $this->_map, $ignored); - if ($ignored !== false) { - $this->_datasSize = strlen($this->_datas) - strlen($ignored); - } else { - $this->_datasSize = strlen($this->_datas); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/ConfigurableSpool.php b/lib/SwiftMailer/classes/Swift/ConfigurableSpool.php deleted file mode 100644 index 4ae5bac..0000000 --- a/lib/SwiftMailer/classes/Swift/ConfigurableSpool.php +++ /dev/null @@ -1,63 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Base class for Spools (implements time and message limits). - * - * @author Fabien Potencier - */ -abstract class Swift_ConfigurableSpool implements Swift_Spool -{ - /** The maximum number of messages to send per flush */ - private $_message_limit; - - /** The time limit per flush */ - private $_time_limit; - - /** - * Sets the maximum number of messages to send per flush. - * - * @param int $limit - */ - public function setMessageLimit($limit) - { - $this->_message_limit = (int) $limit; - } - - /** - * Gets the maximum number of messages to send per flush. - * - * @return int The limit - */ - public function getMessageLimit() - { - return $this->_message_limit; - } - - /** - * Sets the time limit (in seconds) per flush. - * - * @param int $limit The limit - */ - public function setTimeLimit($limit) - { - $this->_time_limit = (int) $limit; - } - - /** - * Gets the time limit (in seconds) per flush. - * - * @return int The limit - */ - public function getTimeLimit() - { - return $this->_time_limit; - } -} diff --git a/lib/SwiftMailer/classes/Swift/DependencyContainer.php b/lib/SwiftMailer/classes/Swift/DependencyContainer.php deleted file mode 100644 index 8c1074a..0000000 --- a/lib/SwiftMailer/classes/Swift/DependencyContainer.php +++ /dev/null @@ -1,373 +0,0 @@ -_store); - } - - /** - * Test if an item is registered in this container with the given name. - * - * @see register() - * - * @param string $itemName - * - * @return bool - */ - public function has($itemName) - { - return array_key_exists($itemName, $this->_store) - && isset($this->_store[$itemName]['lookupType']); - } - - /** - * Lookup the item with the given $itemName. - * - * @see register() - * - * @param string $itemName - * - * @throws Swift_DependencyException If the dependency is not found - * - * @return mixed - */ - public function lookup($itemName) - { - if (!$this->has($itemName)) { - throw new Swift_DependencyException( - 'Cannot lookup dependency "'.$itemName.'" since it is not registered.' - ); - } - - switch ($this->_store[$itemName]['lookupType']) { - case self::TYPE_ALIAS: - return $this->_createAlias($itemName); - case self::TYPE_VALUE: - return $this->_getValue($itemName); - case self::TYPE_INSTANCE: - return $this->_createNewInstance($itemName); - case self::TYPE_SHARED: - return $this->_createSharedInstance($itemName); - } - } - - /** - * Create an array of arguments passed to the constructor of $itemName. - * - * @param string $itemName - * - * @return array - */ - public function createDependenciesFor($itemName) - { - $args = array(); - if (isset($this->_store[$itemName]['args'])) { - $args = $this->_resolveArgs($this->_store[$itemName]['args']); - } - - return $args; - } - - /** - * Register a new dependency with $itemName. - * - * This method returns the current DependencyContainer instance because it - * requires the use of the fluid interface to set the specific details for the - * dependency. - * - * @see asNewInstanceOf(), asSharedInstanceOf(), asValue() - * - * @param string $itemName - * - * @return Swift_DependencyContainer - */ - public function register($itemName) - { - $this->_store[$itemName] = array(); - $this->_endPoint = &$this->_store[$itemName]; - - return $this; - } - - /** - * Specify the previously registered item as a literal value. - * - * {@link register()} must be called before this will work. - * - * @param mixed $value - * - * @return Swift_DependencyContainer - */ - public function asValue($value) - { - $endPoint = &$this->_getEndPoint(); - $endPoint['lookupType'] = self::TYPE_VALUE; - $endPoint['value'] = $value; - - return $this; - } - - /** - * Specify the previously registered item as an alias of another item. - * - * @param string $lookup - * - * @return Swift_DependencyContainer - */ - public function asAliasOf($lookup) - { - $endPoint = &$this->_getEndPoint(); - $endPoint['lookupType'] = self::TYPE_ALIAS; - $endPoint['ref'] = $lookup; - - return $this; - } - - /** - * Specify the previously registered item as a new instance of $className. - * - * {@link register()} must be called before this will work. - * Any arguments can be set with {@link withDependencies()}, - * {@link addConstructorValue()} or {@link addConstructorLookup()}. - * - * @see withDependencies(), addConstructorValue(), addConstructorLookup() - * - * @param string $className - * - * @return Swift_DependencyContainer - */ - public function asNewInstanceOf($className) - { - $endPoint = &$this->_getEndPoint(); - $endPoint['lookupType'] = self::TYPE_INSTANCE; - $endPoint['className'] = $className; - - return $this; - } - - /** - * Specify the previously registered item as a shared instance of $className. - * - * {@link register()} must be called before this will work. - * - * @param string $className - * - * @return Swift_DependencyContainer - */ - public function asSharedInstanceOf($className) - { - $endPoint = &$this->_getEndPoint(); - $endPoint['lookupType'] = self::TYPE_SHARED; - $endPoint['className'] = $className; - - return $this; - } - - /** - * Specify a list of injected dependencies for the previously registered item. - * - * This method takes an array of lookup names. - * - * @see addConstructorValue(), addConstructorLookup() - * - * @param array $lookups - * - * @return Swift_DependencyContainer - */ - public function withDependencies(array $lookups) - { - $endPoint = &$this->_getEndPoint(); - $endPoint['args'] = array(); - foreach ($lookups as $lookup) { - $this->addConstructorLookup($lookup); - } - - return $this; - } - - /** - * Specify a literal (non looked up) value for the constructor of the - * previously registered item. - * - * @see withDependencies(), addConstructorLookup() - * - * @param mixed $value - * - * @return Swift_DependencyContainer - */ - public function addConstructorValue($value) - { - $endPoint = &$this->_getEndPoint(); - if (!isset($endPoint['args'])) { - $endPoint['args'] = array(); - } - $endPoint['args'][] = array('type' => 'value', 'item' => $value); - - return $this; - } - - /** - * Specify a dependency lookup for the constructor of the previously - * registered item. - * - * @see withDependencies(), addConstructorValue() - * - * @param string $lookup - * - * @return Swift_DependencyContainer - */ - public function addConstructorLookup($lookup) - { - $endPoint = &$this->_getEndPoint(); - if (!isset($this->_endPoint['args'])) { - $endPoint['args'] = array(); - } - $endPoint['args'][] = array('type' => 'lookup', 'item' => $lookup); - - return $this; - } - - /** Get the literal value with $itemName */ - private function _getValue($itemName) - { - return $this->_store[$itemName]['value']; - } - - /** Resolve an alias to another item */ - private function _createAlias($itemName) - { - return $this->lookup($this->_store[$itemName]['ref']); - } - - /** Create a fresh instance of $itemName */ - private function _createNewInstance($itemName) - { - $reflector = new ReflectionClass($this->_store[$itemName]['className']); - if ($reflector->getConstructor()) { - return $reflector->newInstanceArgs( - $this->createDependenciesFor($itemName) - ); - } - - return $reflector->newInstance(); - } - - /** Create and register a shared instance of $itemName */ - private function _createSharedInstance($itemName) - { - if (!isset($this->_store[$itemName]['instance'])) { - $this->_store[$itemName]['instance'] = $this->_createNewInstance($itemName); - } - - return $this->_store[$itemName]['instance']; - } - - /** Get the current endpoint in the store */ - private function &_getEndPoint() - { - if (!isset($this->_endPoint)) { - throw new BadMethodCallException( - 'Component must first be registered by calling register()' - ); - } - - return $this->_endPoint; - } - - /** Get an argument list with dependencies resolved */ - private function _resolveArgs(array $args) - { - $resolved = array(); - foreach ($args as $argDefinition) { - switch ($argDefinition['type']) { - case 'lookup': - $resolved[] = $this->_lookupRecursive($argDefinition['item']); - break; - case 'value': - $resolved[] = $argDefinition['item']; - break; - } - } - - return $resolved; - } - - /** Resolve a single dependency with an collections */ - private function _lookupRecursive($item) - { - if (is_array($item)) { - $collection = array(); - foreach ($item as $k => $v) { - $collection[$k] = $this->_lookupRecursive($v); - } - - return $collection; - } - - return $this->lookup($item); - } -} diff --git a/lib/SwiftMailer/classes/Swift/DependencyException.php b/lib/SwiftMailer/classes/Swift/DependencyException.php deleted file mode 100644 index 799d38d..0000000 --- a/lib/SwiftMailer/classes/Swift/DependencyException.php +++ /dev/null @@ -1,27 +0,0 @@ -createDependenciesFor('mime.embeddedfile') - ); - - $this->setBody($data); - $this->setFilename($filename); - if ($contentType) { - $this->setContentType($contentType); - } - } - - /** - * Create a new EmbeddedFile. - * - * @param string|Swift_OutputByteStream $data - * @param string $filename - * @param string $contentType - * - * @return Swift_Mime_EmbeddedFile - */ - public static function newInstance($data = null, $filename = null, $contentType = null) - { - return new self($data, $filename, $contentType); - } - - /** - * Create a new EmbeddedFile from a filesystem path. - * - * @param string $path - * - * @return Swift_Mime_EmbeddedFile - */ - public static function fromPath($path) - { - return self::newInstance()->setFile( - new Swift_ByteStream_FileByteStream($path) - ); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Encoder.php b/lib/SwiftMailer/classes/Swift/Encoder.php deleted file mode 100644 index 2073abc..0000000 --- a/lib/SwiftMailer/classes/Swift/Encoder.php +++ /dev/null @@ -1,28 +0,0 @@ -= $maxLineLength || 76 < $maxLineLength) { - $maxLineLength = 76; - } - - $encodedString = base64_encode($string); - $firstLine = ''; - - if (0 != $firstLineOffset) { - $firstLine = substr( - $encodedString, 0, $maxLineLength - $firstLineOffset - )."\r\n"; - $encodedString = substr( - $encodedString, $maxLineLength - $firstLineOffset - ); - } - - return $firstLine.trim(chunk_split($encodedString, $maxLineLength, "\r\n")); - } - - /** - * Does nothing. - */ - public function charsetChanged($charset) - { - } -} diff --git a/lib/SwiftMailer/classes/Swift/Encoder/Rfc2231Encoder.php b/lib/SwiftMailer/classes/Swift/Encoder/Rfc2231Encoder.php deleted file mode 100644 index b0215e8..0000000 --- a/lib/SwiftMailer/classes/Swift/Encoder/Rfc2231Encoder.php +++ /dev/null @@ -1,92 +0,0 @@ -_charStream = $charStream; - } - - /** - * Takes an unencoded string and produces a string encoded according to - * RFC 2231 from it. - * - * @param string $string - * @param int $firstLineOffset - * @param int $maxLineLength optional, 0 indicates the default of 75 bytes - * - * @return string - */ - public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) - { - $lines = array(); - $lineCount = 0; - $lines[] = ''; - $currentLine = &$lines[$lineCount++]; - - if (0 >= $maxLineLength) { - $maxLineLength = 75; - } - - $this->_charStream->flushContents(); - $this->_charStream->importString($string); - - $thisLineLength = $maxLineLength - $firstLineOffset; - - while (false !== $char = $this->_charStream->read(4)) { - $encodedChar = rawurlencode($char); - if (0 != strlen($currentLine) - && strlen($currentLine.$encodedChar) > $thisLineLength) { - $lines[] = ''; - $currentLine = &$lines[$lineCount++]; - $thisLineLength = $maxLineLength; - } - $currentLine .= $encodedChar; - } - - return implode("\r\n", $lines); - } - - /** - * Updates the charset used. - * - * @param string $charset - */ - public function charsetChanged($charset) - { - $this->_charStream->setCharacterSet($charset); - } - - /** - * Make a deep copy of object. - */ - public function __clone() - { - $this->_charStream = clone $this->_charStream; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Encoding.php b/lib/SwiftMailer/classes/Swift/Encoding.php deleted file mode 100644 index 253977b..0000000 --- a/lib/SwiftMailer/classes/Swift/Encoding.php +++ /dev/null @@ -1,64 +0,0 @@ -lookup($key); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Events/CommandEvent.php b/lib/SwiftMailer/classes/Swift/Events/CommandEvent.php deleted file mode 100644 index 7dc381d..0000000 --- a/lib/SwiftMailer/classes/Swift/Events/CommandEvent.php +++ /dev/null @@ -1,65 +0,0 @@ -_command = $command; - $this->_successCodes = $successCodes; - } - - /** - * Get the command which was sent to the server. - * - * @return string - */ - public function getCommand() - { - return $this->_command; - } - - /** - * Get the numeric response codes which indicate success for this command. - * - * @return integer[] - */ - public function getSuccessCodes() - { - return $this->_successCodes; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Events/CommandListener.php b/lib/SwiftMailer/classes/Swift/Events/CommandListener.php deleted file mode 100644 index 7545404..0000000 --- a/lib/SwiftMailer/classes/Swift/Events/CommandListener.php +++ /dev/null @@ -1,24 +0,0 @@ -_source = $source; - } - - /** - * Get the source object of this event. - * - * @return object - */ - public function getSource() - { - return $this->_source; - } - - /** - * Prevent this Event from bubbling any further up the stack. - * - * @param bool $cancel, optional - */ - public function cancelBubble($cancel = true) - { - $this->_bubbleCancelled = $cancel; - } - - /** - * Returns true if this Event will not bubble any further up the stack. - * - * @return bool - */ - public function bubbleCancelled() - { - return $this->_bubbleCancelled; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Events/ResponseEvent.php b/lib/SwiftMailer/classes/Swift/Events/ResponseEvent.php deleted file mode 100644 index 2e92ba9..0000000 --- a/lib/SwiftMailer/classes/Swift/Events/ResponseEvent.php +++ /dev/null @@ -1,65 +0,0 @@ -_response = $response; - $this->_valid = $valid; - } - - /** - * Get the response which was received from the server. - * - * @return string - */ - public function getResponse() - { - return $this->_response; - } - - /** - * Get the success status of this Event. - * - * @return bool - */ - public function isValid() - { - return $this->_valid; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Events/ResponseListener.php b/lib/SwiftMailer/classes/Swift/Events/ResponseListener.php deleted file mode 100644 index c40919d..0000000 --- a/lib/SwiftMailer/classes/Swift/Events/ResponseListener.php +++ /dev/null @@ -1,24 +0,0 @@ -_message = $message; - $this->_result = self::RESULT_PENDING; - } - - /** - * Get the Transport used to send the Message. - * - * @return Swift_Transport - */ - public function getTransport() - { - return $this->getSource(); - } - - /** - * Get the Message being sent. - * - * @return Swift_Mime_Message - */ - public function getMessage() - { - return $this->_message; - } - - /** - * Set the array of addresses that failed in sending. - * - * @param array $recipients - */ - public function setFailedRecipients($recipients) - { - $this->_failedRecipients = $recipients; - } - - /** - * Get an recipient addresses which were not accepted for delivery. - * - * @return string[] - */ - public function getFailedRecipients() - { - return $this->_failedRecipients; - } - - /** - * Set the result of sending. - * - * @param int $result - */ - public function setResult($result) - { - $this->_result = $result; - } - - /** - * Get the result of this Event. - * - * The return value is a bitmask from - * {@see RESULT_PENDING, RESULT_SUCCESS, RESULT_TENTATIVE, RESULT_FAILED} - * - * @return int - */ - public function getResult() - { - return $this->_result; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Events/SendListener.php b/lib/SwiftMailer/classes/Swift/Events/SendListener.php deleted file mode 100644 index d922e1b..0000000 --- a/lib/SwiftMailer/classes/Swift/Events/SendListener.php +++ /dev/null @@ -1,31 +0,0 @@ -_eventMap = array( - 'Swift_Events_CommandEvent' => 'Swift_Events_CommandListener', - 'Swift_Events_ResponseEvent' => 'Swift_Events_ResponseListener', - 'Swift_Events_SendEvent' => 'Swift_Events_SendListener', - 'Swift_Events_TransportChangeEvent' => 'Swift_Events_TransportChangeListener', - 'Swift_Events_TransportExceptionEvent' => 'Swift_Events_TransportExceptionListener', - ); - } - - /** - * Create a new SendEvent for $source and $message. - * - * @param Swift_Transport $source - * @param Swift_Mime_Message - * - * @return Swift_Events_SendEvent - */ - public function createSendEvent(Swift_Transport $source, Swift_Mime_Message $message) - { - return new Swift_Events_SendEvent($source, $message); - } - - /** - * Create a new CommandEvent for $source and $command. - * - * @param Swift_Transport $source - * @param string $command That will be executed - * @param array $successCodes That are needed - * - * @return Swift_Events_CommandEvent - */ - public function createCommandEvent(Swift_Transport $source, $command, $successCodes = array()) - { - return new Swift_Events_CommandEvent($source, $command, $successCodes); - } - - /** - * Create a new ResponseEvent for $source and $response. - * - * @param Swift_Transport $source - * @param string $response - * @param bool $valid If the response is valid - * - * @return Swift_Events_ResponseEvent - */ - public function createResponseEvent(Swift_Transport $source, $response, $valid) - { - return new Swift_Events_ResponseEvent($source, $response, $valid); - } - - /** - * Create a new TransportChangeEvent for $source. - * - * @param Swift_Transport $source - * - * @return Swift_Events_TransportChangeEvent - */ - public function createTransportChangeEvent(Swift_Transport $source) - { - return new Swift_Events_TransportChangeEvent($source); - } - - /** - * Create a new TransportExceptionEvent for $source. - * - * @param Swift_Transport $source - * @param Swift_TransportException $ex - * - * @return Swift_Events_TransportExceptionEvent - */ - public function createTransportExceptionEvent(Swift_Transport $source, Swift_TransportException $ex) - { - return new Swift_Events_TransportExceptionEvent($source, $ex); - } - - /** - * Bind an event listener to this dispatcher. - * - * @param Swift_Events_EventListener $listener - */ - public function bindEventListener(Swift_Events_EventListener $listener) - { - foreach ($this->_listeners as $l) { - // Already loaded - if ($l === $listener) { - return; - } - } - $this->_listeners[] = $listener; - } - - /** - * Dispatch the given Event to all suitable listeners. - * - * @param Swift_Events_EventObject $evt - * @param string $target method - */ - public function dispatchEvent(Swift_Events_EventObject $evt, $target) - { - $this->_prepareBubbleQueue($evt); - $this->_bubble($evt, $target); - } - - /** Queue listeners on a stack ready for $evt to be bubbled up it */ - private function _prepareBubbleQueue(Swift_Events_EventObject $evt) - { - $this->_bubbleQueue = array(); - $evtClass = get_class($evt); - foreach ($this->_listeners as $listener) { - if (array_key_exists($evtClass, $this->_eventMap) - && ($listener instanceof $this->_eventMap[$evtClass])) { - $this->_bubbleQueue[] = $listener; - } - } - } - - /** Bubble $evt up the stack calling $target() on each listener */ - private function _bubble(Swift_Events_EventObject $evt, $target) - { - if (!$evt->bubbleCancelled() && $listener = array_shift($this->_bubbleQueue)) { - $listener->$target($evt); - $this->_bubble($evt, $target); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Events/TransportChangeEvent.php b/lib/SwiftMailer/classes/Swift/Events/TransportChangeEvent.php deleted file mode 100644 index a8972fd..0000000 --- a/lib/SwiftMailer/classes/Swift/Events/TransportChangeEvent.php +++ /dev/null @@ -1,27 +0,0 @@ -getSource(); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Events/TransportChangeListener.php b/lib/SwiftMailer/classes/Swift/Events/TransportChangeListener.php deleted file mode 100644 index 253165d..0000000 --- a/lib/SwiftMailer/classes/Swift/Events/TransportChangeListener.php +++ /dev/null @@ -1,45 +0,0 @@ -_exception = $ex; - } - - /** - * Get the TransportException thrown. - * - * @return Swift_TransportException - */ - public function getException() - { - return $this->_exception; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Events/TransportExceptionListener.php b/lib/SwiftMailer/classes/Swift/Events/TransportExceptionListener.php deleted file mode 100644 index cc3c099..0000000 --- a/lib/SwiftMailer/classes/Swift/Events/TransportExceptionListener.php +++ /dev/null @@ -1,24 +0,0 @@ -createDependenciesFor('transport.failover') - ); - - $this->setTransports($transports); - } - - /** - * Create a new FailoverTransport instance. - * - * @param Swift_Transport[] $transports - * - * @return Swift_FailoverTransport - */ - public static function newInstance($transports = array()) - { - return new self($transports); - } -} diff --git a/lib/SwiftMailer/classes/Swift/FileSpool.php b/lib/SwiftMailer/classes/Swift/FileSpool.php deleted file mode 100644 index c82c5db..0000000 --- a/lib/SwiftMailer/classes/Swift/FileSpool.php +++ /dev/null @@ -1,208 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Stores Messages on the filesystem. - * - * @author Fabien Potencier - * @author Xavier De Cock - */ -class Swift_FileSpool extends Swift_ConfigurableSpool -{ - /** The spool directory */ - private $_path; - - /** - * File WriteRetry Limit. - * - * @var int - */ - private $_retryLimit = 10; - - /** - * Create a new FileSpool. - * - * @param string $path - * - * @throws Swift_IoException - */ - public function __construct($path) - { - $this->_path = $path; - - if (!file_exists($this->_path)) { - if (!mkdir($this->_path, 0777, true)) { - throw new Swift_IoException(sprintf('Unable to create path "%s".', $this->_path)); - } - } - } - - /** - * Tests if this Spool mechanism has started. - * - * @return bool - */ - public function isStarted() - { - return true; - } - - /** - * Starts this Spool mechanism. - */ - public function start() - { - } - - /** - * Stops this Spool mechanism. - */ - public function stop() - { - } - - /** - * Allow to manage the enqueuing retry limit. - * - * Default, is ten and allows over 64^20 different fileNames - * - * @param int $limit - */ - public function setRetryLimit($limit) - { - $this->_retryLimit = $limit; - } - - /** - * Queues a message. - * - * @param Swift_Mime_Message $message The message to store - * - * @throws Swift_IoException - * - * @return bool - */ - public function queueMessage(Swift_Mime_Message $message) - { - $ser = serialize($message); - $fileName = $this->_path.'/'.$this->getRandomString(10); - for ($i = 0; $i < $this->_retryLimit; ++$i) { - /* We try an exclusive creation of the file. This is an atomic operation, it avoid locking mechanism */ - $fp = @fopen($fileName.'.message', 'x'); - if (false !== $fp) { - if (false === fwrite($fp, $ser)) { - return false; - } - - return fclose($fp); - } else { - /* The file already exists, we try a longer fileName */ - $fileName .= $this->getRandomString(1); - } - } - - throw new Swift_IoException(sprintf('Unable to create a file for enqueuing Message in "%s".', $this->_path)); - } - - /** - * Execute a recovery if for any reason a process is sending for too long. - * - * @param int $timeout in second Defaults is for very slow smtp responses - */ - public function recover($timeout = 900) - { - foreach (new DirectoryIterator($this->_path) as $file) { - $file = $file->getRealPath(); - - if (substr($file, -16) == '.message.sending') { - $lockedtime = filectime($file); - if ((time() - $lockedtime) > $timeout) { - rename($file, substr($file, 0, -8)); - } - } - } - } - - /** - * Sends messages using the given transport instance. - * - * @param Swift_Transport $transport A transport instance - * @param string[] $failedRecipients An array of failures by-reference - * - * @return int The number of sent e-mail's - */ - public function flushQueue(Swift_Transport $transport, &$failedRecipients = null) - { - $directoryIterator = new DirectoryIterator($this->_path); - - /* Start the transport only if there are queued files to send */ - if (!$transport->isStarted()) { - foreach ($directoryIterator as $file) { - if (substr($file->getRealPath(), -8) == '.message') { - $transport->start(); - break; - } - } - } - - $failedRecipients = (array) $failedRecipients; - $count = 0; - $time = time(); - foreach ($directoryIterator as $file) { - $file = $file->getRealPath(); - - if (substr($file, -8) != '.message') { - continue; - } - - /* We try a rename, it's an atomic operation, and avoid locking the file */ - if (rename($file, $file.'.sending')) { - $message = unserialize(file_get_contents($file.'.sending')); - - $count += $transport->send($message, $failedRecipients); - - unlink($file.'.sending'); - } else { - /* This message has just been catched by another process */ - continue; - } - - if ($this->getMessageLimit() && $count >= $this->getMessageLimit()) { - break; - } - - if ($this->getTimeLimit() && (time() - $time) >= $this->getTimeLimit()) { - break; - } - } - - return $count; - } - - /** - * Returns a random string needed to generate a fileName for the queue. - * - * @param int $count - * - * @return string - */ - protected function getRandomString($count) - { - // This string MUST stay FS safe, avoid special chars - $base = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-'; - $ret = ''; - $strlen = strlen($base); - for ($i = 0; $i < $count; ++$i) { - $ret .= $base[((int) rand(0, $strlen - 1))]; - } - - return $ret; - } -} diff --git a/lib/SwiftMailer/classes/Swift/FileStream.php b/lib/SwiftMailer/classes/Swift/FileStream.php deleted file mode 100644 index 0b24db1..0000000 --- a/lib/SwiftMailer/classes/Swift/FileStream.php +++ /dev/null @@ -1,24 +0,0 @@ -setFile( - new Swift_ByteStream_FileByteStream($path) - ); - - return $image; - } -} diff --git a/lib/SwiftMailer/classes/Swift/InputByteStream.php b/lib/SwiftMailer/classes/Swift/InputByteStream.php deleted file mode 100644 index 56efc75..0000000 --- a/lib/SwiftMailer/classes/Swift/InputByteStream.php +++ /dev/null @@ -1,75 +0,0 @@ -_stream = $stream; - } - - /** - * Set a string into the cache under $itemKey for the namespace $nsKey. - * - * @see MODE_WRITE, MODE_APPEND - * - * @param string $nsKey - * @param string $itemKey - * @param string $string - * @param int $mode - */ - public function setString($nsKey, $itemKey, $string, $mode) - { - $this->_prepareCache($nsKey); - switch ($mode) { - case self::MODE_WRITE: - $this->_contents[$nsKey][$itemKey] = $string; - break; - case self::MODE_APPEND: - if (!$this->hasKey($nsKey, $itemKey)) { - $this->_contents[$nsKey][$itemKey] = ''; - } - $this->_contents[$nsKey][$itemKey] .= $string; - break; - default: - throw new Swift_SwiftException( - 'Invalid mode ['.$mode.'] used to set nsKey='. - $nsKey.', itemKey='.$itemKey - ); - } - } - - /** - * Set a ByteStream into the cache under $itemKey for the namespace $nsKey. - * - * @see MODE_WRITE, MODE_APPEND - * - * @param string $nsKey - * @param string $itemKey - * @param Swift_OutputByteStream $os - * @param int $mode - */ - public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, $mode) - { - $this->_prepareCache($nsKey); - switch ($mode) { - case self::MODE_WRITE: - $this->clearKey($nsKey, $itemKey); - case self::MODE_APPEND: - if (!$this->hasKey($nsKey, $itemKey)) { - $this->_contents[$nsKey][$itemKey] = ''; - } - while (false !== $bytes = $os->read(8192)) { - $this->_contents[$nsKey][$itemKey] .= $bytes; - } - break; - default: - throw new Swift_SwiftException( - 'Invalid mode ['.$mode.'] used to set nsKey='. - $nsKey.', itemKey='.$itemKey - ); - } - } - - /** - * Provides a ByteStream which when written to, writes data to $itemKey. - * - * NOTE: The stream will always write in append mode. - * - * @param string $nsKey - * @param string $itemKey - * @param Swift_InputByteStream $writeThrough - * - * @return Swift_InputByteStream - */ - public function getInputByteStream($nsKey, $itemKey, Swift_InputByteStream $writeThrough = null) - { - $is = clone $this->_stream; - $is->setKeyCache($this); - $is->setNsKey($nsKey); - $is->setItemKey($itemKey); - if (isset($writeThrough)) { - $is->setWriteThroughStream($writeThrough); - } - - return $is; - } - - /** - * Get data back out of the cache as a string. - * - * @param string $nsKey - * @param string $itemKey - * - * @return string - */ - public function getString($nsKey, $itemKey) - { - $this->_prepareCache($nsKey); - if ($this->hasKey($nsKey, $itemKey)) { - return $this->_contents[$nsKey][$itemKey]; - } - } - - /** - * Get data back out of the cache as a ByteStream. - * - * @param string $nsKey - * @param string $itemKey - * @param Swift_InputByteStream $is to write the data to - */ - public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is) - { - $this->_prepareCache($nsKey); - $is->write($this->getString($nsKey, $itemKey)); - } - - /** - * Check if the given $itemKey exists in the namespace $nsKey. - * - * @param string $nsKey - * @param string $itemKey - * - * @return bool - */ - public function hasKey($nsKey, $itemKey) - { - $this->_prepareCache($nsKey); - - return array_key_exists($itemKey, $this->_contents[$nsKey]); - } - - /** - * Clear data for $itemKey in the namespace $nsKey if it exists. - * - * @param string $nsKey - * @param string $itemKey - */ - public function clearKey($nsKey, $itemKey) - { - unset($this->_contents[$nsKey][$itemKey]); - } - - /** - * Clear all data in the namespace $nsKey if it exists. - * - * @param string $nsKey - */ - public function clearAll($nsKey) - { - unset($this->_contents[$nsKey]); - } - - /** - * Initialize the namespace of $nsKey if needed. - * - * @param string $nsKey - */ - private function _prepareCache($nsKey) - { - if (!array_key_exists($nsKey, $this->_contents)) { - $this->_contents[$nsKey] = array(); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/KeyCache/DiskKeyCache.php b/lib/SwiftMailer/classes/Swift/KeyCache/DiskKeyCache.php deleted file mode 100644 index 453f50a..0000000 --- a/lib/SwiftMailer/classes/Swift/KeyCache/DiskKeyCache.php +++ /dev/null @@ -1,321 +0,0 @@ -_stream = $stream; - $this->_path = $path; - - if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) { - $this->_quotes = true; - } - } - - /** - * Set a string into the cache under $itemKey for the namespace $nsKey. - * - * @see MODE_WRITE, MODE_APPEND - * - * @param string $nsKey - * @param string $itemKey - * @param string $string - * @param int $mode - * - * @throws Swift_IoException - */ - public function setString($nsKey, $itemKey, $string, $mode) - { - $this->_prepareCache($nsKey); - switch ($mode) { - case self::MODE_WRITE: - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); - break; - case self::MODE_APPEND: - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END); - break; - default: - throw new Swift_SwiftException( - 'Invalid mode ['.$mode.'] used to set nsKey='. - $nsKey.', itemKey='.$itemKey - ); - break; - } - fwrite($fp, $string); - $this->_freeHandle($nsKey, $itemKey); - } - - /** - * Set a ByteStream into the cache under $itemKey for the namespace $nsKey. - * - * @see MODE_WRITE, MODE_APPEND - * - * @param string $nsKey - * @param string $itemKey - * @param Swift_OutputByteStream $os - * @param int $mode - * - * @throws Swift_IoException - */ - public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, $mode) - { - $this->_prepareCache($nsKey); - switch ($mode) { - case self::MODE_WRITE: - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); - break; - case self::MODE_APPEND: - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END); - break; - default: - throw new Swift_SwiftException( - 'Invalid mode ['.$mode.'] used to set nsKey='. - $nsKey.', itemKey='.$itemKey - ); - break; - } - while (false !== $bytes = $os->read(8192)) { - fwrite($fp, $bytes); - } - $this->_freeHandle($nsKey, $itemKey); - } - - /** - * Provides a ByteStream which when written to, writes data to $itemKey. - * - * NOTE: The stream will always write in append mode. - * - * @param string $nsKey - * @param string $itemKey - * @param Swift_InputByteStream $writeThrough - * - * @return Swift_InputByteStream - */ - public function getInputByteStream($nsKey, $itemKey, Swift_InputByteStream $writeThrough = null) - { - $is = clone $this->_stream; - $is->setKeyCache($this); - $is->setNsKey($nsKey); - $is->setItemKey($itemKey); - if (isset($writeThrough)) { - $is->setWriteThroughStream($writeThrough); - } - - return $is; - } - - /** - * Get data back out of the cache as a string. - * - * @param string $nsKey - * @param string $itemKey - * - * @throws Swift_IoException - * - * @return string - */ - public function getString($nsKey, $itemKey) - { - $this->_prepareCache($nsKey); - if ($this->hasKey($nsKey, $itemKey)) { - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); - if ($this->_quotes) { - ini_set('magic_quotes_runtime', 0); - } - $str = ''; - while (!feof($fp) && false !== $bytes = fread($fp, 8192)) { - $str .= $bytes; - } - if ($this->_quotes) { - ini_set('magic_quotes_runtime', 1); - } - $this->_freeHandle($nsKey, $itemKey); - - return $str; - } - } - - /** - * Get data back out of the cache as a ByteStream. - * - * @param string $nsKey - * @param string $itemKey - * @param Swift_InputByteStream $is to write the data to - */ - public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is) - { - if ($this->hasKey($nsKey, $itemKey)) { - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); - if ($this->_quotes) { - ini_set('magic_quotes_runtime', 0); - } - while (!feof($fp) && false !== $bytes = fread($fp, 8192)) { - $is->write($bytes); - } - if ($this->_quotes) { - ini_set('magic_quotes_runtime', 1); - } - $this->_freeHandle($nsKey, $itemKey); - } - } - - /** - * Check if the given $itemKey exists in the namespace $nsKey. - * - * @param string $nsKey - * @param string $itemKey - * - * @return bool - */ - public function hasKey($nsKey, $itemKey) - { - return is_file($this->_path.'/'.$nsKey.'/'.$itemKey); - } - - /** - * Clear data for $itemKey in the namespace $nsKey if it exists. - * - * @param string $nsKey - * @param string $itemKey - */ - public function clearKey($nsKey, $itemKey) - { - if ($this->hasKey($nsKey, $itemKey)) { - $this->_freeHandle($nsKey, $itemKey); - unlink($this->_path.'/'.$nsKey.'/'.$itemKey); - } - } - - /** - * Clear all data in the namespace $nsKey if it exists. - * - * @param string $nsKey - */ - public function clearAll($nsKey) - { - if (array_key_exists($nsKey, $this->_keys)) { - foreach ($this->_keys[$nsKey] as $itemKey => $null) { - $this->clearKey($nsKey, $itemKey); - } - if (is_dir($this->_path.'/'.$nsKey)) { - rmdir($this->_path.'/'.$nsKey); - } - unset($this->_keys[$nsKey]); - } - } - - /** - * Initialize the namespace of $nsKey if needed. - * - * @param string $nsKey - */ - private function _prepareCache($nsKey) - { - $cacheDir = $this->_path.'/'.$nsKey; - if (!is_dir($cacheDir)) { - if (!mkdir($cacheDir)) { - throw new Swift_IoException('Failed to create cache directory '.$cacheDir); - } - $this->_keys[$nsKey] = array(); - } - } - - /** - * Get a file handle on the cache item. - * - * @param string $nsKey - * @param string $itemKey - * @param int $position - * - * @return resource - */ - private function _getHandle($nsKey, $itemKey, $position) - { - if (!isset($this->_keys[$nsKey][$itemKey])) { - $openMode = $this->hasKey($nsKey, $itemKey) ? 'r+b' : 'w+b'; - $fp = fopen($this->_path.'/'.$nsKey.'/'.$itemKey, $openMode); - $this->_keys[$nsKey][$itemKey] = $fp; - } - if (self::POSITION_START == $position) { - fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_SET); - } elseif (self::POSITION_END == $position) { - fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_END); - } - - return $this->_keys[$nsKey][$itemKey]; - } - - private function _freeHandle($nsKey, $itemKey) - { - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_CURRENT); - fclose($fp); - $this->_keys[$nsKey][$itemKey] = null; - } - - /** - * Destructor. - */ - public function __destruct() - { - foreach ($this->_keys as $nsKey => $null) { - $this->clearAll($nsKey); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/KeyCache/KeyCacheInputStream.php b/lib/SwiftMailer/classes/Swift/KeyCache/KeyCacheInputStream.php deleted file mode 100644 index af80bdc..0000000 --- a/lib/SwiftMailer/classes/Swift/KeyCache/KeyCacheInputStream.php +++ /dev/null @@ -1,51 +0,0 @@ -_keyCache = $keyCache; - } - - /** - * Specify a stream to write through for each write(). - * - * @param Swift_InputByteStream $is - */ - public function setWriteThroughStream(Swift_InputByteStream $is) - { - $this->_writeThrough = $is; - } - - /** - * Writes $bytes to the end of the stream. - * - * @param string $bytes - * @param Swift_InputByteStream $is optional - */ - public function write($bytes, Swift_InputByteStream $is = null) - { - $this->_keyCache->setString( - $this->_nsKey, $this->_itemKey, $bytes, Swift_KeyCache::MODE_APPEND - ); - if (isset($is)) { - $is->write($bytes); - } - if (isset($this->_writeThrough)) { - $this->_writeThrough->write($bytes); - } - } - - /** - * Not used. - */ - public function commit() - { - } - - /** - * Not used. - */ - public function bind(Swift_InputByteStream $is) - { - } - - /** - * Not used. - */ - public function unbind(Swift_InputByteStream $is) - { - } - - /** - * Flush the contents of the stream (empty it) and set the internal pointer - * to the beginning. - */ - public function flushBuffers() - { - $this->_keyCache->clearKey($this->_nsKey, $this->_itemKey); - } - - /** - * Set the nsKey which will be written to. - * - * @param string $nsKey - */ - public function setNsKey($nsKey) - { - $this->_nsKey = $nsKey; - } - - /** - * Set the itemKey which will be written to. - * - * @param string $itemKey - */ - public function setItemKey($itemKey) - { - $this->_itemKey = $itemKey; - } - - /** - * Any implementation should be cloneable, allowing the clone to access a - * separate $nsKey and $itemKey. - */ - public function __clone() - { - $this->_writeThrough = null; - } -} diff --git a/lib/SwiftMailer/classes/Swift/LoadBalancedTransport.php b/lib/SwiftMailer/classes/Swift/LoadBalancedTransport.php deleted file mode 100644 index fdba9df..0000000 --- a/lib/SwiftMailer/classes/Swift/LoadBalancedTransport.php +++ /dev/null @@ -1,45 +0,0 @@ -createDependenciesFor('transport.loadbalanced') - ); - - $this->setTransports($transports); - } - - /** - * Create a new LoadBalancedTransport instance. - * - * @param array $transports - * - * @return Swift_LoadBalancedTransport - */ - public static function newInstance($transports = array()) - { - return new self($transports); - } -} diff --git a/lib/SwiftMailer/classes/Swift/MailTransport.php b/lib/SwiftMailer/classes/Swift/MailTransport.php deleted file mode 100644 index 858ca81..0000000 --- a/lib/SwiftMailer/classes/Swift/MailTransport.php +++ /dev/null @@ -1,45 +0,0 @@ -createDependenciesFor('transport.mail') - ); - - $this->setExtraParams($extraParams); - } - - /** - * Create a new MailTransport instance. - * - * @param string $extraParams To be passed to mail() - * - * @return Swift_MailTransport - */ - public static function newInstance($extraParams = '-f%s') - { - return new self($extraParams); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mailer.php b/lib/SwiftMailer/classes/Swift/Mailer.php deleted file mode 100644 index 6411546..0000000 --- a/lib/SwiftMailer/classes/Swift/Mailer.php +++ /dev/null @@ -1,114 +0,0 @@ -_transport = $transport; - } - - /** - * Create a new Mailer instance. - * - * @param Swift_Transport $transport - * - * @return Swift_Mailer - */ - public static function newInstance(Swift_Transport $transport) - { - return new self($transport); - } - - /** - * Create a new class instance of one of the message services. - * - * For example 'mimepart' would create a 'message.mimepart' instance - * - * @param string $service - * - * @return object - */ - public function createMessage($service = 'message') - { - return Swift_DependencyContainer::getInstance() - ->lookup('message.'.$service); - } - - /** - * Send the given Message like it would be sent in a mail client. - * - * All recipients (with the exception of Bcc) will be able to see the other - * recipients this message was sent to. - * - * Recipient/sender data will be retrieved from the Message object. - * - * The return value is the number of recipients who were accepted for - * delivery. - * - * @param Swift_Mime_Message $message - * @param array $failedRecipients An array of failures by-reference - * - * @return int The number of successful recipients. Can be 0 which indicates failure - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - $failedRecipients = (array) $failedRecipients; - - if (!$this->_transport->isStarted()) { - $this->_transport->start(); - } - - $sent = 0; - - try { - $sent = $this->_transport->send($message, $failedRecipients); - } catch (Swift_RfcComplianceException $e) { - foreach ($message->getTo() as $address => $name) { - $failedRecipients[] = $address; - } - } - - return $sent; - } - - /** - * Register a plugin using a known unique key (e.g. myPlugin). - * - * @param Swift_Events_EventListener $plugin - */ - public function registerPlugin(Swift_Events_EventListener $plugin) - { - $this->_transport->registerPlugin($plugin); - } - - /** - * The Transport used to send messages. - * - * @return Swift_Transport - */ - public function getTransport() - { - return $this->_transport; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mailer/ArrayRecipientIterator.php b/lib/SwiftMailer/classes/Swift/Mailer/ArrayRecipientIterator.php deleted file mode 100644 index e3e6cad..0000000 --- a/lib/SwiftMailer/classes/Swift/Mailer/ArrayRecipientIterator.php +++ /dev/null @@ -1,55 +0,0 @@ -_recipients = $recipients; - } - - /** - * Returns true only if there are more recipients to send to. - * - * @return bool - */ - public function hasNext() - { - return !empty($this->_recipients); - } - - /** - * Returns an array where the keys are the addresses of recipients and the - * values are the names. e.g. ('foo@bar' => 'Foo') or ('foo@bar' => NULL). - * - * @return array - */ - public function nextRecipient() - { - return array_splice($this->_recipients, 0, 1); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mailer/RecipientIterator.php b/lib/SwiftMailer/classes/Swift/Mailer/RecipientIterator.php deleted file mode 100644 index 650f3ec..0000000 --- a/lib/SwiftMailer/classes/Swift/Mailer/RecipientIterator.php +++ /dev/null @@ -1,32 +0,0 @@ - 'Foo') or ('foo@bar' => NULL). - * - * @return array - */ - public function nextRecipient(); -} diff --git a/lib/SwiftMailer/classes/Swift/MemorySpool.php b/lib/SwiftMailer/classes/Swift/MemorySpool.php deleted file mode 100644 index 2cafb67..0000000 --- a/lib/SwiftMailer/classes/Swift/MemorySpool.php +++ /dev/null @@ -1,110 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Stores Messages in memory. - * - * @author Fabien Potencier - */ -class Swift_MemorySpool implements Swift_Spool -{ - protected $messages = array(); - private $flushRetries = 3; - - /** - * Tests if this Transport mechanism has started. - * - * @return bool - */ - public function isStarted() - { - return true; - } - - /** - * Starts this Transport mechanism. - */ - public function start() - { - } - - /** - * Stops this Transport mechanism. - */ - public function stop() - { - } - - /** - * @param int $retries - */ - public function setFlushRetries($retries) - { - $this->flushRetries = $retries; - } - - /** - * Stores a message in the queue. - * - * @param Swift_Mime_Message $message The message to store - * - * @return bool Whether the operation has succeeded - */ - public function queueMessage(Swift_Mime_Message $message) - { - //clone the message to make sure it is not changed while in the queue - $this->messages[] = clone $message; - - return true; - } - - /** - * Sends messages using the given transport instance. - * - * @param Swift_Transport $transport A transport instance - * @param string[] $failedRecipients An array of failures by-reference - * - * @return int The number of sent emails - */ - public function flushQueue(Swift_Transport $transport, &$failedRecipients = null) - { - if (!$this->messages) { - return 0; - } - - if (!$transport->isStarted()) { - $transport->start(); - } - - $count = 0; - $retries = $this->flushRetries; - while ($retries--) { - try { - while ($message = array_pop($this->messages)) { - $count += $transport->send($message, $failedRecipients); - } - } catch (Swift_TransportException $exception) { - if ($retries) { - // re-queue the message at the end of the queue to give a chance - // to the other messages to be sent, in case the failure was due to - // this message and not just the transport failing - array_unshift($this->messages, $message); - - // wait half a second before we try again - usleep(500000); - } else { - throw $exception; - } - } - } - - return $count; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Message.php b/lib/SwiftMailer/classes/Swift/Message.php deleted file mode 100644 index 5f75b93..0000000 --- a/lib/SwiftMailer/classes/Swift/Message.php +++ /dev/null @@ -1,291 +0,0 @@ -createDependenciesFor('mime.message') - ); - - if (!isset($charset)) { - $charset = Swift_DependencyContainer::getInstance() - ->lookup('properties.charset'); - } - $this->setSubject($subject); - $this->setBody($body); - $this->setCharset($charset); - if ($contentType) { - $this->setContentType($contentType); - } - } - - /** - * Create a new Message. - * - * @param string $subject - * @param string $body - * @param string $contentType - * @param string $charset - * - * @return Swift_Message - */ - public static function newInstance($subject = null, $body = null, $contentType = null, $charset = null) - { - return new self($subject, $body, $contentType, $charset); - } - - /** - * Add a MimePart to this Message. - * - * @param string|Swift_OutputByteStream $body - * @param string $contentType - * @param string $charset - * - * @return Swift_Mime_SimpleMessage - */ - public function addPart($body, $contentType = null, $charset = null) - { - return $this->attach(Swift_MimePart::newInstance( - $body, $contentType, $charset - )); - } - - /** - * Detach a signature handler from a message. - * - * @param Swift_Signer $signer - * - * @return Swift_Message - */ - public function attachSigner(Swift_Signer $signer) - { - if ($signer instanceof Swift_Signers_HeaderSigner) { - $this->headerSigners[] = $signer; - } elseif ($signer instanceof Swift_Signers_BodySigner) { - $this->bodySigners[] = $signer; - } - - return $this; - } - - /** - * Attach a new signature handler to the message. - * - * @param Swift_Signer $signer - * - * @return Swift_Message - */ - public function detachSigner(Swift_Signer $signer) - { - if ($signer instanceof Swift_Signers_HeaderSigner) { - foreach ($this->headerSigners as $k => $headerSigner) { - if ($headerSigner === $signer) { - unset($this->headerSigners[$k]); - - return $this; - } - } - } elseif ($signer instanceof Swift_Signers_BodySigner) { - foreach ($this->bodySigners as $k => $bodySigner) { - if ($bodySigner === $signer) { - unset($this->bodySigners[$k]); - - return $this; - } - } - } - - return $this; - } - - /** - * Get this message as a complete string. - * - * @return string - */ - public function toString() - { - if (empty($this->headerSigners) && empty($this->bodySigners)) { - return parent::toString(); - } - - $this->saveMessage(); - - $this->doSign(); - - $string = parent::toString(); - - $this->restoreMessage(); - - return $string; - } - - /** - * Write this message to a {@link Swift_InputByteStream}. - * - * @param Swift_InputByteStream $is - */ - public function toByteStream(Swift_InputByteStream $is) - { - if (empty($this->headerSigners) && empty($this->bodySigners)) { - parent::toByteStream($is); - - return; - } - - $this->saveMessage(); - - $this->doSign(); - - parent::toByteStream($is); - - $this->restoreMessage(); - } - - public function __wakeup() - { - Swift_DependencyContainer::getInstance()->createDependenciesFor('mime.message'); - } - - /** - * loops through signers and apply the signatures. - */ - protected function doSign() - { - foreach ($this->bodySigners as $signer) { - $altered = $signer->getAlteredHeaders(); - $this->saveHeaders($altered); - $signer->signMessage($this); - } - - foreach ($this->headerSigners as $signer) { - $altered = $signer->getAlteredHeaders(); - $this->saveHeaders($altered); - $signer->reset(); - - $signer->setHeaders($this->getHeaders()); - - $signer->startBody(); - $this->_bodyToByteStream($signer); - $signer->endBody(); - - $signer->addSignature($this->getHeaders()); - } - } - - /** - * save the message before any signature is applied. - */ - protected function saveMessage() - { - $this->savedMessage = array('headers' => array()); - $this->savedMessage['body'] = $this->getBody(); - $this->savedMessage['children'] = $this->getChildren(); - if (count($this->savedMessage['children']) > 0 && $this->getBody() != '') { - $this->setChildren(array_merge(array($this->_becomeMimePart()), $this->savedMessage['children'])); - $this->setBody(''); - } - } - - /** - * save the original headers. - * - * @param array $altered - */ - protected function saveHeaders(array $altered) - { - foreach ($altered as $head) { - $lc = strtolower($head); - - if (!isset($this->savedMessage['headers'][$lc])) { - $this->savedMessage['headers'][$lc] = $this->getHeaders()->getAll($head); - } - } - } - - /** - * Remove or restore altered headers. - */ - protected function restoreHeaders() - { - foreach ($this->savedMessage['headers'] as $name => $savedValue) { - $headers = $this->getHeaders()->getAll($name); - - foreach ($headers as $key => $value) { - if (!isset($savedValue[$key])) { - $this->getHeaders()->remove($name, $key); - } - } - } - } - - /** - * Restore message body. - */ - protected function restoreMessage() - { - $this->setBody($this->savedMessage['body']); - $this->setChildren($this->savedMessage['children']); - - $this->restoreHeaders(); - $this->savedMessage = array(); - } - - /** - * Clone Message Signers. - * - * @see Swift_Mime_SimpleMimeEntity::__clone() - */ - public function __clone() - { - parent::__clone(); - foreach ($this->bodySigners as $key => $bodySigner) { - $this->bodySigners[$key] = clone($bodySigner); - } - - foreach ($this->headerSigners as $key => $headerSigner) { - $this->headerSigners[$key] = clone($headerSigner); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/Attachment.php b/lib/SwiftMailer/classes/Swift/Mime/Attachment.php deleted file mode 100644 index 46a5e8d..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/Attachment.php +++ /dev/null @@ -1,149 +0,0 @@ -setDisposition('attachment'); - $this->setContentType('application/octet-stream'); - $this->_mimeTypes = $mimeTypes; - } - - /** - * Get the nesting level used for this attachment. - * - * Always returns {@link LEVEL_MIXED}. - * - * @return int - */ - public function getNestingLevel() - { - return self::LEVEL_MIXED; - } - - /** - * Get the Content-Disposition of this attachment. - * - * By default attachments have a disposition of "attachment". - * - * @return string - */ - public function getDisposition() - { - return $this->_getHeaderFieldModel('Content-Disposition'); - } - - /** - * Set the Content-Disposition of this attachment. - * - * @param string $disposition - * - * @return Swift_Mime_Attachment - */ - public function setDisposition($disposition) - { - if (!$this->_setHeaderFieldModel('Content-Disposition', $disposition)) { - $this->getHeaders()->addParameterizedHeader('Content-Disposition', $disposition); - } - - return $this; - } - - /** - * Get the filename of this attachment when downloaded. - * - * @return string - */ - public function getFilename() - { - return $this->_getHeaderParameter('Content-Disposition', 'filename'); - } - - /** - * Set the filename of this attachment. - * - * @param string $filename - * - * @return Swift_Mime_Attachment - */ - public function setFilename($filename) - { - $this->_setHeaderParameter('Content-Disposition', 'filename', $filename); - $this->_setHeaderParameter('Content-Type', 'name', $filename); - - return $this; - } - - /** - * Get the file size of this attachment. - * - * @return int - */ - public function getSize() - { - return $this->_getHeaderParameter('Content-Disposition', 'size'); - } - - /** - * Set the file size of this attachment. - * - * @param int $size - * - * @return Swift_Mime_Attachment - */ - public function setSize($size) - { - $this->_setHeaderParameter('Content-Disposition', 'size', $size); - - return $this; - } - - /** - * Set the file that this attachment is for. - * - * @param Swift_FileStream $file - * @param string $contentType optional - * - * @return Swift_Mime_Attachment - */ - public function setFile(Swift_FileStream $file, $contentType = null) - { - $this->setFilename(basename($file->getPath())); - $this->setBody($file, $contentType); - if (!isset($contentType)) { - $extension = strtolower(substr($file->getPath(), strrpos($file->getPath(), '.') + 1)); - - if (array_key_exists($extension, $this->_mimeTypes)) { - $this->setContentType($this->_mimeTypes[$extension]); - } - } - - return $this; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/CharsetObserver.php b/lib/SwiftMailer/classes/Swift/Mime/CharsetObserver.php deleted file mode 100644 index b49c3a8..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/CharsetObserver.php +++ /dev/null @@ -1,24 +0,0 @@ -= $maxLineLength || 76 < $maxLineLength) { - $maxLineLength = 76; - } - - $remainder = 0; - $base64ReadBufferRemainderBytes = null; - - // To reduce memory usage, the output buffer is streamed to the input buffer like so: - // Output Stream => base64encode => wrap line length => Input Stream - // HOWEVER it's important to note that base64_encode() should only be passed whole triplets of data (except for the final chunk of data) - // otherwise it will assume the input data has *ended* and it will incorrectly pad/terminate the base64 data mid-stream. - // We use $base64ReadBufferRemainderBytes to carry over 1-2 "remainder" bytes from the each chunk from OutputStream and pre-pend those onto the - // chunk of bytes read in the next iteration. - // When the OutputStream is empty, we must flush any remainder bytes. - while (true) { - $readBytes = $os->read(8192); - $atEOF = ($readBytes === false); - - if ($atEOF) { - $streamTheseBytes = $base64ReadBufferRemainderBytes; - } else { - $streamTheseBytes = $base64ReadBufferRemainderBytes.$readBytes; - } - $base64ReadBufferRemainderBytes = null; - $bytesLength = strlen($streamTheseBytes); - - if ($bytesLength === 0) { // no data left to encode - break; - } - - // if we're not on the last block of the ouput stream, make sure $streamTheseBytes ends with a complete triplet of data - // and carry over remainder 1-2 bytes to the next loop iteration - if (!$atEOF) { - $excessBytes = $bytesLength % 3; - if ($excessBytes !== 0) { - $base64ReadBufferRemainderBytes = substr($streamTheseBytes, -$excessBytes); - $streamTheseBytes = substr($streamTheseBytes, 0, $bytesLength - $excessBytes); - } - } - - $encoded = base64_encode($streamTheseBytes); - $encodedTransformed = ''; - $thisMaxLineLength = $maxLineLength - $remainder - $firstLineOffset; - - while ($thisMaxLineLength < strlen($encoded)) { - $encodedTransformed .= substr($encoded, 0, $thisMaxLineLength)."\r\n"; - $firstLineOffset = 0; - $encoded = substr($encoded, $thisMaxLineLength); - $thisMaxLineLength = $maxLineLength; - $remainder = 0; - } - - if (0 < $remainingLength = strlen($encoded)) { - $remainder += $remainingLength; - $encodedTransformed .= $encoded; - $encoded = null; - } - - $is->write($encodedTransformed); - - if ($atEOF) { - break; - } - } - } - - /** - * Get the name of this encoding scheme. - * Returns the string 'base64'. - * - * @return string - */ - public function getName() - { - return 'base64'; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php b/lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php deleted file mode 100644 index 710b5ac..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php +++ /dev/null @@ -1,123 +0,0 @@ -charset = $charset ? $charset : 'utf-8'; - } - - /** - * Notify this observer that the entity's charset has changed. - * - * @param string $charset - */ - public function charsetChanged($charset) - { - $this->charset = $charset; - } - - /** - * Encode $in to $out. - * - * @param Swift_OutputByteStream $os to read from - * @param Swift_InputByteStream $is to write to - * @param int $firstLineOffset - * @param int $maxLineLength 0 indicates the default length for this encoding - * - * @throws RuntimeException - */ - public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0) - { - if ($this->charset !== 'utf-8') { - throw new RuntimeException( - sprintf('Charset "%s" not supported. NativeQpContentEncoder only supports "utf-8"', $this->charset)); - } - - $string = ''; - - while (false !== $bytes = $os->read(8192)) { - $string .= $bytes; - } - - $is->write($this->encodeString($string)); - } - - /** - * Get the MIME name of this content encoding scheme. - * - * @return string - */ - public function getName() - { - return 'quoted-printable'; - } - - /** - * Encode a given string to produce an encoded string. - * - * @param string $string - * @param int $firstLineOffset if first line needs to be shorter - * @param int $maxLineLength 0 indicates the default length for this encoding - * - * @throws RuntimeException - * - * @return string - */ - public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) - { - if ($this->charset !== 'utf-8') { - throw new RuntimeException( - sprintf('Charset "%s" not supported. NativeQpContentEncoder only supports "utf-8"', $this->charset)); - } - - return $this->_standardize(quoted_printable_encode($string)); - } - - /** - * Make sure CRLF is correct and HT/SPACE are in valid places. - * - * @param string $string - * - * @return string - */ - protected function _standardize($string) - { - // transform CR or LF to CRLF - $string = preg_replace('~=0D(?!=0A)|(?_name = $name; - $this->_canonical = $canonical; - } - - /** - * Encode a given string to produce an encoded string. - * - * @param string $string - * @param int $firstLineOffset ignored - * @param int $maxLineLength - 0 means no wrapping will occur - * - * @return string - */ - public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) - { - if ($this->_canonical) { - $string = $this->_canonicalize($string); - } - - return $this->_safeWordWrap($string, $maxLineLength, "\r\n"); - } - - /** - * Encode stream $in to stream $out. - * - * @param Swift_OutputByteStream $os - * @param Swift_InputByteStream $is - * @param int $firstLineOffset ignored - * @param int $maxLineLength optional, 0 means no wrapping will occur - */ - public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0) - { - $leftOver = ''; - while (false !== $bytes = $os->read(8192)) { - $toencode = $leftOver.$bytes; - if ($this->_canonical) { - $toencode = $this->_canonicalize($toencode); - } - $wrapped = $this->_safeWordWrap($toencode, $maxLineLength, "\r\n"); - $lastLinePos = strrpos($wrapped, "\r\n"); - $leftOver = substr($wrapped, $lastLinePos); - $wrapped = substr($wrapped, 0, $lastLinePos); - - $is->write($wrapped); - } - if (strlen($leftOver)) { - $is->write($leftOver); - } - } - - /** - * Get the name of this encoding scheme. - * - * @return string - */ - public function getName() - { - return $this->_name; - } - - /** - * Not used. - */ - public function charsetChanged($charset) - { - } - - /** - * A safer (but weaker) wordwrap for unicode. - * - * @param string $string - * @param int $length - * @param string $le - * - * @return string - */ - private function _safeWordwrap($string, $length = 75, $le = "\r\n") - { - if (0 >= $length) { - return $string; - } - - $originalLines = explode($le, $string); - - $lines = array(); - $lineCount = 0; - - foreach ($originalLines as $originalLine) { - $lines[] = ''; - $currentLine = &$lines[$lineCount++]; - - //$chunks = preg_split('/(?<=[\ \t,\.!\?\-&\+\/])/', $originalLine); - $chunks = preg_split('/(?<=\s)/', $originalLine); - - foreach ($chunks as $chunk) { - if (0 != strlen($currentLine) - && strlen($currentLine.$chunk) > $length) { - $lines[] = ''; - $currentLine = &$lines[$lineCount++]; - } - $currentLine .= $chunk; - } - } - - return implode("\r\n", $lines); - } - - /** - * Canonicalize string input (fix CRLF). - * - * @param string $string - * - * @return string - */ - private function _canonicalize($string) - { - return str_replace( - array("\r\n", "\r", "\n"), - array("\n", "\n", "\r\n"), - $string - ); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php b/lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php deleted file mode 100644 index 5cc907b..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php +++ /dev/null @@ -1,134 +0,0 @@ -_dotEscape = $dotEscape; - parent::__construct($charStream, $filter); - } - - public function __sleep() - { - return array('_charStream', '_filter', '_dotEscape'); - } - - protected function getSafeMapShareId() - { - return get_class($this).($this->_dotEscape ? '.dotEscape' : ''); - } - - protected function initSafeMap() - { - parent::initSafeMap(); - if ($this->_dotEscape) { - /* Encode . as =2e for buggy remote servers */ - unset($this->_safeMap[0x2e]); - } - } - - /** - * Encode stream $in to stream $out. - * - * QP encoded strings have a maximum line length of 76 characters. - * If the first line needs to be shorter, indicate the difference with - * $firstLineOffset. - * - * @param Swift_OutputByteStream $os output stream - * @param Swift_InputByteStream $is input stream - * @param int $firstLineOffset - * @param int $maxLineLength - */ - public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0) - { - if ($maxLineLength > 76 || $maxLineLength <= 0) { - $maxLineLength = 76; - } - - $thisLineLength = $maxLineLength - $firstLineOffset; - - $this->_charStream->flushContents(); - $this->_charStream->importByteStream($os); - - $currentLine = ''; - $prepend = ''; - $size = $lineLen = 0; - - while (false !== $bytes = $this->_nextSequence()) { - // If we're filtering the input - if (isset($this->_filter)) { - // If we can't filter because we need more bytes - while ($this->_filter->shouldBuffer($bytes)) { - // Then collect bytes into the buffer - if (false === $moreBytes = $this->_nextSequence(1)) { - break; - } - - foreach ($moreBytes as $b) { - $bytes[] = $b; - } - } - // And filter them - $bytes = $this->_filter->filter($bytes); - } - - $enc = $this->_encodeByteSequence($bytes, $size); - - $i = strpos($enc, '=0D=0A'); - $newLineLength = $lineLen + ($i === false ? $size : $i); - - if ($currentLine && $newLineLength >= $thisLineLength) { - $is->write($prepend.$this->_standardize($currentLine)); - $currentLine = ''; - $prepend = "=\r\n"; - $thisLineLength = $maxLineLength; - $lineLen = 0; - } - - $currentLine .= $enc; - - if ($i === false) { - $lineLen += $size; - } else { - // 6 is the length of '=0D=0A'. - $lineLen = $size - strrpos($enc, '=0D=0A') - 6; - } - } - if (strlen($currentLine)) { - $is->write($prepend.$this->_standardize($currentLine)); - } - } - - /** - * Get the name of this encoding scheme. - * Returns the string 'quoted-printable'. - * - * @return string - */ - public function getName() - { - return 'quoted-printable'; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php b/lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php deleted file mode 100644 index 3214e1c..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php +++ /dev/null @@ -1,98 +0,0 @@ - - */ -class Swift_Mime_ContentEncoder_QpContentEncoderProxy implements Swift_Mime_ContentEncoder -{ - /** - * @var Swift_Mime_ContentEncoder_QpContentEncoder - */ - private $safeEncoder; - - /** - * @var Swift_Mime_ContentEncoder_NativeQpContentEncoder - */ - private $nativeEncoder; - - /** - * @var null|string - */ - private $charset; - - /** - * Constructor. - * - * @param Swift_Mime_ContentEncoder_QpContentEncoder $safeEncoder - * @param Swift_Mime_ContentEncoder_NativeQpContentEncoder $nativeEncoder - * @param string|null $charset - */ - public function __construct(Swift_Mime_ContentEncoder_QpContentEncoder $safeEncoder, Swift_Mime_ContentEncoder_NativeQpContentEncoder $nativeEncoder, $charset) - { - $this->safeEncoder = $safeEncoder; - $this->nativeEncoder = $nativeEncoder; - $this->charset = $charset; - } - - /** - * Make a deep copy of object. - */ - public function __clone() - { - $this->safeEncoder = clone $this->safeEncoder; - $this->nativeEncoder = clone $this->nativeEncoder; - } - - /** - * {@inheritdoc} - */ - public function charsetChanged($charset) - { - $this->charset = $charset; - $this->safeEncoder->charsetChanged($charset); - } - - /** - * {@inheritdoc} - */ - public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0) - { - $this->getEncoder()->encodeByteStream($os, $is, $firstLineOffset, $maxLineLength); - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'quoted-printable'; - } - - /** - * {@inheritdoc} - */ - public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) - { - return $this->getEncoder()->encodeString($string, $firstLineOffset, $maxLineLength); - } - - /** - * @return Swift_Mime_ContentEncoder - */ - private function getEncoder() - { - return 'utf-8' === $this->charset ? $this->nativeEncoder : $this->safeEncoder; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/RawContentEncoder.php b/lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/RawContentEncoder.php deleted file mode 100644 index 0b8526e..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/ContentEncoder/RawContentEncoder.php +++ /dev/null @@ -1,64 +0,0 @@ - - */ -class Swift_Mime_ContentEncoder_RawContentEncoder implements Swift_Mime_ContentEncoder -{ - /** - * Encode a given string to produce an encoded string. - * - * @param string $string - * @param int $firstLineOffset ignored - * @param int $maxLineLength ignored - * - * @return string - */ - public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) - { - return $string; - } - - /** - * Encode stream $in to stream $out. - * - * @param Swift_OutputByteStream $in - * @param Swift_InputByteStream $out - * @param int $firstLineOffset ignored - * @param int $maxLineLength ignored - */ - public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0) - { - while (false !== ($bytes = $os->read(8192))) { - $is->write($bytes); - } - } - - /** - * Get the name of this encoding scheme. - * - * @return string - */ - public function getName() - { - return 'raw'; - } - - /** - * Not used. - */ - public function charsetChanged($charset) - { - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/EmbeddedFile.php b/lib/SwiftMailer/classes/Swift/Mime/EmbeddedFile.php deleted file mode 100644 index 6af7571..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/EmbeddedFile.php +++ /dev/null @@ -1,45 +0,0 @@ -setDisposition('inline'); - $this->setId($this->getId()); - } - - /** - * Get the nesting level of this EmbeddedFile. - * - * Returns {@see LEVEL_RELATED}. - * - * @return int - */ - public function getNestingLevel() - { - return self::LEVEL_RELATED; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/EncodingObserver.php b/lib/SwiftMailer/classes/Swift/Mime/EncodingObserver.php deleted file mode 100644 index cc44a6e..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/EncodingObserver.php +++ /dev/null @@ -1,24 +0,0 @@ -init(); - } - - public function __wakeup() - { - $this->init(); - } - - protected function init() - { - if (count(self::$_specials) > 0) { - return; - } - - self::$_specials = array( - '(', ')', '<', '>', '[', ']', - ':', ';', '@', ',', '.', '"', - ); - - /*** Refer to RFC 2822 for ABNF grammar ***/ - - // All basic building blocks - self::$_grammar['NO-WS-CTL'] = '[\x01-\x08\x0B\x0C\x0E-\x19\x7F]'; - self::$_grammar['WSP'] = '[ \t]'; - self::$_grammar['CRLF'] = '(?:\r\n)'; - self::$_grammar['FWS'] = '(?:(?:'.self::$_grammar['WSP'].'*'. - self::$_grammar['CRLF'].')?'.self::$_grammar['WSP'].')'; - self::$_grammar['text'] = '[\x00-\x08\x0B\x0C\x0E-\x7F]'; - self::$_grammar['quoted-pair'] = '(?:\\\\'.self::$_grammar['text'].')'; - self::$_grammar['ctext'] = '(?:'.self::$_grammar['NO-WS-CTL']. - '|[\x21-\x27\x2A-\x5B\x5D-\x7E])'; - // Uses recursive PCRE (?1) -- could be a weak point?? - self::$_grammar['ccontent'] = '(?:'.self::$_grammar['ctext'].'|'. - self::$_grammar['quoted-pair'].'|(?1))'; - self::$_grammar['comment'] = '(\((?:'.self::$_grammar['FWS'].'|'. - self::$_grammar['ccontent'].')*'.self::$_grammar['FWS'].'?\))'; - self::$_grammar['CFWS'] = '(?:(?:'.self::$_grammar['FWS'].'?'. - self::$_grammar['comment'].')*(?:(?:'.self::$_grammar['FWS'].'?'. - self::$_grammar['comment'].')|'.self::$_grammar['FWS'].'))'; - self::$_grammar['qtext'] = '(?:'.self::$_grammar['NO-WS-CTL']. - '|[\x21\x23-\x5B\x5D-\x7E])'; - self::$_grammar['qcontent'] = '(?:'.self::$_grammar['qtext'].'|'. - self::$_grammar['quoted-pair'].')'; - self::$_grammar['quoted-string'] = '(?:'.self::$_grammar['CFWS'].'?"'. - '('.self::$_grammar['FWS'].'?'.self::$_grammar['qcontent'].')*'. - self::$_grammar['FWS'].'?"'.self::$_grammar['CFWS'].'?)'; - self::$_grammar['atext'] = '[a-zA-Z0-9!#\$%&\'\*\+\-\/=\?\^_`\{\}\|~]'; - self::$_grammar['atom'] = '(?:'.self::$_grammar['CFWS'].'?'. - self::$_grammar['atext'].'+'.self::$_grammar['CFWS'].'?)'; - self::$_grammar['dot-atom-text'] = '(?:'.self::$_grammar['atext'].'+'. - '(\.'.self::$_grammar['atext'].'+)*)'; - self::$_grammar['dot-atom'] = '(?:'.self::$_grammar['CFWS'].'?'. - self::$_grammar['dot-atom-text'].'+'.self::$_grammar['CFWS'].'?)'; - self::$_grammar['word'] = '(?:'.self::$_grammar['atom'].'|'. - self::$_grammar['quoted-string'].')'; - self::$_grammar['phrase'] = '(?:'.self::$_grammar['word'].'+?)'; - self::$_grammar['no-fold-quote'] = '(?:"(?:'.self::$_grammar['qtext']. - '|'.self::$_grammar['quoted-pair'].')*")'; - self::$_grammar['dtext'] = '(?:'.self::$_grammar['NO-WS-CTL']. - '|[\x21-\x5A\x5E-\x7E])'; - self::$_grammar['no-fold-literal'] = '(?:\[(?:'.self::$_grammar['dtext']. - '|'.self::$_grammar['quoted-pair'].')*\])'; - - // Message IDs - self::$_grammar['id-left'] = '(?:'.self::$_grammar['dot-atom-text'].'|'. - self::$_grammar['no-fold-quote'].')'; - self::$_grammar['id-right'] = '(?:'.self::$_grammar['dot-atom-text'].'|'. - self::$_grammar['no-fold-literal'].')'; - - // Addresses, mailboxes and paths - self::$_grammar['local-part'] = '(?:'.self::$_grammar['dot-atom'].'|'. - self::$_grammar['quoted-string'].')'; - self::$_grammar['dcontent'] = '(?:'.self::$_grammar['dtext'].'|'. - self::$_grammar['quoted-pair'].')'; - self::$_grammar['domain-literal'] = '(?:'.self::$_grammar['CFWS'].'?\[('. - self::$_grammar['FWS'].'?'.self::$_grammar['dcontent'].')*?'. - self::$_grammar['FWS'].'?\]'.self::$_grammar['CFWS'].'?)'; - self::$_grammar['domain'] = '(?:'.self::$_grammar['dot-atom'].'|'. - self::$_grammar['domain-literal'].')'; - self::$_grammar['addr-spec'] = '(?:'.self::$_grammar['local-part'].'@'. - self::$_grammar['domain'].')'; - } - - /** - * Get the grammar defined for $name token. - * - * @param string $name exactly as written in the RFC - * - * @return string - */ - public function getDefinition($name) - { - if (array_key_exists($name, self::$_grammar)) { - return self::$_grammar[$name]; - } - - throw new Swift_RfcComplianceException( - "No such grammar '".$name."' defined." - ); - } - - /** - * Returns the tokens defined in RFC 2822 (and some related RFCs). - * - * @return array - */ - public function getGrammarDefinitions() - { - return self::$_grammar; - } - - /** - * Returns the current special characters used in the syntax which need to be escaped. - * - * @return array - */ - public function getSpecials() - { - return self::$_specials; - } - - /** - * Escape special characters in a string (convert to quoted-pairs). - * - * @param string $token - * @param string[] $include additional chars to escape - * @param string[] $exclude chars from escaping - * - * @return string - */ - public function escapeSpecials($token, $include = array(), $exclude = array()) - { - foreach (array_merge(array('\\'), array_diff(self::$_specials, $exclude), $include) as $char) { - $token = str_replace($char, '\\'.$char, $token); - } - - return $token; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/Header.php b/lib/SwiftMailer/classes/Swift/Mime/Header.php deleted file mode 100644 index a8ddd27..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/Header.php +++ /dev/null @@ -1,93 +0,0 @@ -getName(), "\r\n"); - mb_internal_encoding($old); - - return $newstring; - } - - return parent::encodeString($string, $firstLineOffset, $maxLineLength); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php b/lib/SwiftMailer/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php deleted file mode 100644 index 510dd66..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php +++ /dev/null @@ -1,65 +0,0 @@ -_safeMap[$byte] = chr($byte); - } - } - - /** - * Get the name of this encoding scheme. - * - * Returns the string 'Q'. - * - * @return string - */ - public function getName() - { - return 'Q'; - } - - /** - * Takes an unencoded string and produces a QP encoded string from it. - * - * @param string $string string to encode - * @param int $firstLineOffset optional - * @param int $maxLineLength optional, 0 indicates the default of 76 chars - * - * @return string - */ - public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) - { - return str_replace(array(' ', '=20', "=\r\n"), array('_', '_', "\r\n"), - parent::encodeString($string, $firstLineOffset, $maxLineLength) - ); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/HeaderFactory.php b/lib/SwiftMailer/classes/Swift/Mime/HeaderFactory.php deleted file mode 100644 index c65f26d..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/HeaderFactory.php +++ /dev/null @@ -1,78 +0,0 @@ -setGrammar($grammar); - } - - /** - * Set the character set used in this Header. - * - * @param string $charset - */ - public function setCharset($charset) - { - $this->clearCachedValueIf($charset != $this->_charset); - $this->_charset = $charset; - if (isset($this->_encoder)) { - $this->_encoder->charsetChanged($charset); - } - } - - /** - * Get the character set used in this Header. - * - * @return string - */ - public function getCharset() - { - return $this->_charset; - } - - /** - * Set the language used in this Header. - * - * For example, for US English, 'en-us'. - * This can be unspecified. - * - * @param string $lang - */ - public function setLanguage($lang) - { - $this->clearCachedValueIf($this->_lang != $lang); - $this->_lang = $lang; - } - - /** - * Get the language used in this Header. - * - * @return string - */ - public function getLanguage() - { - return $this->_lang; - } - - /** - * Set the encoder used for encoding the header. - * - * @param Swift_Mime_HeaderEncoder $encoder - */ - public function setEncoder(Swift_Mime_HeaderEncoder $encoder) - { - $this->_encoder = $encoder; - $this->setCachedValue(null); - } - - /** - * Get the encoder used for encoding this Header. - * - * @return Swift_Mime_HeaderEncoder - */ - public function getEncoder() - { - return $this->_encoder; - } - - /** - * Set the grammar used for the header. - * - * @param Swift_Mime_Grammar $grammar - */ - public function setGrammar(Swift_Mime_Grammar $grammar) - { - $this->_grammar = $grammar; - $this->setCachedValue(null); - } - - /** - * Get the grammar used for this Header. - * - * @return Swift_Mime_Grammar - */ - public function getGrammar() - { - return $this->_grammar; - } - - /** - * Get the name of this header (e.g. charset). - * - * @return string - */ - public function getFieldName() - { - return $this->_name; - } - - /** - * Set the maximum length of lines in the header (excluding EOL). - * - * @param int $lineLength - */ - public function setMaxLineLength($lineLength) - { - $this->clearCachedValueIf($this->_lineLength != $lineLength); - $this->_lineLength = $lineLength; - } - - /** - * Get the maximum permitted length of lines in this Header. - * - * @return int - */ - public function getMaxLineLength() - { - return $this->_lineLength; - } - - /** - * Get this Header rendered as a RFC 2822 compliant string. - * - * @throws Swift_RfcComplianceException - * - * @return string - */ - public function toString() - { - return $this->_tokensToString($this->toTokens()); - } - - /** - * Returns a string representation of this object. - * - * @return string - * - * @see toString() - */ - public function __toString() - { - return $this->toString(); - } - - // -- Points of extension - - /** - * Set the name of this Header field. - * - * @param string $name - */ - protected function setFieldName($name) - { - $this->_name = $name; - } - - /** - * Produces a compliant, formatted RFC 2822 'phrase' based on the string given. - * - * @param Swift_Mime_Header $header - * @param string $string as displayed - * @param string $charset of the text - * @param Swift_Mime_HeaderEncoder $encoder - * @param bool $shorten the first line to make remove for header name - * - * @return string - */ - protected function createPhrase(Swift_Mime_Header $header, $string, $charset, Swift_Mime_HeaderEncoder $encoder = null, $shorten = false) - { - // Treat token as exactly what was given - $phraseStr = $string; - // If it's not valid - if (!preg_match('/^'.$this->getGrammar()->getDefinition('phrase').'$/D', $phraseStr)) { - // .. but it is just ascii text, try escaping some characters - // and make it a quoted-string - if (preg_match('/^'.$this->getGrammar()->getDefinition('text').'*$/D', $phraseStr)) { - $phraseStr = $this->getGrammar()->escapeSpecials( - $phraseStr, array('"'), $this->getGrammar()->getSpecials() - ); - $phraseStr = '"'.$phraseStr.'"'; - } else { - // ... otherwise it needs encoding - // Determine space remaining on line if first line - if ($shorten) { - $usedLength = strlen($header->getFieldName().': '); - } else { - $usedLength = 0; - } - $phraseStr = $this->encodeWords($header, $string, $usedLength); - } - } - - return $phraseStr; - } - - /** - * Encode needed word tokens within a string of input. - * - * @param Swift_Mime_Header $header - * @param string $input - * @param string $usedLength optional - * - * @return string - */ - protected function encodeWords(Swift_Mime_Header $header, $input, $usedLength = -1) - { - $value = ''; - - $tokens = $this->getEncodableWordTokens($input); - - foreach ($tokens as $token) { - // See RFC 2822, Sect 2.2 (really 2.2 ??) - if ($this->tokenNeedsEncoding($token)) { - // Don't encode starting WSP - $firstChar = substr($token, 0, 1); - switch ($firstChar) { - case ' ': - case "\t": - $value .= $firstChar; - $token = substr($token, 1); - } - - if (-1 == $usedLength) { - $usedLength = strlen($header->getFieldName().': ') + strlen($value); - } - $value .= $this->getTokenAsEncodedWord($token, $usedLength); - - $header->setMaxLineLength(76); // Forcefully override - } else { - $value .= $token; - } - } - - return $value; - } - - /** - * Test if a token needs to be encoded or not. - * - * @param string $token - * - * @return bool - */ - protected function tokenNeedsEncoding($token) - { - return preg_match('~[\x00-\x08\x10-\x19\x7F-\xFF\r\n]~', $token); - } - - /** - * Splits a string into tokens in blocks of words which can be encoded quickly. - * - * @param string $string - * - * @return string[] - */ - protected function getEncodableWordTokens($string) - { - $tokens = array(); - - $encodedToken = ''; - // Split at all whitespace boundaries - foreach (preg_split('~(?=[\t ])~', $string) as $token) { - if ($this->tokenNeedsEncoding($token)) { - $encodedToken .= $token; - } else { - if (strlen($encodedToken) > 0) { - $tokens[] = $encodedToken; - $encodedToken = ''; - } - $tokens[] = $token; - } - } - if (strlen($encodedToken)) { - $tokens[] = $encodedToken; - } - - return $tokens; - } - - /** - * Get a token as an encoded word for safe insertion into headers. - * - * @param string $token token to encode - * @param int $firstLineOffset optional - * - * @return string - */ - protected function getTokenAsEncodedWord($token, $firstLineOffset = 0) - { - // Adjust $firstLineOffset to account for space needed for syntax - $charsetDecl = $this->_charset; - if (isset($this->_lang)) { - $charsetDecl .= '*'.$this->_lang; - } - $encodingWrapperLength = strlen( - '=?'.$charsetDecl.'?'.$this->_encoder->getName().'??=' - ); - - if ($firstLineOffset >= 75) { - //Does this logic need to be here? - $firstLineOffset = 0; - } - - $encodedTextLines = explode("\r\n", - $this->_encoder->encodeString( - $token, $firstLineOffset, 75 - $encodingWrapperLength, $this->_charset - ) - ); - - if (strtolower($this->_charset) !== 'iso-2022-jp') { - // special encoding for iso-2022-jp using mb_encode_mimeheader - foreach ($encodedTextLines as $lineNum => $line) { - $encodedTextLines[$lineNum] = '=?'.$charsetDecl. - '?'.$this->_encoder->getName(). - '?'.$line.'?='; - } - } - - return implode("\r\n ", $encodedTextLines); - } - - /** - * Generates tokens from the given string which include CRLF as individual tokens. - * - * @param string $token - * - * @return string[] - */ - protected function generateTokenLines($token) - { - return preg_split('~(\r\n)~', $token, -1, PREG_SPLIT_DELIM_CAPTURE); - } - - /** - * Set a value into the cache. - * - * @param string $value - */ - protected function setCachedValue($value) - { - $this->_cachedValue = $value; - } - - /** - * Get the value in the cache. - * - * @return string - */ - protected function getCachedValue() - { - return $this->_cachedValue; - } - - /** - * Clear the cached value if $condition is met. - * - * @param bool $condition - */ - protected function clearCachedValueIf($condition) - { - if ($condition) { - $this->setCachedValue(null); - } - } - - /** - * Generate a list of all tokens in the final header. - * - * @param string $string The string to tokenize - * - * @return array An array of tokens as strings - */ - protected function toTokens($string = null) - { - if (is_null($string)) { - $string = $this->getFieldBody(); - } - - $tokens = array(); - - // Generate atoms; split at all invisible boundaries followed by WSP - foreach (preg_split('~(?=[ \t])~', $string) as $token) { - $newTokens = $this->generateTokenLines($token); - foreach ($newTokens as $newToken) { - $tokens[] = $newToken; - } - } - - return $tokens; - } - - /** - * Takes an array of tokens which appear in the header and turns them into - * an RFC 2822 compliant string, adding FWSP where needed. - * - * @param string[] $tokens - * - * @return string - */ - private function _tokensToString(array $tokens) - { - $lineCount = 0; - $headerLines = array(); - $headerLines[] = $this->_name.': '; - $currentLine = &$headerLines[$lineCount++]; - - // Build all tokens back into compliant header - foreach ($tokens as $i => $token) { - // Line longer than specified maximum or token was just a new line - if (("\r\n" == $token) || - ($i > 0 && strlen($currentLine.$token) > $this->_lineLength) - && 0 < strlen($currentLine)) { - $headerLines[] = ''; - $currentLine = &$headerLines[$lineCount++]; - } - - // Append token to the line - if ("\r\n" != $token) { - $currentLine .= $token; - } - } - - // Implode with FWS (RFC 2822, 2.2.3) - return implode("\r\n", $headerLines)."\r\n"; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/Headers/DateHeader.php b/lib/SwiftMailer/classes/Swift/Mime/Headers/DateHeader.php deleted file mode 100644 index 4fd6674..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/Headers/DateHeader.php +++ /dev/null @@ -1,125 +0,0 @@ - - * - * - * - * @param string $name of Header - * @param Swift_Mime_Grammar $grammar - */ - public function __construct($name, Swift_Mime_Grammar $grammar) - { - $this->setFieldName($name); - parent::__construct($grammar); - } - - /** - * Get the type of Header that this instance represents. - * - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - * - * @return int - */ - public function getFieldType() - { - return self::TYPE_DATE; - } - - /** - * Set the model for the field body. - * - * This method takes a UNIX timestamp. - * - * @param int $model - */ - public function setFieldBodyModel($model) - { - $this->setTimestamp($model); - } - - /** - * Get the model for the field body. - * - * This method returns a UNIX timestamp. - * - * @return mixed - */ - public function getFieldBodyModel() - { - return $this->getTimestamp(); - } - - /** - * Get the UNIX timestamp of the Date in this Header. - * - * @return int - */ - public function getTimestamp() - { - return $this->_timestamp; - } - - /** - * Set the UNIX timestamp of the Date in this Header. - * - * @param int $timestamp - */ - public function setTimestamp($timestamp) - { - if (!is_null($timestamp)) { - $timestamp = (int) $timestamp; - } - $this->clearCachedValueIf($this->_timestamp != $timestamp); - $this->_timestamp = $timestamp; - } - - /** - * Get the string value of the body in this Header. - * - * This is not necessarily RFC 2822 compliant since folding white space will - * not be added at this stage (see {@link toString()} for that). - * - * @see toString() - * - * @return string - */ - public function getFieldBody() - { - if (!$this->getCachedValue()) { - if (isset($this->_timestamp)) { - $this->setCachedValue(date('r', $this->_timestamp)); - } - } - - return $this->getCachedValue(); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/Headers/IdentificationHeader.php b/lib/SwiftMailer/classes/Swift/Mime/Headers/IdentificationHeader.php deleted file mode 100644 index b114506..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/Headers/IdentificationHeader.php +++ /dev/null @@ -1,180 +0,0 @@ -setFieldName($name); - parent::__construct($grammar); - } - - /** - * Get the type of Header that this instance represents. - * - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - * - * @return int - */ - public function getFieldType() - { - return self::TYPE_ID; - } - - /** - * Set the model for the field body. - * - * This method takes a string ID, or an array of IDs. - * - * @param mixed $model - * - * @throws Swift_RfcComplianceException - */ - public function setFieldBodyModel($model) - { - $this->setId($model); - } - - /** - * Get the model for the field body. - * - * This method returns an array of IDs - * - * @return array - */ - public function getFieldBodyModel() - { - return $this->getIds(); - } - - /** - * Set the ID used in the value of this header. - * - * @param string|array $id - * - * @throws Swift_RfcComplianceException - */ - public function setId($id) - { - $this->setIds(is_array($id) ? $id : array($id)); - } - - /** - * Get the ID used in the value of this Header. - * - * If multiple IDs are set only the first is returned. - * - * @return string - */ - public function getId() - { - if (count($this->_ids) > 0) { - return $this->_ids[0]; - } - } - - /** - * Set a collection of IDs to use in the value of this Header. - * - * @param string[] $ids - * - * @throws Swift_RfcComplianceException - */ - public function setIds(array $ids) - { - $actualIds = array(); - - foreach ($ids as $id) { - $this->_assertValidId($id); - $actualIds[] = $id; - } - - $this->clearCachedValueIf($this->_ids != $actualIds); - $this->_ids = $actualIds; - } - - /** - * Get the list of IDs used in this Header. - * - * @return string[] - */ - public function getIds() - { - return $this->_ids; - } - - /** - * Get the string value of the body in this Header. - * - * This is not necessarily RFC 2822 compliant since folding white space will - * not be added at this stage (see {@see toString()} for that). - * - * @see toString() - * - * @throws Swift_RfcComplianceException - * - * @return string - */ - public function getFieldBody() - { - if (!$this->getCachedValue()) { - $angleAddrs = array(); - - foreach ($this->_ids as $id) { - $angleAddrs[] = '<'.$id.'>'; - } - - $this->setCachedValue(implode(' ', $angleAddrs)); - } - - return $this->getCachedValue(); - } - - /** - * Throws an Exception if the id passed does not comply with RFC 2822. - * - * @param string $id - * - * @throws Swift_RfcComplianceException - */ - private function _assertValidId($id) - { - if (!preg_match( - '/^'.$this->getGrammar()->getDefinition('id-left').'@'. - $this->getGrammar()->getDefinition('id-right').'$/D', - $id - )) { - throw new Swift_RfcComplianceException( - 'Invalid ID given <'.$id.'>' - ); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php b/lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php deleted file mode 100644 index 222a57c..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php +++ /dev/null @@ -1,353 +0,0 @@ -setFieldName($name); - $this->setEncoder($encoder); - parent::__construct($grammar); - } - - /** - * Get the type of Header that this instance represents. - * - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - * - * @return int - */ - public function getFieldType() - { - return self::TYPE_MAILBOX; - } - - /** - * Set the model for the field body. - * - * This method takes a string, or an array of addresses. - * - * @param mixed $model - * - * @throws Swift_RfcComplianceException - */ - public function setFieldBodyModel($model) - { - $this->setNameAddresses($model); - } - - /** - * Get the model for the field body. - * - * This method returns an associative array like {@link getNameAddresses()} - * - * @throws Swift_RfcComplianceException - * - * @return array - */ - public function getFieldBodyModel() - { - return $this->getNameAddresses(); - } - - /** - * Set a list of mailboxes to be shown in this Header. - * - * The mailboxes can be a simple array of addresses, or an array of - * key=>value pairs where (email => personalName). - * Example: - * - * setNameAddresses(array( - * 'chris@swiftmailer.org' => 'Chris Corbyn', - * 'mark@swiftmailer.org' //No associated personal name - * )); - * ?> - * - * - * @see __construct() - * @see setAddresses() - * @see setValue() - * - * @param string|string[] $mailboxes - * - * @throws Swift_RfcComplianceException - */ - public function setNameAddresses($mailboxes) - { - $this->_mailboxes = $this->normalizeMailboxes((array) $mailboxes); - $this->setCachedValue(null); //Clear any cached value - } - - /** - * Get the full mailbox list of this Header as an array of valid RFC 2822 strings. - * - * Example: - * - * 'Chris Corbyn', - * 'mark@swiftmailer.org' => 'Mark Corbyn') - * ); - * print_r($header->getNameAddressStrings()); - * // array ( - * // 0 => Chris Corbyn , - * // 1 => Mark Corbyn - * // ) - * ?> - * - * - * @see getNameAddresses() - * @see toString() - * - * @throws Swift_RfcComplianceException - * - * @return string[] - */ - public function getNameAddressStrings() - { - return $this->_createNameAddressStrings($this->getNameAddresses()); - } - - /** - * Get all mailboxes in this Header as key=>value pairs. - * - * The key is the address and the value is the name (or null if none set). - * Example: - * - * 'Chris Corbyn', - * 'mark@swiftmailer.org' => 'Mark Corbyn') - * ); - * print_r($header->getNameAddresses()); - * // array ( - * // chris@swiftmailer.org => Chris Corbyn, - * // mark@swiftmailer.org => Mark Corbyn - * // ) - * ?> - * - * - * @see getAddresses() - * @see getNameAddressStrings() - * - * @return string[] - */ - public function getNameAddresses() - { - return $this->_mailboxes; - } - - /** - * Makes this Header represent a list of plain email addresses with no names. - * - * Example: - * - * setAddresses( - * array('one@domain.tld', 'two@domain.tld', 'three@domain.tld') - * ); - * ?> - * - * - * @see setNameAddresses() - * @see setValue() - * - * @param string[] $addresses - * - * @throws Swift_RfcComplianceException - */ - public function setAddresses($addresses) - { - $this->setNameAddresses(array_values((array) $addresses)); - } - - /** - * Get all email addresses in this Header. - * - * @see getNameAddresses() - * - * @return string[] - */ - public function getAddresses() - { - return array_keys($this->_mailboxes); - } - - /** - * Remove one or more addresses from this Header. - * - * @param string|string[] $addresses - */ - public function removeAddresses($addresses) - { - $this->setCachedValue(null); - foreach ((array) $addresses as $address) { - unset($this->_mailboxes[$address]); - } - } - - /** - * Get the string value of the body in this Header. - * - * This is not necessarily RFC 2822 compliant since folding white space will - * not be added at this stage (see {@link toString()} for that). - * - * @see toString() - * - * @throws Swift_RfcComplianceException - * - * @return string - */ - public function getFieldBody() - { - // Compute the string value of the header only if needed - if (is_null($this->getCachedValue())) { - $this->setCachedValue($this->createMailboxListString($this->_mailboxes)); - } - - return $this->getCachedValue(); - } - - // -- Points of extension - - /** - * Normalizes a user-input list of mailboxes into consistent key=>value pairs. - * - * @param string[] $mailboxes - * - * @return string[] - */ - protected function normalizeMailboxes(array $mailboxes) - { - $actualMailboxes = array(); - - foreach ($mailboxes as $key => $value) { - if (is_string($key)) { - //key is email addr - $address = $key; - $name = $value; - } else { - $address = $value; - $name = null; - } - $this->_assertValidAddress($address); - $actualMailboxes[$address] = $name; - } - - return $actualMailboxes; - } - - /** - * Produces a compliant, formatted display-name based on the string given. - * - * @param string $displayName as displayed - * @param bool $shorten the first line to make remove for header name - * - * @return string - */ - protected function createDisplayNameString($displayName, $shorten = false) - { - return $this->createPhrase($this, $displayName, $this->getCharset(), $this->getEncoder(), $shorten); - } - - /** - * Creates a string form of all the mailboxes in the passed array. - * - * @param string[] $mailboxes - * - * @throws Swift_RfcComplianceException - * - * @return string - */ - protected function createMailboxListString(array $mailboxes) - { - return implode(', ', $this->_createNameAddressStrings($mailboxes)); - } - - /** - * Redefine the encoding requirements for mailboxes. - * - * All "specials" must be encoded as the full header value will not be quoted - * - * @see RFC 2822 3.2.1 - * - * @param string $token - * - * @return bool - */ - protected function tokenNeedsEncoding($token) - { - return preg_match('/[()<>\[\]:;@\,."]/', $token) || parent::tokenNeedsEncoding($token); - } - - /** - * Return an array of strings conforming the the name-addr spec of RFC 2822. - * - * @param string[] $mailboxes - * - * @return string[] - */ - private function _createNameAddressStrings(array $mailboxes) - { - $strings = array(); - - foreach ($mailboxes as $email => $name) { - $mailboxStr = $email; - if (!is_null($name)) { - $nameStr = $this->createDisplayNameString($name, empty($strings)); - $mailboxStr = $nameStr.' <'.$mailboxStr.'>'; - } - $strings[] = $mailboxStr; - } - - return $strings; - } - - /** - * Throws an Exception if the address passed does not comply with RFC 2822. - * - * @param string $address - * - * @throws Swift_RfcComplianceException If invalid. - */ - private function _assertValidAddress($address) - { - if (!preg_match('/^'.$this->getGrammar()->getDefinition('addr-spec').'$/D', - $address)) { - throw new Swift_RfcComplianceException( - 'Address in mailbox given ['.$address. - '] does not comply with RFC 2822, 3.6.2.' - ); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/Headers/OpenDKIMHeader.php b/lib/SwiftMailer/classes/Swift/Mime/Headers/OpenDKIMHeader.php deleted file mode 100644 index d749550..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/Headers/OpenDKIMHeader.php +++ /dev/null @@ -1,133 +0,0 @@ - - */ -class Swift_Mime_Headers_OpenDKIMHeader implements Swift_Mime_Header -{ - /** - * The value of this Header. - * - * @var string - */ - private $_value; - - /** - * The name of this Header. - * - * @var string - */ - private $_fieldName; - - /** - * @param string $name - */ - public function __construct($name) - { - $this->_fieldName = $name; - } - - /** - * Get the type of Header that this instance represents. - * - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - * - * @return int - */ - public function getFieldType() - { - return self::TYPE_TEXT; - } - - /** - * Set the model for the field body. - * - * This method takes a string for the field value. - * - * @param string $model - */ - public function setFieldBodyModel($model) - { - $this->setValue($model); - } - - /** - * Get the model for the field body. - * - * This method returns a string. - * - * @return string - */ - public function getFieldBodyModel() - { - return $this->getValue(); - } - - /** - * Get the (unencoded) value of this header. - * - * @return string - */ - public function getValue() - { - return $this->_value; - } - - /** - * Set the (unencoded) value of this header. - * - * @param string $value - */ - public function setValue($value) - { - $this->_value = $value; - } - - /** - * Get the value of this header prepared for rendering. - * - * @return string - */ - public function getFieldBody() - { - return $this->_value; - } - - /** - * Get this Header rendered as a RFC 2822 compliant string. - * - * @return string - */ - public function toString() - { - return $this->_fieldName.': '.$this->_value; - } - - /** - * Set the Header FieldName. - * - * @see Swift_Mime_Header::getFieldName() - */ - public function getFieldName() - { - return $this->_fieldName; - } - - /** - * Ignored. - */ - public function setCharset($charset) - { - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/Headers/ParameterizedHeader.php b/lib/SwiftMailer/classes/Swift/Mime/Headers/ParameterizedHeader.php deleted file mode 100644 index c506dae..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/Headers/ParameterizedHeader.php +++ /dev/null @@ -1,258 +0,0 @@ -_paramEncoder = $paramEncoder; - } - - /** - * Get the type of Header that this instance represents. - * - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - * - * @return int - */ - public function getFieldType() - { - return self::TYPE_PARAMETERIZED; - } - - /** - * Set the character set used in this Header. - * - * @param string $charset - */ - public function setCharset($charset) - { - parent::setCharset($charset); - if (isset($this->_paramEncoder)) { - $this->_paramEncoder->charsetChanged($charset); - } - } - - /** - * Set the value of $parameter. - * - * @param string $parameter - * @param string $value - */ - public function setParameter($parameter, $value) - { - $this->setParameters(array_merge($this->getParameters(), array($parameter => $value))); - } - - /** - * Get the value of $parameter. - * - * @param string $parameter - * - * @return string - */ - public function getParameter($parameter) - { - $params = $this->getParameters(); - - return array_key_exists($parameter, $params) ? $params[$parameter] : null; - } - - /** - * Set an associative array of parameter names mapped to values. - * - * @param string[] $parameters - */ - public function setParameters(array $parameters) - { - $this->clearCachedValueIf($this->_params != $parameters); - $this->_params = $parameters; - } - - /** - * Returns an associative array of parameter names mapped to values. - * - * @return string[] - */ - public function getParameters() - { - return $this->_params; - } - - /** - * Get the value of this header prepared for rendering. - * - * @return string - */ - public function getFieldBody() //TODO: Check caching here - { - $body = parent::getFieldBody(); - foreach ($this->_params as $name => $value) { - if (!is_null($value)) { - // Add the parameter - $body .= '; '.$this->_createParameter($name, $value); - } - } - - return $body; - } - - /** - * Generate a list of all tokens in the final header. - * - * This doesn't need to be overridden in theory, but it is for implementation - * reasons to prevent potential breakage of attributes. - * - * @param string $string The string to tokenize - * - * @return array An array of tokens as strings - */ - protected function toTokens($string = null) - { - $tokens = parent::toTokens(parent::getFieldBody()); - - // Try creating any parameters - foreach ($this->_params as $name => $value) { - if (!is_null($value)) { - // Add the semi-colon separator - $tokens[count($tokens) - 1] .= ';'; - $tokens = array_merge($tokens, $this->generateTokenLines( - ' '.$this->_createParameter($name, $value) - )); - } - } - - return $tokens; - } - - /** - * Render a RFC 2047 compliant header parameter from the $name and $value. - * - * @param string $name - * @param string $value - * - * @return string - */ - private function _createParameter($name, $value) - { - $origValue = $value; - - $encoded = false; - // Allow room for parameter name, indices, "=" and DQUOTEs - $maxValueLength = $this->getMaxLineLength() - strlen($name.'=*N"";') - 1; - $firstLineOffset = 0; - - // If it's not already a valid parameter value... - if (!preg_match('/^'.self::TOKEN_REGEX.'$/D', $value)) { - // TODO: text, or something else?? - // ... and it's not ascii - if (!preg_match('/^'.$this->getGrammar()->getDefinition('text').'*$/D', $value)) { - $encoded = true; - // Allow space for the indices, charset and language - $maxValueLength = $this->getMaxLineLength() - strlen($name.'*N*="";') - 1; - $firstLineOffset = strlen( - $this->getCharset()."'".$this->getLanguage()."'" - ); - } - } - - // Encode if we need to - if ($encoded || strlen($value) > $maxValueLength) { - if (isset($this->_paramEncoder)) { - $value = $this->_paramEncoder->encodeString( - $origValue, $firstLineOffset, $maxValueLength, $this->getCharset() - ); - } else { - // We have to go against RFC 2183/2231 in some areas for interoperability - $value = $this->getTokenAsEncodedWord($origValue); - $encoded = false; - } - } - - $valueLines = isset($this->_paramEncoder) ? explode("\r\n", $value) : array($value); - - // Need to add indices - if (count($valueLines) > 1) { - $paramLines = array(); - foreach ($valueLines as $i => $line) { - $paramLines[] = $name.'*'.$i. - $this->_getEndOfParameterValue($line, true, $i == 0); - } - - return implode(";\r\n ", $paramLines); - } else { - return $name.$this->_getEndOfParameterValue( - $valueLines[0], $encoded, true - ); - } - } - - /** - * Returns the parameter value from the "=" and beyond. - * - * @param string $value to append - * @param bool $encoded - * @param bool $firstLine - * - * @return string - */ - private function _getEndOfParameterValue($value, $encoded = false, $firstLine = false) - { - if (!preg_match('/^'.self::TOKEN_REGEX.'$/D', $value)) { - $value = '"'.$value.'"'; - } - $prepend = '='; - if ($encoded) { - $prepend = '*='; - if ($firstLine) { - $prepend = '*='.$this->getCharset()."'".$this->getLanguage(). - "'"; - } - } - - return $prepend.$value; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/Headers/PathHeader.php b/lib/SwiftMailer/classes/Swift/Mime/Headers/PathHeader.php deleted file mode 100644 index 2fffc7b..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/Headers/PathHeader.php +++ /dev/null @@ -1,143 +0,0 @@ -setFieldName($name); - parent::__construct($grammar); - } - - /** - * Get the type of Header that this instance represents. - * - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - * - * @return int - */ - public function getFieldType() - { - return self::TYPE_PATH; - } - - /** - * Set the model for the field body. - * This method takes a string for an address. - * - * @param string $model - * - * @throws Swift_RfcComplianceException - */ - public function setFieldBodyModel($model) - { - $this->setAddress($model); - } - - /** - * Get the model for the field body. - * This method returns a string email address. - * - * @return mixed - */ - public function getFieldBodyModel() - { - return $this->getAddress(); - } - - /** - * Set the Address which should appear in this Header. - * - * @param string $address - * - * @throws Swift_RfcComplianceException - */ - public function setAddress($address) - { - if (is_null($address)) { - $this->_address = null; - } elseif ('' == $address) { - $this->_address = ''; - } else { - $this->_assertValidAddress($address); - $this->_address = $address; - } - $this->setCachedValue(null); - } - - /** - * Get the address which is used in this Header (if any). - * - * Null is returned if no address is set. - * - * @return string - */ - public function getAddress() - { - return $this->_address; - } - - /** - * Get the string value of the body in this Header. - * - * This is not necessarily RFC 2822 compliant since folding white space will - * not be added at this stage (see {@link toString()} for that). - * - * @see toString() - * - * @return string - */ - public function getFieldBody() - { - if (!$this->getCachedValue()) { - if (isset($this->_address)) { - $this->setCachedValue('<'.$this->_address.'>'); - } - } - - return $this->getCachedValue(); - } - - /** - * Throws an Exception if the address passed does not comply with RFC 2822. - * - * @param string $address - * - * @throws Swift_RfcComplianceException If address is invalid - */ - private function _assertValidAddress($address) - { - if (!preg_match('/^'.$this->getGrammar()->getDefinition('addr-spec').'$/D', - $address)) { - throw new Swift_RfcComplianceException( - 'Address set in PathHeader does not comply with addr-spec of RFC 2822.' - ); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/Headers/UnstructuredHeader.php b/lib/SwiftMailer/classes/Swift/Mime/Headers/UnstructuredHeader.php deleted file mode 100644 index 86177f1..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/Headers/UnstructuredHeader.php +++ /dev/null @@ -1,112 +0,0 @@ -setFieldName($name); - $this->setEncoder($encoder); - parent::__construct($grammar); - } - - /** - * Get the type of Header that this instance represents. - * - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - * - * @return int - */ - public function getFieldType() - { - return self::TYPE_TEXT; - } - - /** - * Set the model for the field body. - * - * This method takes a string for the field value. - * - * @param string $model - */ - public function setFieldBodyModel($model) - { - $this->setValue($model); - } - - /** - * Get the model for the field body. - * - * This method returns a string. - * - * @return string - */ - public function getFieldBodyModel() - { - return $this->getValue(); - } - - /** - * Get the (unencoded) value of this header. - * - * @return string - */ - public function getValue() - { - return $this->_value; - } - - /** - * Set the (unencoded) value of this header. - * - * @param string $value - */ - public function setValue($value) - { - $this->clearCachedValueIf($this->_value != $value); - $this->_value = $value; - } - - /** - * Get the value of this header prepared for rendering. - * - * @return string - */ - public function getFieldBody() - { - if (!$this->getCachedValue()) { - $this->setCachedValue( - $this->encodeWords($this, $this->_value) - ); - } - - return $this->getCachedValue(); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/Message.php b/lib/SwiftMailer/classes/Swift/Mime/Message.php deleted file mode 100644 index 9b36d21..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/Message.php +++ /dev/null @@ -1,223 +0,0 @@ - 'Real Name'). - * - * If the second parameter is provided and the first is a string, then $name - * is associated with the address. - * - * @param mixed $address - * @param string $name optional - */ - public function setSender($address, $name = null); - - /** - * Get the sender address for this message. - * - * This has a higher significance than the From address. - * - * @return string - */ - public function getSender(); - - /** - * Set the From address of this message. - * - * It is permissible for multiple From addresses to be set using an array. - * - * If multiple From addresses are used, you SHOULD set the Sender address and - * according to RFC 2822, MUST set the sender address. - * - * An array can be used if display names are to be provided: i.e. - * array('email@address.com' => 'Real Name'). - * - * If the second parameter is provided and the first is a string, then $name - * is associated with the address. - * - * @param mixed $addresses - * @param string $name optional - */ - public function setFrom($addresses, $name = null); - - /** - * Get the From address(es) of this message. - * - * This method always returns an associative array where the keys are the - * addresses. - * - * @return string[] - */ - public function getFrom(); - - /** - * Set the Reply-To address(es). - * - * Any replies from the receiver will be sent to this address. - * - * It is permissible for multiple reply-to addresses to be set using an array. - * - * This method has the same synopsis as {@link setFrom()} and {@link setTo()}. - * - * If the second parameter is provided and the first is a string, then $name - * is associated with the address. - * - * @param mixed $addresses - * @param string $name optional - */ - public function setReplyTo($addresses, $name = null); - - /** - * Get the Reply-To addresses for this message. - * - * This method always returns an associative array where the keys provide the - * email addresses. - * - * @return string[] - */ - public function getReplyTo(); - - /** - * Set the To address(es). - * - * Recipients set in this field will receive a copy of this message. - * - * This method has the same synopsis as {@link setFrom()} and {@link setCc()}. - * - * If the second parameter is provided and the first is a string, then $name - * is associated with the address. - * - * @param mixed $addresses - * @param string $name optional - */ - public function setTo($addresses, $name = null); - - /** - * Get the To addresses for this message. - * - * This method always returns an associative array, whereby the keys provide - * the actual email addresses. - * - * @return string[] - */ - public function getTo(); - - /** - * Set the Cc address(es). - * - * Recipients set in this field will receive a 'carbon-copy' of this message. - * - * This method has the same synopsis as {@link setFrom()} and {@link setTo()}. - * - * @param mixed $addresses - * @param string $name optional - */ - public function setCc($addresses, $name = null); - - /** - * Get the Cc addresses for this message. - * - * This method always returns an associative array, whereby the keys provide - * the actual email addresses. - * - * @return string[] - */ - public function getCc(); - - /** - * Set the Bcc address(es). - * - * Recipients set in this field will receive a 'blind-carbon-copy' of this - * message. - * - * In other words, they will get the message, but any other recipients of the - * message will have no such knowledge of their receipt of it. - * - * This method has the same synopsis as {@link setFrom()} and {@link setTo()}. - * - * @param mixed $addresses - * @param string $name optional - */ - public function setBcc($addresses, $name = null); - - /** - * Get the Bcc addresses for this message. - * - * This method always returns an associative array, whereby the keys provide - * the actual email addresses. - * - * @return string[] - */ - public function getBcc(); -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/MimeEntity.php b/lib/SwiftMailer/classes/Swift/Mime/MimeEntity.php deleted file mode 100644 index 30f460c..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/MimeEntity.php +++ /dev/null @@ -1,117 +0,0 @@ -setContentType('text/plain'); - if (!is_null($charset)) { - $this->setCharset($charset); - } - } - - /** - * Set the body of this entity, either as a string, or as an instance of - * {@link Swift_OutputByteStream}. - * - * @param mixed $body - * @param string $contentType optional - * @param string $charset optional - * - * @return Swift_Mime_MimePart - */ - public function setBody($body, $contentType = null, $charset = null) - { - if (isset($charset)) { - $this->setCharset($charset); - } - $body = $this->_convertString($body); - - parent::setBody($body, $contentType); - - return $this; - } - - /** - * Get the character set of this entity. - * - * @return string - */ - public function getCharset() - { - return $this->_getHeaderParameter('Content-Type', 'charset'); - } - - /** - * Set the character set of this entity. - * - * @param string $charset - * - * @return Swift_Mime_MimePart - */ - public function setCharset($charset) - { - $this->_setHeaderParameter('Content-Type', 'charset', $charset); - if ($charset !== $this->_userCharset) { - $this->_clearCache(); - } - $this->_userCharset = $charset; - parent::charsetChanged($charset); - - return $this; - } - - /** - * Get the format of this entity (i.e. flowed or fixed). - * - * @return string - */ - public function getFormat() - { - return $this->_getHeaderParameter('Content-Type', 'format'); - } - - /** - * Set the format of this entity (flowed or fixed). - * - * @param string $format - * - * @return Swift_Mime_MimePart - */ - public function setFormat($format) - { - $this->_setHeaderParameter('Content-Type', 'format', $format); - $this->_userFormat = $format; - - return $this; - } - - /** - * Test if delsp is being used for this entity. - * - * @return bool - */ - public function getDelSp() - { - return 'yes' == $this->_getHeaderParameter('Content-Type', 'delsp') ? true : false; - } - - /** - * Turn delsp on or off for this entity. - * - * @param bool $delsp - * - * @return Swift_Mime_MimePart - */ - public function setDelSp($delsp = true) - { - $this->_setHeaderParameter('Content-Type', 'delsp', $delsp ? 'yes' : null); - $this->_userDelSp = $delsp; - - return $this; - } - - /** - * Get the nesting level of this entity. - * - * @see LEVEL_TOP, LEVEL_ALTERNATIVE, LEVEL_MIXED, LEVEL_RELATED - * - * @return int - */ - public function getNestingLevel() - { - return $this->_nestingLevel; - } - - /** - * Receive notification that the charset has changed on this document, or a - * parent document. - * - * @param string $charset - */ - public function charsetChanged($charset) - { - $this->setCharset($charset); - } - - /** Fix the content-type and encoding of this entity */ - protected function _fixHeaders() - { - parent::_fixHeaders(); - if (count($this->getChildren())) { - $this->_setHeaderParameter('Content-Type', 'charset', null); - $this->_setHeaderParameter('Content-Type', 'format', null); - $this->_setHeaderParameter('Content-Type', 'delsp', null); - } else { - $this->setCharset($this->_userCharset); - $this->setFormat($this->_userFormat); - $this->setDelSp($this->_userDelSp); - } - } - - /** Set the nesting level of this entity */ - protected function _setNestingLevel($level) - { - $this->_nestingLevel = $level; - } - - /** Encode charset when charset is not utf-8 */ - protected function _convertString($string) - { - $charset = strtolower($this->getCharset()); - if (!in_array($charset, array('utf-8', 'iso-8859-1', 'iso-8859-15', ''))) { - // mb_convert_encoding must be the first one to check, since iconv cannot convert some words. - if (function_exists('mb_convert_encoding')) { - $string = mb_convert_encoding($string, $charset, 'utf-8'); - } elseif (function_exists('iconv')) { - $string = iconv('utf-8//TRANSLIT//IGNORE', $charset, $string); - } else { - throw new Swift_SwiftException('No suitable convert encoding function (use UTF-8 as your charset or install the mbstring or iconv extension).'); - } - - return $string; - } - - return $string; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/ParameterizedHeader.php b/lib/SwiftMailer/classes/Swift/Mime/ParameterizedHeader.php deleted file mode 100644 index e15c6ef..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/ParameterizedHeader.php +++ /dev/null @@ -1,34 +0,0 @@ -_encoder = $encoder; - $this->_paramEncoder = $paramEncoder; - $this->_grammar = $grammar; - $this->_charset = $charset; - } - - /** - * Create a new Mailbox Header with a list of $addresses. - * - * @param string $name - * @param array|string|null $addresses - * - * @return Swift_Mime_Header - */ - public function createMailboxHeader($name, $addresses = null) - { - $header = new Swift_Mime_Headers_MailboxHeader($name, $this->_encoder, $this->_grammar); - if (isset($addresses)) { - $header->setFieldBodyModel($addresses); - } - $this->_setHeaderCharset($header); - - return $header; - } - - /** - * Create a new Date header using $timestamp (UNIX time). - * - * @param string $name - * @param int|null $timestamp - * - * @return Swift_Mime_Header - */ - public function createDateHeader($name, $timestamp = null) - { - $header = new Swift_Mime_Headers_DateHeader($name, $this->_grammar); - if (isset($timestamp)) { - $header->setFieldBodyModel($timestamp); - } - $this->_setHeaderCharset($header); - - return $header; - } - - /** - * Create a new basic text header with $name and $value. - * - * @param string $name - * @param string $value - * - * @return Swift_Mime_Header - */ - public function createTextHeader($name, $value = null) - { - $header = new Swift_Mime_Headers_UnstructuredHeader($name, $this->_encoder, $this->_grammar); - if (isset($value)) { - $header->setFieldBodyModel($value); - } - $this->_setHeaderCharset($header); - - return $header; - } - - /** - * Create a new ParameterizedHeader with $name, $value and $params. - * - * @param string $name - * @param string $value - * @param array $params - * - * @return Swift_Mime_ParameterizedHeader - */ - public function createParameterizedHeader($name, $value = null, - $params = array()) - { - $header = new Swift_Mime_Headers_ParameterizedHeader($name, $this->_encoder, strtolower($name) == 'content-disposition' ? $this->_paramEncoder : null, $this->_grammar); - if (isset($value)) { - $header->setFieldBodyModel($value); - } - foreach ($params as $k => $v) { - $header->setParameter($k, $v); - } - $this->_setHeaderCharset($header); - - return $header; - } - - /** - * Create a new ID header for Message-ID or Content-ID. - * - * @param string $name - * @param string|array $ids - * - * @return Swift_Mime_Header - */ - public function createIdHeader($name, $ids = null) - { - $header = new Swift_Mime_Headers_IdentificationHeader($name, $this->_grammar); - if (isset($ids)) { - $header->setFieldBodyModel($ids); - } - $this->_setHeaderCharset($header); - - return $header; - } - - /** - * Create a new Path header with an address (path) in it. - * - * @param string $name - * @param string $path - * - * @return Swift_Mime_Header - */ - public function createPathHeader($name, $path = null) - { - $header = new Swift_Mime_Headers_PathHeader($name, $this->_grammar); - if (isset($path)) { - $header->setFieldBodyModel($path); - } - $this->_setHeaderCharset($header); - - return $header; - } - - /** - * Notify this observer that the entity's charset has changed. - * - * @param string $charset - */ - public function charsetChanged($charset) - { - $this->_charset = $charset; - $this->_encoder->charsetChanged($charset); - $this->_paramEncoder->charsetChanged($charset); - } - - /** - * Make a deep copy of object. - */ - public function __clone() - { - $this->_encoder = clone $this->_encoder; - $this->_paramEncoder = clone $this->_paramEncoder; - } - - /** Apply the charset to the Header */ - private function _setHeaderCharset(Swift_Mime_Header $header) - { - if (isset($this->_charset)) { - $header->setCharset($this->_charset); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/SimpleHeaderSet.php b/lib/SwiftMailer/classes/Swift/Mime/SimpleHeaderSet.php deleted file mode 100644 index e2d0e87..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/SimpleHeaderSet.php +++ /dev/null @@ -1,414 +0,0 @@ -_factory = $factory; - if (isset($charset)) { - $this->setCharset($charset); - } - } - - /** - * Set the charset used by these headers. - * - * @param string $charset - */ - public function setCharset($charset) - { - $this->_charset = $charset; - $this->_factory->charsetChanged($charset); - $this->_notifyHeadersOfCharset($charset); - } - - /** - * Add a new Mailbox Header with a list of $addresses. - * - * @param string $name - * @param array|string $addresses - */ - public function addMailboxHeader($name, $addresses = null) - { - $this->_storeHeader($name, - $this->_factory->createMailboxHeader($name, $addresses)); - } - - /** - * Add a new Date header using $timestamp (UNIX time). - * - * @param string $name - * @param int $timestamp - */ - public function addDateHeader($name, $timestamp = null) - { - $this->_storeHeader($name, - $this->_factory->createDateHeader($name, $timestamp)); - } - - /** - * Add a new basic text header with $name and $value. - * - * @param string $name - * @param string $value - */ - public function addTextHeader($name, $value = null) - { - $this->_storeHeader($name, - $this->_factory->createTextHeader($name, $value)); - } - - /** - * Add a new ParameterizedHeader with $name, $value and $params. - * - * @param string $name - * @param string $value - * @param array $params - */ - public function addParameterizedHeader($name, $value = null, $params = array()) - { - $this->_storeHeader($name, $this->_factory->createParameterizedHeader($name, $value, $params)); - } - - /** - * Add a new ID header for Message-ID or Content-ID. - * - * @param string $name - * @param string|array $ids - */ - public function addIdHeader($name, $ids = null) - { - $this->_storeHeader($name, $this->_factory->createIdHeader($name, $ids)); - } - - /** - * Add a new Path header with an address (path) in it. - * - * @param string $name - * @param string $path - */ - public function addPathHeader($name, $path = null) - { - $this->_storeHeader($name, $this->_factory->createPathHeader($name, $path)); - } - - /** - * Returns true if at least one header with the given $name exists. - * - * If multiple headers match, the actual one may be specified by $index. - * - * @param string $name - * @param int $index - * - * @return bool - */ - public function has($name, $index = 0) - { - $lowerName = strtolower($name); - - if (!array_key_exists($lowerName, $this->_headers)) { - return false; - } - - if (func_num_args() < 2) { - // index was not specified, so we only need to check that there is at least one header value set - return (bool) count($this->_headers[$lowerName]); - } - - return array_key_exists($index, $this->_headers[$lowerName]); - } - - /** - * Set a header in the HeaderSet. - * - * The header may be a previously fetched header via {@link get()} or it may - * be one that has been created separately. - * - * If $index is specified, the header will be inserted into the set at this - * offset. - * - * @param Swift_Mime_Header $header - * @param int $index - */ - public function set(Swift_Mime_Header $header, $index = 0) - { - $this->_storeHeader($header->getFieldName(), $header, $index); - } - - /** - * Get the header with the given $name. - * - * If multiple headers match, the actual one may be specified by $index. - * Returns NULL if none present. - * - * @param string $name - * @param int $index - * - * @return Swift_Mime_Header - */ - public function get($name, $index = 0) - { - $name = strtolower($name); - - if (func_num_args() < 2) { - if ($this->has($name)) { - $values = array_values($this->_headers[$name]); - - return array_shift($values); - } - } else { - if ($this->has($name, $index)) { - return $this->_headers[$name][$index]; - } - } - } - - /** - * Get all headers with the given $name. - * - * @param string $name - * - * @return array - */ - public function getAll($name = null) - { - if (!isset($name)) { - $headers = array(); - foreach ($this->_headers as $collection) { - $headers = array_merge($headers, $collection); - } - - return $headers; - } - - $lowerName = strtolower($name); - if (!array_key_exists($lowerName, $this->_headers)) { - return array(); - } - - return $this->_headers[$lowerName]; - } - - /** - * Return the name of all Headers. - * - * @return array - */ - public function listAll() - { - $headers = $this->_headers; - if ($this->_canSort()) { - uksort($headers, array($this, '_sortHeaders')); - } - - return array_keys($headers); - } - - /** - * Remove the header with the given $name if it's set. - * - * If multiple headers match, the actual one may be specified by $index. - * - * @param string $name - * @param int $index - */ - public function remove($name, $index = 0) - { - $lowerName = strtolower($name); - unset($this->_headers[$lowerName][$index]); - } - - /** - * Remove all headers with the given $name. - * - * @param string $name - */ - public function removeAll($name) - { - $lowerName = strtolower($name); - unset($this->_headers[$lowerName]); - } - - /** - * Create a new instance of this HeaderSet. - * - * @return Swift_Mime_HeaderSet - */ - public function newInstance() - { - return new self($this->_factory); - } - - /** - * Define a list of Header names as an array in the correct order. - * - * These Headers will be output in the given order where present. - * - * @param array $sequence - */ - public function defineOrdering(array $sequence) - { - $this->_order = array_flip(array_map('strtolower', $sequence)); - } - - /** - * Set a list of header names which must always be displayed when set. - * - * Usually headers without a field value won't be output unless set here. - * - * @param array $names - */ - public function setAlwaysDisplayed(array $names) - { - $this->_required = array_flip(array_map('strtolower', $names)); - } - - /** - * Notify this observer that the entity's charset has changed. - * - * @param string $charset - */ - public function charsetChanged($charset) - { - $this->setCharset($charset); - } - - /** - * Returns a string with a representation of all headers. - * - * @return string - */ - public function toString() - { - $string = ''; - $headers = $this->_headers; - if ($this->_canSort()) { - uksort($headers, array($this, '_sortHeaders')); - } - foreach ($headers as $collection) { - foreach ($collection as $header) { - if ($this->_isDisplayed($header) || $header->getFieldBody() != '') { - $string .= $header->toString(); - } - } - } - - return $string; - } - - /** - * Returns a string representation of this object. - * - * @return string - * - * @see toString() - */ - public function __toString() - { - return $this->toString(); - } - - /** Save a Header to the internal collection */ - private function _storeHeader($name, Swift_Mime_Header $header, $offset = null) - { - if (!isset($this->_headers[strtolower($name)])) { - $this->_headers[strtolower($name)] = array(); - } - if (!isset($offset)) { - $this->_headers[strtolower($name)][] = $header; - } else { - $this->_headers[strtolower($name)][$offset] = $header; - } - } - - /** Test if the headers can be sorted */ - private function _canSort() - { - return count($this->_order) > 0; - } - - /** uksort() algorithm for Header ordering */ - private function _sortHeaders($a, $b) - { - $lowerA = strtolower($a); - $lowerB = strtolower($b); - $aPos = array_key_exists($lowerA, $this->_order) ? $this->_order[$lowerA] : -1; - $bPos = array_key_exists($lowerB, $this->_order) ? $this->_order[$lowerB] : -1; - - if (-1 === $aPos && -1 === $bPos) { - // just be sure to be determinist here - return $a > $b ? -1 : 1; - } - - if ($aPos == -1) { - return 1; - } elseif ($bPos == -1) { - return -1; - } - - return $aPos < $bPos ? -1 : 1; - } - - /** Test if the given Header is always displayed */ - private function _isDisplayed(Swift_Mime_Header $header) - { - return array_key_exists(strtolower($header->getFieldName()), $this->_required); - } - - /** Notify all Headers of the new charset */ - private function _notifyHeadersOfCharset($charset) - { - foreach ($this->_headers as $headerGroup) { - foreach ($headerGroup as $header) { - $header->setCharset($charset); - } - } - } - - /** - * Make a deep copy of object. - */ - public function __clone() - { - $this->_factory = clone $this->_factory; - foreach ($this->_headers as $groupKey => $headerGroup) { - foreach ($headerGroup as $key => $header) { - $this->_headers[$groupKey][$key] = clone $header; - } - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/SimpleMessage.php b/lib/SwiftMailer/classes/Swift/Mime/SimpleMessage.php deleted file mode 100644 index 124644b..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/SimpleMessage.php +++ /dev/null @@ -1,649 +0,0 @@ -getHeaders()->defineOrdering(array( - 'Return-Path', - 'Received', - 'DKIM-Signature', - 'DomainKey-Signature', - 'Sender', - 'Message-ID', - 'Date', - 'Subject', - 'From', - 'Reply-To', - 'To', - 'Cc', - 'Bcc', - 'MIME-Version', - 'Content-Type', - 'Content-Transfer-Encoding', - )); - $this->getHeaders()->setAlwaysDisplayed(array('Date', 'Message-ID', 'From')); - $this->getHeaders()->addTextHeader('MIME-Version', '1.0'); - $this->setDate(time()); - $this->setId($this->getId()); - $this->getHeaders()->addMailboxHeader('From'); - } - - /** - * Always returns {@link LEVEL_TOP} for a message instance. - * - * @return int - */ - public function getNestingLevel() - { - return self::LEVEL_TOP; - } - - /** - * Set the subject of this message. - * - * @param string $subject - * - * @return Swift_Mime_SimpleMessage - */ - public function setSubject($subject) - { - if (!$this->_setHeaderFieldModel('Subject', $subject)) { - $this->getHeaders()->addTextHeader('Subject', $subject); - } - - return $this; - } - - /** - * Get the subject of this message. - * - * @return string - */ - public function getSubject() - { - return $this->_getHeaderFieldModel('Subject'); - } - - /** - * Set the date at which this message was created. - * - * @param int $date - * - * @return Swift_Mime_SimpleMessage - */ - public function setDate($date) - { - if (!$this->_setHeaderFieldModel('Date', $date)) { - $this->getHeaders()->addDateHeader('Date', $date); - } - - return $this; - } - - /** - * Get the date at which this message was created. - * - * @return int - */ - public function getDate() - { - return $this->_getHeaderFieldModel('Date'); - } - - /** - * Set the return-path (the bounce address) of this message. - * - * @param string $address - * - * @return Swift_Mime_SimpleMessage - */ - public function setReturnPath($address) - { - if (!$this->_setHeaderFieldModel('Return-Path', $address)) { - $this->getHeaders()->addPathHeader('Return-Path', $address); - } - - return $this; - } - - /** - * Get the return-path (bounce address) of this message. - * - * @return string - */ - public function getReturnPath() - { - return $this->_getHeaderFieldModel('Return-Path'); - } - - /** - * Set the sender of this message. - * - * This does not override the From field, but it has a higher significance. - * - * @param string $address - * @param string $name optional - * - * @return Swift_Mime_SimpleMessage - */ - public function setSender($address, $name = null) - { - if (!is_array($address) && isset($name)) { - $address = array($address => $name); - } - - if (!$this->_setHeaderFieldModel('Sender', (array) $address)) { - $this->getHeaders()->addMailboxHeader('Sender', (array) $address); - } - - return $this; - } - - /** - * Get the sender of this message. - * - * @return string - */ - public function getSender() - { - return $this->_getHeaderFieldModel('Sender'); - } - - /** - * Add a From: address to this message. - * - * If $name is passed this name will be associated with the address. - * - * @param string $address - * @param string $name optional - * - * @return Swift_Mime_SimpleMessage - */ - public function addFrom($address, $name = null) - { - $current = $this->getFrom(); - $current[$address] = $name; - - return $this->setFrom($current); - } - - /** - * Set the from address of this message. - * - * You may pass an array of addresses if this message is from multiple people. - * - * If $name is passed and the first parameter is a string, this name will be - * associated with the address. - * - * @param string|array $addresses - * @param string $name optional - * - * @return Swift_Mime_SimpleMessage - */ - public function setFrom($addresses, $name = null) - { - if (!is_array($addresses) && isset($name)) { - $addresses = array($addresses => $name); - } - - if (!$this->_setHeaderFieldModel('From', (array) $addresses)) { - $this->getHeaders()->addMailboxHeader('From', (array) $addresses); - } - - return $this; - } - - /** - * Get the from address of this message. - * - * @return mixed - */ - public function getFrom() - { - return $this->_getHeaderFieldModel('From'); - } - - /** - * Add a Reply-To: address to this message. - * - * If $name is passed this name will be associated with the address. - * - * @param string $address - * @param string $name optional - * - * @return Swift_Mime_SimpleMessage - */ - public function addReplyTo($address, $name = null) - { - $current = $this->getReplyTo(); - $current[$address] = $name; - - return $this->setReplyTo($current); - } - - /** - * Set the reply-to address of this message. - * - * You may pass an array of addresses if replies will go to multiple people. - * - * If $name is passed and the first parameter is a string, this name will be - * associated with the address. - * - * @param mixed $addresses - * @param string $name optional - * - * @return Swift_Mime_SimpleMessage - */ - public function setReplyTo($addresses, $name = null) - { - if (!is_array($addresses) && isset($name)) { - $addresses = array($addresses => $name); - } - - if (!$this->_setHeaderFieldModel('Reply-To', (array) $addresses)) { - $this->getHeaders()->addMailboxHeader('Reply-To', (array) $addresses); - } - - return $this; - } - - /** - * Get the reply-to address of this message. - * - * @return string - */ - public function getReplyTo() - { - return $this->_getHeaderFieldModel('Reply-To'); - } - - /** - * Add a To: address to this message. - * - * If $name is passed this name will be associated with the address. - * - * @param string $address - * @param string $name optional - * - * @return Swift_Mime_SimpleMessage - */ - public function addTo($address, $name = null) - { - $current = $this->getTo(); - $current[$address] = $name; - - return $this->setTo($current); - } - - /** - * Set the to addresses of this message. - * - * If multiple recipients will receive the message an array should be used. - * Example: array('receiver@domain.org', 'other@domain.org' => 'A name') - * - * If $name is passed and the first parameter is a string, this name will be - * associated with the address. - * - * @param mixed $addresses - * @param string $name optional - * - * @return Swift_Mime_SimpleMessage - */ - public function setTo($addresses, $name = null) - { - if (!is_array($addresses) && isset($name)) { - $addresses = array($addresses => $name); - } - - if (!$this->_setHeaderFieldModel('To', (array) $addresses)) { - $this->getHeaders()->addMailboxHeader('To', (array) $addresses); - } - - return $this; - } - - /** - * Get the To addresses of this message. - * - * @return array - */ - public function getTo() - { - return $this->_getHeaderFieldModel('To'); - } - - /** - * Add a Cc: address to this message. - * - * If $name is passed this name will be associated with the address. - * - * @param string $address - * @param string $name optional - * - * @return Swift_Mime_SimpleMessage - */ - public function addCc($address, $name = null) - { - $current = $this->getCc(); - $current[$address] = $name; - - return $this->setCc($current); - } - - /** - * Set the Cc addresses of this message. - * - * If $name is passed and the first parameter is a string, this name will be - * associated with the address. - * - * @param mixed $addresses - * @param string $name optional - * - * @return Swift_Mime_SimpleMessage - */ - public function setCc($addresses, $name = null) - { - if (!is_array($addresses) && isset($name)) { - $addresses = array($addresses => $name); - } - - if (!$this->_setHeaderFieldModel('Cc', (array) $addresses)) { - $this->getHeaders()->addMailboxHeader('Cc', (array) $addresses); - } - - return $this; - } - - /** - * Get the Cc address of this message. - * - * @return array - */ - public function getCc() - { - return $this->_getHeaderFieldModel('Cc'); - } - - /** - * Add a Bcc: address to this message. - * - * If $name is passed this name will be associated with the address. - * - * @param string $address - * @param string $name optional - * - * @return Swift_Mime_SimpleMessage - */ - public function addBcc($address, $name = null) - { - $current = $this->getBcc(); - $current[$address] = $name; - - return $this->setBcc($current); - } - - /** - * Set the Bcc addresses of this message. - * - * If $name is passed and the first parameter is a string, this name will be - * associated with the address. - * - * @param mixed $addresses - * @param string $name optional - * - * @return Swift_Mime_SimpleMessage - */ - public function setBcc($addresses, $name = null) - { - if (!is_array($addresses) && isset($name)) { - $addresses = array($addresses => $name); - } - - if (!$this->_setHeaderFieldModel('Bcc', (array) $addresses)) { - $this->getHeaders()->addMailboxHeader('Bcc', (array) $addresses); - } - - return $this; - } - - /** - * Get the Bcc addresses of this message. - * - * @return array - */ - public function getBcc() - { - return $this->_getHeaderFieldModel('Bcc'); - } - - /** - * Set the priority of this message. - * - * The value is an integer where 1 is the highest priority and 5 is the lowest. - * - * @param int $priority - * - * @return Swift_Mime_SimpleMessage - */ - public function setPriority($priority) - { - $priorityMap = array( - 1 => 'Highest', - 2 => 'High', - 3 => 'Normal', - 4 => 'Low', - 5 => 'Lowest', - ); - $pMapKeys = array_keys($priorityMap); - if ($priority > max($pMapKeys)) { - $priority = max($pMapKeys); - } elseif ($priority < min($pMapKeys)) { - $priority = min($pMapKeys); - } - if (!$this->_setHeaderFieldModel('X-Priority', - sprintf('%d (%s)', $priority, $priorityMap[$priority]))) { - $this->getHeaders()->addTextHeader('X-Priority', - sprintf('%d (%s)', $priority, $priorityMap[$priority])); - } - - return $this; - } - - /** - * Get the priority of this message. - * - * The returned value is an integer where 1 is the highest priority and 5 - * is the lowest. - * - * @return int - */ - public function getPriority() - { - list($priority) = sscanf($this->_getHeaderFieldModel('X-Priority'), - '%[1-5]' - ); - - return isset($priority) ? $priority : 3; - } - - /** - * Ask for a delivery receipt from the recipient to be sent to $addresses. - * - * @param array $addresses - * - * @return Swift_Mime_SimpleMessage - */ - public function setReadReceiptTo($addresses) - { - if (!$this->_setHeaderFieldModel('Disposition-Notification-To', $addresses)) { - $this->getHeaders() - ->addMailboxHeader('Disposition-Notification-To', $addresses); - } - - return $this; - } - - /** - * Get the addresses to which a read-receipt will be sent. - * - * @return string - */ - public function getReadReceiptTo() - { - return $this->_getHeaderFieldModel('Disposition-Notification-To'); - } - - /** - * Attach a {@link Swift_Mime_MimeEntity} such as an Attachment or MimePart. - * - * @param Swift_Mime_MimeEntity $entity - * - * @return Swift_Mime_SimpleMessage - */ - public function attach(Swift_Mime_MimeEntity $entity) - { - $this->setChildren(array_merge($this->getChildren(), array($entity))); - - return $this; - } - - /** - * Remove an already attached entity. - * - * @param Swift_Mime_MimeEntity $entity - * - * @return Swift_Mime_SimpleMessage - */ - public function detach(Swift_Mime_MimeEntity $entity) - { - $newChildren = array(); - foreach ($this->getChildren() as $child) { - if ($entity !== $child) { - $newChildren[] = $child; - } - } - $this->setChildren($newChildren); - - return $this; - } - - /** - * Attach a {@link Swift_Mime_MimeEntity} and return it's CID source. - * This method should be used when embedding images or other data in a message. - * - * @param Swift_Mime_MimeEntity $entity - * - * @return string - */ - public function embed(Swift_Mime_MimeEntity $entity) - { - $this->attach($entity); - - return 'cid:'.$entity->getId(); - } - - /** - * Get this message as a complete string. - * - * @return string - */ - public function toString() - { - if (count($children = $this->getChildren()) > 0 && $this->getBody() != '') { - $this->setChildren(array_merge(array($this->_becomeMimePart()), $children)); - $string = parent::toString(); - $this->setChildren($children); - } else { - $string = parent::toString(); - } - - return $string; - } - - /** - * Returns a string representation of this object. - * - * @see toString() - * - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - /** - * Write this message to a {@link Swift_InputByteStream}. - * - * @param Swift_InputByteStream $is - */ - public function toByteStream(Swift_InputByteStream $is) - { - if (count($children = $this->getChildren()) > 0 && $this->getBody() != '') { - $this->setChildren(array_merge(array($this->_becomeMimePart()), $children)); - parent::toByteStream($is); - $this->setChildren($children); - } else { - parent::toByteStream($is); - } - } - - /** @see Swift_Mime_SimpleMimeEntity::_getIdField() */ - protected function _getIdField() - { - return 'Message-ID'; - } - - /** Turn the body of this message into a child of itself if needed */ - protected function _becomeMimePart() - { - $part = new parent($this->getHeaders()->newInstance(), $this->getEncoder(), - $this->_getCache(), $this->_getGrammar(), $this->_userCharset - ); - $part->setContentType($this->_userContentType); - $part->setBody($this->getBody()); - $part->setFormat($this->_userFormat); - $part->setDelSp($this->_userDelSp); - $part->_setNestingLevel($this->_getTopNestingLevel()); - - return $part; - } - - /** Get the highest nesting level nested inside this message */ - private function _getTopNestingLevel() - { - $highestLevel = $this->getNestingLevel(); - foreach ($this->getChildren() as $child) { - $childLevel = $child->getNestingLevel(); - if ($highestLevel < $childLevel) { - $highestLevel = $childLevel; - } - } - - return $highestLevel; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Mime/SimpleMimeEntity.php b/lib/SwiftMailer/classes/Swift/Mime/SimpleMimeEntity.php deleted file mode 100644 index 0694ee1..0000000 --- a/lib/SwiftMailer/classes/Swift/Mime/SimpleMimeEntity.php +++ /dev/null @@ -1,843 +0,0 @@ - array(self::LEVEL_TOP, self::LEVEL_MIXED), - 'multipart/alternative' => array(self::LEVEL_MIXED, self::LEVEL_ALTERNATIVE), - 'multipart/related' => array(self::LEVEL_ALTERNATIVE, self::LEVEL_RELATED), - ); - - /** A set of filter rules to define what level an entity should be nested at */ - private $_compoundLevelFilters = array(); - - /** The nesting level of this entity */ - private $_nestingLevel = self::LEVEL_ALTERNATIVE; - - /** A KeyCache instance used during encoding and streaming */ - private $_cache; - - /** Direct descendants of this entity */ - private $_immediateChildren = array(); - - /** All descendants of this entity */ - private $_children = array(); - - /** The maximum line length of the body of this entity */ - private $_maxLineLength = 78; - - /** The order in which alternative mime types should appear */ - private $_alternativePartOrder = array( - 'text/plain' => 1, - 'text/html' => 2, - 'multipart/related' => 3, - ); - - /** The CID of this entity */ - private $_id; - - /** The key used for accessing the cache */ - private $_cacheKey; - - protected $_userContentType; - - /** - * Create a new SimpleMimeEntity with $headers, $encoder and $cache. - * - * @param Swift_Mime_HeaderSet $headers - * @param Swift_Mime_ContentEncoder $encoder - * @param Swift_KeyCache $cache - * @param Swift_Mime_Grammar $grammar - */ - public function __construct(Swift_Mime_HeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_Mime_Grammar $grammar) - { - $this->_cacheKey = md5(uniqid(getmypid().mt_rand(), true)); - $this->_cache = $cache; - $this->_headers = $headers; - $this->_grammar = $grammar; - $this->setEncoder($encoder); - $this->_headers->defineOrdering(array('Content-Type', 'Content-Transfer-Encoding')); - - // This array specifies that, when the entire MIME document contains - // $compoundLevel, then for each child within $level, if its Content-Type - // is $contentType then it should be treated as if it's level is - // $neededLevel instead. I tried to write that unambiguously! :-\ - // Data Structure: - // array ( - // $compoundLevel => array( - // $level => array( - // $contentType => $neededLevel - // ) - // ) - // ) - - $this->_compoundLevelFilters = array( - (self::LEVEL_ALTERNATIVE + self::LEVEL_RELATED) => array( - self::LEVEL_ALTERNATIVE => array( - 'text/plain' => self::LEVEL_ALTERNATIVE, - 'text/html' => self::LEVEL_RELATED, - ), - ), - ); - - $this->_id = $this->getRandomId(); - } - - /** - * Generate a new Content-ID or Message-ID for this MIME entity. - * - * @return string - */ - public function generateId() - { - $this->setId($this->getRandomId()); - - return $this->_id; - } - - /** - * Get the {@link Swift_Mime_HeaderSet} for this entity. - * - * @return Swift_Mime_HeaderSet - */ - public function getHeaders() - { - return $this->_headers; - } - - /** - * Get the nesting level of this entity. - * - * @see LEVEL_TOP, LEVEL_MIXED, LEVEL_RELATED, LEVEL_ALTERNATIVE - * - * @return int - */ - public function getNestingLevel() - { - return $this->_nestingLevel; - } - - /** - * Get the Content-type of this entity. - * - * @return string - */ - public function getContentType() - { - return $this->_getHeaderFieldModel('Content-Type'); - } - - /** - * Set the Content-type of this entity. - * - * @param string $type - * - * @return Swift_Mime_SimpleMimeEntity - */ - public function setContentType($type) - { - $this->_setContentTypeInHeaders($type); - // Keep track of the value so that if the content-type changes automatically - // due to added child entities, it can be restored if they are later removed - $this->_userContentType = $type; - - return $this; - } - - /** - * Get the CID of this entity. - * - * The CID will only be present in headers if a Content-ID header is present. - * - * @return string - */ - public function getId() - { - $tmp = (array) $this->_getHeaderFieldModel($this->_getIdField()); - - return $this->_headers->has($this->_getIdField()) ? current($tmp) : $this->_id; - } - - /** - * Set the CID of this entity. - * - * @param string $id - * - * @return Swift_Mime_SimpleMimeEntity - */ - public function setId($id) - { - if (!$this->_setHeaderFieldModel($this->_getIdField(), $id)) { - $this->_headers->addIdHeader($this->_getIdField(), $id); - } - $this->_id = $id; - - return $this; - } - - /** - * Get the description of this entity. - * - * This value comes from the Content-Description header if set. - * - * @return string - */ - public function getDescription() - { - return $this->_getHeaderFieldModel('Content-Description'); - } - - /** - * Set the description of this entity. - * - * This method sets a value in the Content-ID header. - * - * @param string $description - * - * @return Swift_Mime_SimpleMimeEntity - */ - public function setDescription($description) - { - if (!$this->_setHeaderFieldModel('Content-Description', $description)) { - $this->_headers->addTextHeader('Content-Description', $description); - } - - return $this; - } - - /** - * Get the maximum line length of the body of this entity. - * - * @return int - */ - public function getMaxLineLength() - { - return $this->_maxLineLength; - } - - /** - * Set the maximum line length of lines in this body. - * - * Though not enforced by the library, lines should not exceed 1000 chars. - * - * @param int $length - * - * @return Swift_Mime_SimpleMimeEntity - */ - public function setMaxLineLength($length) - { - $this->_maxLineLength = $length; - - return $this; - } - - /** - * Get all children added to this entity. - * - * @return Swift_Mime_MimeEntity[] - */ - public function getChildren() - { - return $this->_children; - } - - /** - * Set all children of this entity. - * - * @param Swift_Mime_MimeEntity[] $children - * @param int $compoundLevel For internal use only - * - * @return Swift_Mime_SimpleMimeEntity - */ - public function setChildren(array $children, $compoundLevel = null) - { - // TODO: Try to refactor this logic - - $compoundLevel = isset($compoundLevel) ? $compoundLevel : $this->_getCompoundLevel($children); - $immediateChildren = array(); - $grandchildren = array(); - $newContentType = $this->_userContentType; - - foreach ($children as $child) { - $level = $this->_getNeededChildLevel($child, $compoundLevel); - if (empty($immediateChildren)) { - //first iteration - $immediateChildren = array($child); - } else { - $nextLevel = $this->_getNeededChildLevel($immediateChildren[0], $compoundLevel); - if ($nextLevel == $level) { - $immediateChildren[] = $child; - } elseif ($level < $nextLevel) { - // Re-assign immediateChildren to grandchildren - $grandchildren = array_merge($grandchildren, $immediateChildren); - // Set new children - $immediateChildren = array($child); - } else { - $grandchildren[] = $child; - } - } - } - - if ($immediateChildren) { - $lowestLevel = $this->_getNeededChildLevel($immediateChildren[0], $compoundLevel); - - // Determine which composite media type is needed to accommodate the - // immediate children - foreach ($this->_compositeRanges as $mediaType => $range) { - if ($lowestLevel > $range[0] && $lowestLevel <= $range[1]) { - $newContentType = $mediaType; - - break; - } - } - - // Put any grandchildren in a subpart - if (!empty($grandchildren)) { - $subentity = $this->_createChild(); - $subentity->_setNestingLevel($lowestLevel); - $subentity->setChildren($grandchildren, $compoundLevel); - array_unshift($immediateChildren, $subentity); - } - } - - $this->_immediateChildren = $immediateChildren; - $this->_children = $children; - $this->_setContentTypeInHeaders($newContentType); - $this->_fixHeaders(); - $this->_sortChildren(); - - return $this; - } - - /** - * Get the body of this entity as a string. - * - * @return string - */ - public function getBody() - { - return $this->_body instanceof Swift_OutputByteStream ? $this->_readStream($this->_body) : $this->_body; - } - - /** - * Set the body of this entity, either as a string, or as an instance of - * {@link Swift_OutputByteStream}. - * - * @param mixed $body - * @param string $contentType optional - * - * @return Swift_Mime_SimpleMimeEntity - */ - public function setBody($body, $contentType = null) - { - if ($body !== $this->_body) { - $this->_clearCache(); - } - - $this->_body = $body; - if (isset($contentType)) { - $this->setContentType($contentType); - } - - return $this; - } - - /** - * Get the encoder used for the body of this entity. - * - * @return Swift_Mime_ContentEncoder - */ - public function getEncoder() - { - return $this->_encoder; - } - - /** - * Set the encoder used for the body of this entity. - * - * @param Swift_Mime_ContentEncoder $encoder - * - * @return Swift_Mime_SimpleMimeEntity - */ - public function setEncoder(Swift_Mime_ContentEncoder $encoder) - { - if ($encoder !== $this->_encoder) { - $this->_clearCache(); - } - - $this->_encoder = $encoder; - $this->_setEncoding($encoder->getName()); - $this->_notifyEncoderChanged($encoder); - - return $this; - } - - /** - * Get the boundary used to separate children in this entity. - * - * @return string - */ - public function getBoundary() - { - if (!isset($this->_boundary)) { - $this->_boundary = '_=_swift_v4_'.time().'_'.md5(getmypid().mt_rand().uniqid('', true)).'_=_'; - } - - return $this->_boundary; - } - - /** - * Set the boundary used to separate children in this entity. - * - * @param string $boundary - * - * @throws Swift_RfcComplianceException - * - * @return Swift_Mime_SimpleMimeEntity - */ - public function setBoundary($boundary) - { - $this->_assertValidBoundary($boundary); - $this->_boundary = $boundary; - - return $this; - } - - /** - * Receive notification that the charset of this entity, or a parent entity - * has changed. - * - * @param string $charset - */ - public function charsetChanged($charset) - { - $this->_notifyCharsetChanged($charset); - } - - /** - * Receive notification that the encoder of this entity or a parent entity - * has changed. - * - * @param Swift_Mime_ContentEncoder $encoder - */ - public function encoderChanged(Swift_Mime_ContentEncoder $encoder) - { - $this->_notifyEncoderChanged($encoder); - } - - /** - * Get this entire entity as a string. - * - * @return string - */ - public function toString() - { - $string = $this->_headers->toString(); - $string .= $this->_bodyToString(); - - return $string; - } - - /** - * Get this entire entity as a string. - * - * @return string - */ - protected function _bodyToString() - { - $string = ''; - - if (isset($this->_body) && empty($this->_immediateChildren)) { - if ($this->_cache->hasKey($this->_cacheKey, 'body')) { - $body = $this->_cache->getString($this->_cacheKey, 'body'); - } else { - $body = "\r\n".$this->_encoder->encodeString($this->getBody(), 0, $this->getMaxLineLength()); - $this->_cache->setString($this->_cacheKey, 'body', $body, Swift_KeyCache::MODE_WRITE); - } - $string .= $body; - } - - if (!empty($this->_immediateChildren)) { - foreach ($this->_immediateChildren as $child) { - $string .= "\r\n\r\n--".$this->getBoundary()."\r\n"; - $string .= $child->toString(); - } - $string .= "\r\n\r\n--".$this->getBoundary()."--\r\n"; - } - - return $string; - } - - /** - * Returns a string representation of this object. - * - * @see toString() - * - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - /** - * Write this entire entity to a {@see Swift_InputByteStream}. - * - * @param Swift_InputByteStream - */ - public function toByteStream(Swift_InputByteStream $is) - { - $is->write($this->_headers->toString()); - $is->commit(); - - $this->_bodyToByteStream($is); - } - - /** - * Write this entire entity to a {@link Swift_InputByteStream}. - * - * @param Swift_InputByteStream - */ - protected function _bodyToByteStream(Swift_InputByteStream $is) - { - if (empty($this->_immediateChildren)) { - if (isset($this->_body)) { - if ($this->_cache->hasKey($this->_cacheKey, 'body')) { - $this->_cache->exportToByteStream($this->_cacheKey, 'body', $is); - } else { - $cacheIs = $this->_cache->getInputByteStream($this->_cacheKey, 'body'); - if ($cacheIs) { - $is->bind($cacheIs); - } - - $is->write("\r\n"); - - if ($this->_body instanceof Swift_OutputByteStream) { - $this->_body->setReadPointer(0); - - $this->_encoder->encodeByteStream($this->_body, $is, 0, $this->getMaxLineLength()); - } else { - $is->write($this->_encoder->encodeString($this->getBody(), 0, $this->getMaxLineLength())); - } - - if ($cacheIs) { - $is->unbind($cacheIs); - } - } - } - } - - if (!empty($this->_immediateChildren)) { - foreach ($this->_immediateChildren as $child) { - $is->write("\r\n\r\n--".$this->getBoundary()."\r\n"); - $child->toByteStream($is); - } - $is->write("\r\n\r\n--".$this->getBoundary()."--\r\n"); - } - } - - /** - * Get the name of the header that provides the ID of this entity. - */ - protected function _getIdField() - { - return 'Content-ID'; - } - - /** - * Get the model data (usually an array or a string) for $field. - */ - protected function _getHeaderFieldModel($field) - { - if ($this->_headers->has($field)) { - return $this->_headers->get($field)->getFieldBodyModel(); - } - } - - /** - * Set the model data for $field. - */ - protected function _setHeaderFieldModel($field, $model) - { - if ($this->_headers->has($field)) { - $this->_headers->get($field)->setFieldBodyModel($model); - - return true; - } - - return false; - } - - /** - * Get the parameter value of $parameter on $field header. - */ - protected function _getHeaderParameter($field, $parameter) - { - if ($this->_headers->has($field)) { - return $this->_headers->get($field)->getParameter($parameter); - } - } - - /** - * Set the parameter value of $parameter on $field header. - */ - protected function _setHeaderParameter($field, $parameter, $value) - { - if ($this->_headers->has($field)) { - $this->_headers->get($field)->setParameter($parameter, $value); - - return true; - } - - return false; - } - - /** - * Re-evaluate what content type and encoding should be used on this entity. - */ - protected function _fixHeaders() - { - if (count($this->_immediateChildren)) { - $this->_setHeaderParameter('Content-Type', 'boundary', - $this->getBoundary() - ); - $this->_headers->remove('Content-Transfer-Encoding'); - } else { - $this->_setHeaderParameter('Content-Type', 'boundary', null); - $this->_setEncoding($this->_encoder->getName()); - } - } - - /** - * Get the KeyCache used in this entity. - * - * @return Swift_KeyCache - */ - protected function _getCache() - { - return $this->_cache; - } - - /** - * Get the grammar used for validation. - * - * @return Swift_Mime_Grammar - */ - protected function _getGrammar() - { - return $this->_grammar; - } - - /** - * Empty the KeyCache for this entity. - */ - protected function _clearCache() - { - $this->_cache->clearKey($this->_cacheKey, 'body'); - } - - /** - * Returns a random Content-ID or Message-ID. - * - * @return string - */ - protected function getRandomId() - { - $idLeft = md5(getmypid().'.'.time().'.'.uniqid(mt_rand(), true)); - $idRight = !empty($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'swift.generated'; - $id = $idLeft.'@'.$idRight; - - try { - $this->_assertValidId($id); - } catch (Swift_RfcComplianceException $e) { - $id = $idLeft.'@swift.generated'; - } - - return $id; - } - - private function _readStream(Swift_OutputByteStream $os) - { - $string = ''; - while (false !== $bytes = $os->read(8192)) { - $string .= $bytes; - } - - $os->setReadPointer(0); - - return $string; - } - - private function _setEncoding($encoding) - { - if (!$this->_setHeaderFieldModel('Content-Transfer-Encoding', $encoding)) { - $this->_headers->addTextHeader('Content-Transfer-Encoding', $encoding); - } - } - - private function _assertValidBoundary($boundary) - { - if (!preg_match('/^[a-z0-9\'\(\)\+_\-,\.\/:=\?\ ]{0,69}[a-z0-9\'\(\)\+_\-,\.\/:=\?]$/Di', $boundary)) { - throw new Swift_RfcComplianceException('Mime boundary set is not RFC 2046 compliant.'); - } - } - - private function _setContentTypeInHeaders($type) - { - if (!$this->_setHeaderFieldModel('Content-Type', $type)) { - $this->_headers->addParameterizedHeader('Content-Type', $type); - } - } - - private function _setNestingLevel($level) - { - $this->_nestingLevel = $level; - } - - private function _getCompoundLevel($children) - { - $level = 0; - foreach ($children as $child) { - $level |= $child->getNestingLevel(); - } - - return $level; - } - - private function _getNeededChildLevel($child, $compoundLevel) - { - $filter = array(); - foreach ($this->_compoundLevelFilters as $bitmask => $rules) { - if (($compoundLevel & $bitmask) === $bitmask) { - $filter = $rules + $filter; - } - } - - $realLevel = $child->getNestingLevel(); - $lowercaseType = strtolower($child->getContentType()); - - if (isset($filter[$realLevel]) && isset($filter[$realLevel][$lowercaseType])) { - return $filter[$realLevel][$lowercaseType]; - } - - return $realLevel; - } - - private function _createChild() - { - return new self($this->_headers->newInstance(), $this->_encoder, $this->_cache, $this->_grammar); - } - - private function _notifyEncoderChanged(Swift_Mime_ContentEncoder $encoder) - { - foreach ($this->_immediateChildren as $child) { - $child->encoderChanged($encoder); - } - } - - private function _notifyCharsetChanged($charset) - { - $this->_encoder->charsetChanged($charset); - $this->_headers->charsetChanged($charset); - foreach ($this->_immediateChildren as $child) { - $child->charsetChanged($charset); - } - } - - private function _sortChildren() - { - $shouldSort = false; - foreach ($this->_immediateChildren as $child) { - // NOTE: This include alternative parts moved into a related part - if ($child->getNestingLevel() == self::LEVEL_ALTERNATIVE) { - $shouldSort = true; - break; - } - } - - // Sort in order of preference, if there is one - if ($shouldSort) { - usort($this->_immediateChildren, array($this, '_childSortAlgorithm')); - } - } - - private function _childSortAlgorithm($a, $b) - { - $typePrefs = array(); - $types = array(strtolower($a->getContentType()), strtolower($b->getContentType())); - - foreach ($types as $type) { - $typePrefs[] = array_key_exists($type, $this->_alternativePartOrder) ? $this->_alternativePartOrder[$type] : max($this->_alternativePartOrder) + 1; - } - - return $typePrefs[0] >= $typePrefs[1] ? 1 : -1; - } - - // -- Destructor - - /** - * Empties it's own contents from the cache. - */ - public function __destruct() - { - $this->_cache->clearAll($this->_cacheKey); - } - - /** - * Throws an Exception if the id passed does not comply with RFC 2822. - * - * @param string $id - * - * @throws Swift_RfcComplianceException - */ - private function _assertValidId($id) - { - if (!preg_match('/^'.$this->_grammar->getDefinition('id-left').'@'.$this->_grammar->getDefinition('id-right').'$/D', $id)) { - throw new Swift_RfcComplianceException('Invalid ID given <'.$id.'>'); - } - } - - /** - * Make a deep copy of object. - */ - public function __clone() - { - $this->_headers = clone $this->_headers; - $this->_encoder = clone $this->_encoder; - $this->_cacheKey = md5(uniqid(getmypid().mt_rand(), true)); - $children = array(); - foreach ($this->_children as $pos => $child) { - $children[$pos] = clone $child; - } - $this->setChildren($children); - } -} diff --git a/lib/SwiftMailer/classes/Swift/MimePart.php b/lib/SwiftMailer/classes/Swift/MimePart.php deleted file mode 100644 index 215f8db..0000000 --- a/lib/SwiftMailer/classes/Swift/MimePart.php +++ /dev/null @@ -1,59 +0,0 @@ -createDependenciesFor('mime.part') - ); - - if (!isset($charset)) { - $charset = Swift_DependencyContainer::getInstance() - ->lookup('properties.charset'); - } - $this->setBody($body); - $this->setCharset($charset); - if ($contentType) { - $this->setContentType($contentType); - } - } - - /** - * Create a new MimePart. - * - * @param string $body - * @param string $contentType - * @param string $charset - * - * @return Swift_Mime_MimePart - */ - public static function newInstance($body = null, $contentType = null, $charset = null) - { - return new self($body, $contentType, $charset); - } -} diff --git a/lib/SwiftMailer/classes/Swift/NullTransport.php b/lib/SwiftMailer/classes/Swift/NullTransport.php deleted file mode 100644 index b38e1cf..0000000 --- a/lib/SwiftMailer/classes/Swift/NullTransport.php +++ /dev/null @@ -1,39 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Pretends messages have been sent, but just ignores them. - * - * @author Fabien Potencier - */ -class Swift_NullTransport extends Swift_Transport_NullTransport -{ - /** - * Create a new NullTransport. - */ - public function __construct() - { - call_user_func_array( - array($this, 'Swift_Transport_NullTransport::__construct'), - Swift_DependencyContainer::getInstance() - ->createDependenciesFor('transport.null') - ); - } - - /** - * Create a new NullTransport instance. - * - * @return Swift_NullTransport - */ - public static function newInstance() - { - return new self(); - } -} diff --git a/lib/SwiftMailer/classes/Swift/OutputByteStream.php b/lib/SwiftMailer/classes/Swift/OutputByteStream.php deleted file mode 100644 index 1f26f9b..0000000 --- a/lib/SwiftMailer/classes/Swift/OutputByteStream.php +++ /dev/null @@ -1,46 +0,0 @@ -setThreshold($threshold); - $this->setSleepTime($sleep); - $this->_sleeper = $sleeper; - } - - /** - * Set the number of emails to send before restarting. - * - * @param int $threshold - */ - public function setThreshold($threshold) - { - $this->_threshold = $threshold; - } - - /** - * Get the number of emails to send before restarting. - * - * @return int - */ - public function getThreshold() - { - return $this->_threshold; - } - - /** - * Set the number of seconds to sleep for during a restart. - * - * @param int $sleep time - */ - public function setSleepTime($sleep) - { - $this->_sleep = $sleep; - } - - /** - * Get the number of seconds to sleep for during a restart. - * - * @return int - */ - public function getSleepTime() - { - return $this->_sleep; - } - - /** - * Invoked immediately before the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) - { - } - - /** - * Invoked immediately after the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt) - { - ++$this->_counter; - if ($this->_counter >= $this->_threshold) { - $transport = $evt->getTransport(); - $transport->stop(); - if ($this->_sleep) { - $this->sleep($this->_sleep); - } - $transport->start(); - $this->_counter = 0; - } - } - - /** - * Sleep for $seconds. - * - * @param int $seconds - */ - public function sleep($seconds) - { - if (isset($this->_sleeper)) { - $this->_sleeper->sleep($seconds); - } else { - sleep($seconds); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/BandwidthMonitorPlugin.php b/lib/SwiftMailer/classes/Swift/Plugins/BandwidthMonitorPlugin.php deleted file mode 100644 index f7e18d0..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/BandwidthMonitorPlugin.php +++ /dev/null @@ -1,164 +0,0 @@ -getMessage(); - $message->toByteStream($this); - } - - /** - * Invoked immediately following a command being sent. - * - * @param Swift_Events_CommandEvent $evt - */ - public function commandSent(Swift_Events_CommandEvent $evt) - { - $command = $evt->getCommand(); - $this->_out += strlen($command); - } - - /** - * Invoked immediately following a response coming back. - * - * @param Swift_Events_ResponseEvent $evt - */ - public function responseReceived(Swift_Events_ResponseEvent $evt) - { - $response = $evt->getResponse(); - $this->_in += strlen($response); - } - - /** - * Called when a message is sent so that the outgoing counter can be increased. - * - * @param string $bytes - */ - public function write($bytes) - { - $this->_out += strlen($bytes); - foreach ($this->_mirrors as $stream) { - $stream->write($bytes); - } - } - - /** - * Not used. - */ - public function commit() - { - } - - /** - * Attach $is to this stream. - * - * The stream acts as an observer, receiving all data that is written. - * All {@link write()} and {@link flushBuffers()} operations will be mirrored. - * - * @param Swift_InputByteStream $is - */ - public function bind(Swift_InputByteStream $is) - { - $this->_mirrors[] = $is; - } - - /** - * Remove an already bound stream. - * - * If $is is not bound, no errors will be raised. - * If the stream currently has any buffered data it will be written to $is - * before unbinding occurs. - * - * @param Swift_InputByteStream $is - */ - public function unbind(Swift_InputByteStream $is) - { - foreach ($this->_mirrors as $k => $stream) { - if ($is === $stream) { - unset($this->_mirrors[$k]); - } - } - } - - /** - * Not used. - */ - public function flushBuffers() - { - foreach ($this->_mirrors as $stream) { - $stream->flushBuffers(); - } - } - - /** - * Get the total number of bytes sent to the server. - * - * @return int - */ - public function getBytesOut() - { - return $this->_out; - } - - /** - * Get the total number of bytes received from the server. - * - * @return int - */ - public function getBytesIn() - { - return $this->_in; - } - - /** - * Reset the internal counters to zero. - */ - public function reset() - { - $this->_out = 0; - $this->_in = 0; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/Decorator/Replacements.php b/lib/SwiftMailer/classes/Swift/Plugins/Decorator/Replacements.php deleted file mode 100644 index 9f9f08b..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/Decorator/Replacements.php +++ /dev/null @@ -1,31 +0,0 @@ - - * $replacements = array( - * "address1@domain.tld" => array("{a}" => "b", "{c}" => "d"), - * "address2@domain.tld" => array("{a}" => "x", "{c}" => "y") - * ) - * - * - * When using an instance of {@link Swift_Plugins_Decorator_Replacements}, - * the object should return just the array of replacements for the address - * given to {@link Swift_Plugins_Decorator_Replacements::getReplacementsFor()}. - * - * @param mixed $replacements Array or Swift_Plugins_Decorator_Replacements - */ - public function __construct($replacements) - { - $this->setReplacements($replacements); - } - - /** - * Sets replacements. - * - * @param mixed $replacements Array or Swift_Plugins_Decorator_Replacements - * - * @see __construct() - */ - public function setReplacements($replacements) - { - if (!($replacements instanceof Swift_Plugins_Decorator_Replacements)) { - $this->_replacements = (array) $replacements; - } else { - $this->_replacements = $replacements; - } - } - - /** - * Invoked immediately before the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) - { - $message = $evt->getMessage(); - $this->_restoreMessage($message); - $to = array_keys($message->getTo()); - $address = array_shift($to); - if ($replacements = $this->getReplacementsFor($address)) { - $body = $message->getBody(); - $search = array_keys($replacements); - $replace = array_values($replacements); - $bodyReplaced = str_replace( - $search, $replace, $body - ); - if ($body != $bodyReplaced) { - $this->_originalBody = $body; - $message->setBody($bodyReplaced); - } - - foreach ($message->getHeaders()->getAll() as $header) { - $body = $header->getFieldBodyModel(); - $count = 0; - if (is_array($body)) { - $bodyReplaced = array(); - foreach ($body as $key => $value) { - $count1 = 0; - $count2 = 0; - $key = is_string($key) ? str_replace($search, $replace, $key, $count1) : $key; - $value = is_string($value) ? str_replace($search, $replace, $value, $count2) : $value; - $bodyReplaced[$key] = $value; - - if (!$count && ($count1 || $count2)) { - $count = 1; - } - } - } else { - $bodyReplaced = str_replace($search, $replace, $body, $count); - } - - if ($count) { - $this->_originalHeaders[$header->getFieldName()] = $body; - $header->setFieldBodyModel($bodyReplaced); - } - } - - $children = (array) $message->getChildren(); - foreach ($children as $child) { - list($type) = sscanf($child->getContentType(), '%[^/]/%s'); - if ('text' == $type) { - $body = $child->getBody(); - $bodyReplaced = str_replace( - $search, $replace, $body - ); - if ($body != $bodyReplaced) { - $child->setBody($bodyReplaced); - $this->_originalChildBodies[$child->getId()] = $body; - } - } - } - $this->_lastMessage = $message; - } - } - - /** - * Find a map of replacements for the address. - * - * If this plugin was provided with a delegate instance of - * {@link Swift_Plugins_Decorator_Replacements} then the call will be - * delegated to it. Otherwise, it will attempt to find the replacements - * from the array provided in the constructor. - * - * If no replacements can be found, an empty value (NULL) is returned. - * - * @param string $address - * - * @return array - */ - public function getReplacementsFor($address) - { - if ($this->_replacements instanceof Swift_Plugins_Decorator_Replacements) { - return $this->_replacements->getReplacementsFor($address); - } - - return isset($this->_replacements[$address]) ? $this->_replacements[$address] : null; - } - - /** - * Invoked immediately after the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt) - { - $this->_restoreMessage($evt->getMessage()); - } - - /** Restore a changed message back to its original state */ - private function _restoreMessage(Swift_Mime_Message $message) - { - if ($this->_lastMessage === $message) { - if (isset($this->_originalBody)) { - $message->setBody($this->_originalBody); - $this->_originalBody = null; - } - if (!empty($this->_originalHeaders)) { - foreach ($message->getHeaders()->getAll() as $header) { - if (array_key_exists($header->getFieldName(), $this->_originalHeaders)) { - $header->setFieldBodyModel($this->_originalHeaders[$header->getFieldName()]); - } - } - $this->_originalHeaders = array(); - } - if (!empty($this->_originalChildBodies)) { - $children = (array) $message->getChildren(); - foreach ($children as $child) { - $id = $child->getId(); - if (array_key_exists($id, $this->_originalChildBodies)) { - $child->setBody($this->_originalChildBodies[$id]); - } - } - $this->_originalChildBodies = array(); - } - $this->_lastMessage = null; - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/ImpersonatePlugin.php b/lib/SwiftMailer/classes/Swift/Plugins/ImpersonatePlugin.php deleted file mode 100644 index 7552b67..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/ImpersonatePlugin.php +++ /dev/null @@ -1,69 +0,0 @@ -_sender = $sender; - } - - /** - * Invoked immediately before the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) - { - $message = $evt->getMessage(); - $headers = $message->getHeaders(); - - // save current recipients - $headers->addPathHeader('X-Swift-Return-Path', $message->getReturnPath()); - - // replace them with the one to send to - $message->setReturnPath($this->_sender); - } - - /** - * Invoked immediately after the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt) - { - $message = $evt->getMessage(); - - // restore original headers - $headers = $message->getHeaders(); - - if ($headers->has('X-Swift-Return-Path')) { - $message->setReturnPath($headers->get('X-Swift-Return-Path')->getAddress()); - $headers->removeAll('X-Swift-Return-Path'); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/Logger.php b/lib/SwiftMailer/classes/Swift/Plugins/Logger.php deleted file mode 100644 index d9bce89..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/Logger.php +++ /dev/null @@ -1,36 +0,0 @@ -_logger = $logger; - } - - /** - * Add a log entry. - * - * @param string $entry - */ - public function add($entry) - { - $this->_logger->add($entry); - } - - /** - * Clear the log contents. - */ - public function clear() - { - $this->_logger->clear(); - } - - /** - * Get this log as a string. - * - * @return string - */ - public function dump() - { - return $this->_logger->dump(); - } - - /** - * Invoked immediately following a command being sent. - * - * @param Swift_Events_CommandEvent $evt - */ - public function commandSent(Swift_Events_CommandEvent $evt) - { - $command = $evt->getCommand(); - $this->_logger->add(sprintf('>> %s', $command)); - } - - /** - * Invoked immediately following a response coming back. - * - * @param Swift_Events_ResponseEvent $evt - */ - public function responseReceived(Swift_Events_ResponseEvent $evt) - { - $response = $evt->getResponse(); - $this->_logger->add(sprintf('<< %s', $response)); - } - - /** - * Invoked just before a Transport is started. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt) - { - $transportName = get_class($evt->getSource()); - $this->_logger->add(sprintf('++ Starting %s', $transportName)); - } - - /** - * Invoked immediately after the Transport is started. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function transportStarted(Swift_Events_TransportChangeEvent $evt) - { - $transportName = get_class($evt->getSource()); - $this->_logger->add(sprintf('++ %s started', $transportName)); - } - - /** - * Invoked just before a Transport is stopped. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt) - { - $transportName = get_class($evt->getSource()); - $this->_logger->add(sprintf('++ Stopping %s', $transportName)); - } - - /** - * Invoked immediately after the Transport is stopped. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function transportStopped(Swift_Events_TransportChangeEvent $evt) - { - $transportName = get_class($evt->getSource()); - $this->_logger->add(sprintf('++ %s stopped', $transportName)); - } - - /** - * Invoked as a TransportException is thrown in the Transport system. - * - * @param Swift_Events_TransportExceptionEvent $evt - */ - public function exceptionThrown(Swift_Events_TransportExceptionEvent $evt) - { - $e = $evt->getException(); - $message = $e->getMessage(); - $code = $e->getCode(); - $this->_logger->add(sprintf('!! %s (code: %s)', $message, $code)); - $message .= PHP_EOL; - $message .= 'Log data:'.PHP_EOL; - $message .= $this->_logger->dump(); - $evt->cancelBubble(); - throw new Swift_TransportException($message, $code, $e->getPrevious()); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/Loggers/ArrayLogger.php b/lib/SwiftMailer/classes/Swift/Plugins/Loggers/ArrayLogger.php deleted file mode 100644 index 865bb0a..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/Loggers/ArrayLogger.php +++ /dev/null @@ -1,72 +0,0 @@ -_size = $size; - } - - /** - * Add a log entry. - * - * @param string $entry - */ - public function add($entry) - { - $this->_log[] = $entry; - while (count($this->_log) > $this->_size) { - array_shift($this->_log); - } - } - - /** - * Clear the log contents. - */ - public function clear() - { - $this->_log = array(); - } - - /** - * Get this log as a string. - * - * @return string - */ - public function dump() - { - return implode(PHP_EOL, $this->_log); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/Loggers/EchoLogger.php b/lib/SwiftMailer/classes/Swift/Plugins/Loggers/EchoLogger.php deleted file mode 100644 index 3583297..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/Loggers/EchoLogger.php +++ /dev/null @@ -1,58 +0,0 @@ -_isHtml = $isHtml; - } - - /** - * Add a log entry. - * - * @param string $entry - */ - public function add($entry) - { - if ($this->_isHtml) { - printf('%s%s%s', htmlspecialchars($entry, ENT_QUOTES), '
', PHP_EOL); - } else { - printf('%s%s', $entry, PHP_EOL); - } - } - - /** - * Not implemented. - */ - public function clear() - { - } - - /** - * Not implemented. - */ - public function dump() - { - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/MessageLogger.php b/lib/SwiftMailer/classes/Swift/Plugins/MessageLogger.php deleted file mode 100644 index e622cb3..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/MessageLogger.php +++ /dev/null @@ -1,74 +0,0 @@ -messages = array(); - } - - /** - * Get the message list. - * - * @return array - */ - public function getMessages() - { - return $this->messages; - } - - /** - * Get the message count. - * - * @return int count - */ - public function countMessages() - { - return count($this->messages); - } - - /** - * Empty the message list. - */ - public function clear() - { - $this->messages = array(); - } - - /** - * Invoked immediately before the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) - { - $this->messages[] = clone $evt->getMessage(); - } - - /** - * Invoked immediately after the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt) - { - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/Pop/Pop3Connection.php b/lib/SwiftMailer/classes/Swift/Plugins/Pop/Pop3Connection.php deleted file mode 100644 index fb99e4c..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/Pop/Pop3Connection.php +++ /dev/null @@ -1,31 +0,0 @@ -_host = $host; - $this->_port = $port; - $this->_crypto = $crypto; - } - - /** - * Create a new PopBeforeSmtpPlugin for $host and $port. - * - * @param string $host - * @param int $port - * @param string $crypto as "tls" or "ssl" - * - * @return Swift_Plugins_PopBeforeSmtpPlugin - */ - public static function newInstance($host, $port = 110, $crypto = null) - { - return new self($host, $port, $crypto); - } - - /** - * Set a Pop3Connection to delegate to instead of connecting directly. - * - * @param Swift_Plugins_Pop_Pop3Connection $connection - * - * @return Swift_Plugins_PopBeforeSmtpPlugin - */ - public function setConnection(Swift_Plugins_Pop_Pop3Connection $connection) - { - $this->_connection = $connection; - - return $this; - } - - /** - * Bind this plugin to a specific SMTP transport instance. - * - * @param Swift_Transport - */ - public function bindSmtp(Swift_Transport $smtp) - { - $this->_transport = $smtp; - } - - /** - * Set the connection timeout in seconds (default 10). - * - * @param int $timeout - * - * @return Swift_Plugins_PopBeforeSmtpPlugin - */ - public function setTimeout($timeout) - { - $this->_timeout = (int) $timeout; - - return $this; - } - - /** - * Set the username to use when connecting (if needed). - * - * @param string $username - * - * @return Swift_Plugins_PopBeforeSmtpPlugin - */ - public function setUsername($username) - { - $this->_username = $username; - - return $this; - } - - /** - * Set the password to use when connecting (if needed). - * - * @param string $password - * - * @return Swift_Plugins_PopBeforeSmtpPlugin - */ - public function setPassword($password) - { - $this->_password = $password; - - return $this; - } - - /** - * Connect to the POP3 host and authenticate. - * - * @throws Swift_Plugins_Pop_Pop3Exception if connection fails - */ - public function connect() - { - if (isset($this->_connection)) { - $this->_connection->connect(); - } else { - if (!isset($this->_socket)) { - if (!$socket = fsockopen( - $this->_getHostString(), $this->_port, $errno, $errstr, $this->_timeout)) { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('Failed to connect to POP3 host [%s]: %s', $this->_host, $errstr) - ); - } - $this->_socket = $socket; - - if (false === $greeting = fgets($this->_socket)) { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('Failed to connect to POP3 host [%s]', trim($greeting)) - ); - } - - $this->_assertOk($greeting); - - if ($this->_username) { - $this->_command(sprintf("USER %s\r\n", $this->_username)); - $this->_command(sprintf("PASS %s\r\n", $this->_password)); - } - } - } - } - - /** - * Disconnect from the POP3 host. - */ - public function disconnect() - { - if (isset($this->_connection)) { - $this->_connection->disconnect(); - } else { - $this->_command("QUIT\r\n"); - if (!fclose($this->_socket)) { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('POP3 host [%s] connection could not be stopped', $this->_host) - ); - } - $this->_socket = null; - } - } - - /** - * Invoked just before a Transport is started. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt) - { - if (isset($this->_transport)) { - if ($this->_transport !== $evt->getTransport()) { - return; - } - } - - $this->connect(); - $this->disconnect(); - } - - /** - * Not used. - */ - public function transportStarted(Swift_Events_TransportChangeEvent $evt) - { - } - - /** - * Not used. - */ - public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt) - { - } - - /** - * Not used. - */ - public function transportStopped(Swift_Events_TransportChangeEvent $evt) - { - } - - private function _command($command) - { - if (!fwrite($this->_socket, $command)) { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('Failed to write command [%s] to POP3 host', trim($command)) - ); - } - - if (false === $response = fgets($this->_socket)) { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('Failed to read from POP3 host after command [%s]', trim($command)) - ); - } - - $this->_assertOk($response); - - return $response; - } - - private function _assertOk($response) - { - if (substr($response, 0, 3) != '+OK') { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('POP3 command failed [%s]', trim($response)) - ); - } - } - - private function _getHostString() - { - $host = $this->_host; - switch (strtolower($this->_crypto)) { - case 'ssl': - $host = 'ssl://'.$host; - break; - - case 'tls': - $host = 'tls://'.$host; - break; - } - - return $host; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/RedirectingPlugin.php b/lib/SwiftMailer/classes/Swift/Plugins/RedirectingPlugin.php deleted file mode 100644 index c3a1f86..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/RedirectingPlugin.php +++ /dev/null @@ -1,213 +0,0 @@ -_recipient = $recipient; - $this->_whitelist = $whitelist; - } - - /** - * Set the recipient of all messages. - * - * @param mixed $recipient - */ - public function setRecipient($recipient) - { - $this->_recipient = $recipient; - } - - /** - * Get the recipient of all messages. - * - * @return mixed - */ - public function getRecipient() - { - return $this->_recipient; - } - - /** - * Set a list of regular expressions to whitelist certain recipients. - * - * @param array $whitelist - */ - public function setWhitelist(array $whitelist) - { - $this->_whitelist = $whitelist; - } - - /** - * Get the whitelist. - * - * @return array - */ - public function getWhitelist() - { - return $this->_whitelist; - } - - /** - * Invoked immediately before the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) - { - $message = $evt->getMessage(); - $headers = $message->getHeaders(); - - // conditionally save current recipients - - if ($headers->has('to')) { - $headers->addMailboxHeader('X-Swift-To', $message->getTo()); - } - - if ($headers->has('cc')) { - $headers->addMailboxHeader('X-Swift-Cc', $message->getCc()); - } - - if ($headers->has('bcc')) { - $headers->addMailboxHeader('X-Swift-Bcc', $message->getBcc()); - } - - // Filter remaining headers against whitelist - $this->_filterHeaderSet($headers, 'To'); - $this->_filterHeaderSet($headers, 'Cc'); - $this->_filterHeaderSet($headers, 'Bcc'); - - // Add each hard coded recipient - $to = $message->getTo(); - if (null === $to) { - $to = array(); - } - - foreach ((array) $this->_recipient as $recipient) { - if (!array_key_exists($recipient, $to)) { - $message->addTo($recipient); - } - } - } - - /** - * Filter header set against a whitelist of regular expressions. - * - * @param Swift_Mime_HeaderSet $headerSet - * @param string $type - */ - private function _filterHeaderSet(Swift_Mime_HeaderSet $headerSet, $type) - { - foreach ($headerSet->getAll($type) as $headers) { - $headers->setNameAddresses($this->_filterNameAddresses($headers->getNameAddresses())); - } - } - - /** - * Filtered list of addresses => name pairs. - * - * @param array $recipients - * - * @return array - */ - private function _filterNameAddresses(array $recipients) - { - $filtered = array(); - - foreach ($recipients as $address => $name) { - if ($this->_isWhitelisted($address)) { - $filtered[$address] = $name; - } - } - - return $filtered; - } - - /** - * Matches address against whitelist of regular expressions. - * - * @param $recipient - * - * @return bool - */ - protected function _isWhitelisted($recipient) - { - if (in_array($recipient, (array) $this->_recipient)) { - return true; - } - - foreach ($this->_whitelist as $pattern) { - if (preg_match($pattern, $recipient)) { - return true; - } - } - - return false; - } - - /** - * Invoked immediately after the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt) - { - $this->_restoreMessage($evt->getMessage()); - } - - private function _restoreMessage(Swift_Mime_Message $message) - { - // restore original headers - $headers = $message->getHeaders(); - - if ($headers->has('X-Swift-To')) { - $message->setTo($headers->get('X-Swift-To')->getNameAddresses()); - $headers->removeAll('X-Swift-To'); - } else { - $message->setTo(null); - } - - if ($headers->has('X-Swift-Cc')) { - $message->setCc($headers->get('X-Swift-Cc')->getNameAddresses()); - $headers->removeAll('X-Swift-Cc'); - } - - if ($headers->has('X-Swift-Bcc')) { - $message->setBcc($headers->get('X-Swift-Bcc')->getNameAddresses()); - $headers->removeAll('X-Swift-Bcc'); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/Reporter.php b/lib/SwiftMailer/classes/Swift/Plugins/Reporter.php deleted file mode 100644 index 0f21b7d..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/Reporter.php +++ /dev/null @@ -1,32 +0,0 @@ -_reporter = $reporter; - } - - /** - * Not used. - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) - { - } - - /** - * Invoked immediately after the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt) - { - $message = $evt->getMessage(); - $failures = array_flip($evt->getFailedRecipients()); - foreach ((array) $message->getTo() as $address => $null) { - $this->_reporter->notify($message, $address, array_key_exists($address, $failures) ? Swift_Plugins_Reporter::RESULT_FAIL : Swift_Plugins_Reporter::RESULT_PASS); - } - foreach ((array) $message->getCc() as $address => $null) { - $this->_reporter->notify($message, $address, array_key_exists($address, $failures) ? Swift_Plugins_Reporter::RESULT_FAIL : Swift_Plugins_Reporter::RESULT_PASS); - } - foreach ((array) $message->getBcc() as $address => $null) { - $this->_reporter->notify($message, $address, array_key_exists($address, $failures) ? Swift_Plugins_Reporter::RESULT_FAIL : Swift_Plugins_Reporter::RESULT_PASS); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/Reporters/HitReporter.php b/lib/SwiftMailer/classes/Swift/Plugins/Reporters/HitReporter.php deleted file mode 100644 index cad9d16..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/Reporters/HitReporter.php +++ /dev/null @@ -1,59 +0,0 @@ -_failures_cache[$address])) { - $this->_failures[] = $address; - $this->_failures_cache[$address] = true; - } - } - - /** - * Get an array of addresses for which delivery failed. - * - * @return array - */ - public function getFailedRecipients() - { - return $this->_failures; - } - - /** - * Clear the buffer (empty the list). - */ - public function clear() - { - $this->_failures = $this->_failures_cache = array(); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/Reporters/HtmlReporter.php b/lib/SwiftMailer/classes/Swift/Plugins/Reporters/HtmlReporter.php deleted file mode 100644 index c625935..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/Reporters/HtmlReporter.php +++ /dev/null @@ -1,39 +0,0 @@ -'.PHP_EOL; - echo 'PASS '.$address.PHP_EOL; - echo ''.PHP_EOL; - flush(); - } else { - echo '
'.PHP_EOL; - echo 'FAIL '.$address.PHP_EOL; - echo '
'.PHP_EOL; - flush(); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/Sleeper.php b/lib/SwiftMailer/classes/Swift/Plugins/Sleeper.php deleted file mode 100644 index 595c0f6..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/Sleeper.php +++ /dev/null @@ -1,24 +0,0 @@ -_rate = $rate; - $this->_mode = $mode; - $this->_sleeper = $sleeper; - $this->_timer = $timer; - } - - /** - * Invoked immediately before the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) - { - $time = $this->getTimestamp(); - if (!isset($this->_start)) { - $this->_start = $time; - } - $duration = $time - $this->_start; - - switch ($this->_mode) { - case self::BYTES_PER_MINUTE : - $sleep = $this->_throttleBytesPerMinute($duration); - break; - case self::MESSAGES_PER_SECOND : - $sleep = $this->_throttleMessagesPerSecond($duration); - break; - case self::MESSAGES_PER_MINUTE : - $sleep = $this->_throttleMessagesPerMinute($duration); - break; - default : - $sleep = 0; - break; - } - - if ($sleep > 0) { - $this->sleep($sleep); - } - } - - /** - * Invoked when a Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt) - { - parent::sendPerformed($evt); - ++$this->_messages; - } - - /** - * Sleep for $seconds. - * - * @param int $seconds - */ - public function sleep($seconds) - { - if (isset($this->_sleeper)) { - $this->_sleeper->sleep($seconds); - } else { - sleep($seconds); - } - } - - /** - * Get the current UNIX timestamp. - * - * @return int - */ - public function getTimestamp() - { - if (isset($this->_timer)) { - return $this->_timer->getTimestamp(); - } - - return time(); - } - - /** - * Get a number of seconds to sleep for. - * - * @param int $timePassed - * - * @return int - */ - private function _throttleBytesPerMinute($timePassed) - { - $expectedDuration = $this->getBytesOut() / ($this->_rate / 60); - - return (int) ceil($expectedDuration - $timePassed); - } - - /** - * Get a number of seconds to sleep for. - * - * @param int $timePassed - * - * @return int - */ - private function _throttleMessagesPerSecond($timePassed) - { - $expectedDuration = $this->_messages / ($this->_rate); - - return (int) ceil($expectedDuration - $timePassed); - } - - /** - * Get a number of seconds to sleep for. - * - * @param int $timePassed - * - * @return int - */ - private function _throttleMessagesPerMinute($timePassed) - { - $expectedDuration = $this->_messages / ($this->_rate / 60); - - return (int) ceil($expectedDuration - $timePassed); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Plugins/Timer.php b/lib/SwiftMailer/classes/Swift/Plugins/Timer.php deleted file mode 100644 index 9c8deb3..0000000 --- a/lib/SwiftMailer/classes/Swift/Plugins/Timer.php +++ /dev/null @@ -1,24 +0,0 @@ -register('properties.charset')->asValue($charset); - - return $this; - } - - /** - * Set the directory where temporary files can be saved. - * - * @param string $dir - * - * @return Swift_Preferences - */ - public function setTempDir($dir) - { - Swift_DependencyContainer::getInstance() - ->register('tempdir')->asValue($dir); - - return $this; - } - - /** - * Set the type of cache to use (i.e. "disk" or "array"). - * - * @param string $type - * - * @return Swift_Preferences - */ - public function setCacheType($type) - { - Swift_DependencyContainer::getInstance() - ->register('cache')->asAliasOf(sprintf('cache.%s', $type)); - - return $this; - } - - /** - * Set the QuotedPrintable dot escaper preference. - * - * @param bool $dotEscape - * - * @return Swift_Preferences - */ - public function setQPDotEscape($dotEscape) - { - $dotEscape = !empty($dotEscape); - Swift_DependencyContainer::getInstance() - ->register('mime.qpcontentencoder') - ->asNewInstanceOf('Swift_Mime_ContentEncoder_QpContentEncoder') - ->withDependencies(array('mime.charstream', 'mime.bytecanonicalizer')) - ->addConstructorValue($dotEscape); - - return $this; - } -} diff --git a/lib/SwiftMailer/classes/Swift/ReplacementFilterFactory.php b/lib/SwiftMailer/classes/Swift/ReplacementFilterFactory.php deleted file mode 100644 index 2897474..0000000 --- a/lib/SwiftMailer/classes/Swift/ReplacementFilterFactory.php +++ /dev/null @@ -1,27 +0,0 @@ -createDependenciesFor('transport.sendmail') - ); - - $this->setCommand($command); - } - - /** - * Create a new SendmailTransport instance. - * - * @param string $command - * - * @return Swift_SendmailTransport - */ - public static function newInstance($command = '/usr/sbin/sendmail -bs') - { - return new self($command); - } -} diff --git a/lib/SwiftMailer/classes/Swift/SignedMessage.php b/lib/SwiftMailer/classes/Swift/SignedMessage.php deleted file mode 100644 index 2e7a872..0000000 --- a/lib/SwiftMailer/classes/Swift/SignedMessage.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * @deprecated - */ -class Swift_SignedMessage extends Swift_Message -{ -} diff --git a/lib/SwiftMailer/classes/Swift/Signer.php b/lib/SwiftMailer/classes/Swift/Signer.php deleted file mode 100644 index 2d8176d..0000000 --- a/lib/SwiftMailer/classes/Swift/Signer.php +++ /dev/null @@ -1,20 +0,0 @@ - - */ -interface Swift_Signer -{ - public function reset(); -} diff --git a/lib/SwiftMailer/classes/Swift/Signers/BodySigner.php b/lib/SwiftMailer/classes/Swift/Signers/BodySigner.php deleted file mode 100644 index 9ffcef3..0000000 --- a/lib/SwiftMailer/classes/Swift/Signers/BodySigner.php +++ /dev/null @@ -1,33 +0,0 @@ - - */ -interface Swift_Signers_BodySigner extends Swift_Signer -{ - /** - * Change the Swift_Signed_Message to apply the singing. - * - * @param Swift_Message $message - * - * @return Swift_Signers_BodySigner - */ - public function signMessage(Swift_Message $message); - - /** - * Return the list of header a signer might tamper. - * - * @return array - */ - public function getAlteredHeaders(); -} diff --git a/lib/SwiftMailer/classes/Swift/Signers/DKIMSigner.php b/lib/SwiftMailer/classes/Swift/Signers/DKIMSigner.php deleted file mode 100644 index b7a6209..0000000 --- a/lib/SwiftMailer/classes/Swift/Signers/DKIMSigner.php +++ /dev/null @@ -1,698 +0,0 @@ - - */ -class Swift_Signers_DKIMSigner implements Swift_Signers_HeaderSigner -{ - /** - * PrivateKey. - * - * @var string - */ - protected $_privateKey; - - /** - * DomainName. - * - * @var string - */ - protected $_domainName; - - /** - * Selector. - * - * @var string - */ - protected $_selector; - - /** - * Hash algorithm used. - * - * @var string - */ - protected $_hashAlgorithm = 'rsa-sha1'; - - /** - * Body canon method. - * - * @var string - */ - protected $_bodyCanon = 'simple'; - - /** - * Header canon method. - * - * @var string - */ - protected $_headerCanon = 'simple'; - - /** - * Headers not being signed. - * - * @var array - */ - protected $_ignoredHeaders = array('return-path' => true); - - /** - * Signer identity. - * - * @var string - */ - protected $_signerIdentity; - - /** - * BodyLength. - * - * @var int - */ - protected $_bodyLen = 0; - - /** - * Maximum signedLen. - * - * @var int - */ - protected $_maxLen = PHP_INT_MAX; - - /** - * Embbed bodyLen in signature. - * - * @var bool - */ - protected $_showLen = false; - - /** - * When the signature has been applied (true means time()), false means not embedded. - * - * @var mixed - */ - protected $_signatureTimestamp = true; - - /** - * When will the signature expires false means not embedded, if sigTimestamp is auto - * Expiration is relative, otherwhise it's absolute. - * - * @var int - */ - protected $_signatureExpiration = false; - - /** - * Must we embed signed headers? - * - * @var bool - */ - protected $_debugHeaders = false; - - // work variables - /** - * Headers used to generate hash. - * - * @var array - */ - protected $_signedHeaders = array(); - - /** - * If debugHeaders is set store debugDatas here. - * - * @var string - */ - private $_debugHeadersData = ''; - - /** - * Stores the bodyHash. - * - * @var string - */ - private $_bodyHash = ''; - - /** - * Stores the signature header. - * - * @var Swift_Mime_Headers_ParameterizedHeader - */ - protected $_dkimHeader; - - private $_bodyHashHandler; - - private $_headerHash; - - private $_headerCanonData = ''; - - private $_bodyCanonEmptyCounter = 0; - - private $_bodyCanonIgnoreStart = 2; - - private $_bodyCanonSpace = false; - - private $_bodyCanonLastChar = null; - - private $_bodyCanonLine = ''; - - private $_bound = array(); - - /** - * Constructor. - * - * @param string $privateKey - * @param string $domainName - * @param string $selector - */ - public function __construct($privateKey, $domainName, $selector) - { - $this->_privateKey = $privateKey; - $this->_domainName = $domainName; - $this->_signerIdentity = '@'.$domainName; - $this->_selector = $selector; - } - - /** - * Instanciate DKIMSigner. - * - * @param string $privateKey - * @param string $domainName - * @param string $selector - * - * @return Swift_Signers_DKIMSigner - */ - public static function newInstance($privateKey, $domainName, $selector) - { - return new static($privateKey, $domainName, $selector); - } - - /** - * Reset the Signer. - * - * @see Swift_Signer::reset() - */ - public function reset() - { - $this->_headerHash = null; - $this->_signedHeaders = array(); - $this->_bodyHash = null; - $this->_bodyHashHandler = null; - $this->_bodyCanonIgnoreStart = 2; - $this->_bodyCanonEmptyCounter = 0; - $this->_bodyCanonLastChar = null; - $this->_bodyCanonSpace = false; - } - - /** - * Writes $bytes to the end of the stream. - * - * Writing may not happen immediately if the stream chooses to buffer. If - * you want to write these bytes with immediate effect, call {@link commit()} - * after calling write(). - * - * This method returns the sequence ID of the write (i.e. 1 for first, 2 for - * second, etc etc). - * - * @param string $bytes - * - * @throws Swift_IoException - * - * @return int - */ - public function write($bytes) - { - $this->_canonicalizeBody($bytes); - foreach ($this->_bound as $is) { - $is->write($bytes); - } - } - - /** - * For any bytes that are currently buffered inside the stream, force them - * off the buffer. - * - * @throws Swift_IoException - */ - public function commit() - { - // Nothing to do - return; - } - - /** - * Attach $is to this stream. - * The stream acts as an observer, receiving all data that is written. - * All {@link write()} and {@link flushBuffers()} operations will be mirrored. - * - * @param Swift_InputByteStream $is - */ - public function bind(Swift_InputByteStream $is) - { - // Don't have to mirror anything - $this->_bound[] = $is; - - return; - } - - /** - * Remove an already bound stream. - * If $is is not bound, no errors will be raised. - * If the stream currently has any buffered data it will be written to $is - * before unbinding occurs. - * - * @param Swift_InputByteStream $is - */ - public function unbind(Swift_InputByteStream $is) - { - // Don't have to mirror anything - foreach ($this->_bound as $k => $stream) { - if ($stream === $is) { - unset($this->_bound[$k]); - - return; - } - } - - return; - } - - /** - * Flush the contents of the stream (empty it) and set the internal pointer - * to the beginning. - * - * @throws Swift_IoException - */ - public function flushBuffers() - { - $this->reset(); - } - - /** - * Set hash_algorithm, must be one of rsa-sha256 | rsa-sha1 defaults to rsa-sha256. - * - * @param string $hash - * - * @return Swift_Signers_DKIMSigner - */ - public function setHashAlgorithm($hash) - { - // Unable to sign with rsa-sha256 - if ($hash == 'rsa-sha1') { - $this->_hashAlgorithm = 'rsa-sha1'; - } else { - $this->_hashAlgorithm = 'rsa-sha256'; - } - - return $this; - } - - /** - * Set the body canonicalization algorithm. - * - * @param string $canon - * - * @return Swift_Signers_DKIMSigner - */ - public function setBodyCanon($canon) - { - if ($canon == 'relaxed') { - $this->_bodyCanon = 'relaxed'; - } else { - $this->_bodyCanon = 'simple'; - } - - return $this; - } - - /** - * Set the header canonicalization algorithm. - * - * @param string $canon - * - * @return Swift_Signers_DKIMSigner - */ - public function setHeaderCanon($canon) - { - if ($canon == 'relaxed') { - $this->_headerCanon = 'relaxed'; - } else { - $this->_headerCanon = 'simple'; - } - - return $this; - } - - /** - * Set the signer identity. - * - * @param string $identity - * - * @return Swift_Signers_DKIMSigner - */ - public function setSignerIdentity($identity) - { - $this->_signerIdentity = $identity; - - return $this; - } - - /** - * Set the length of the body to sign. - * - * @param mixed $len (bool or int) - * - * @return Swift_Signers_DKIMSigner - */ - public function setBodySignedLen($len) - { - if ($len === true) { - $this->_showLen = true; - $this->_maxLen = PHP_INT_MAX; - } elseif ($len === false) { - $this->_showLen = false; - $this->_maxLen = PHP_INT_MAX; - } else { - $this->_showLen = true; - $this->_maxLen = (int) $len; - } - - return $this; - } - - /** - * Set the signature timestamp. - * - * @param int $time A timestamp - * - * @return Swift_Signers_DKIMSigner - */ - public function setSignatureTimestamp($time) - { - $this->_signatureTimestamp = $time; - - return $this; - } - - /** - * Set the signature expiration timestamp. - * - * @param int $time A timestamp - * - * @return Swift_Signers_DKIMSigner - */ - public function setSignatureExpiration($time) - { - $this->_signatureExpiration = $time; - - return $this; - } - - /** - * Enable / disable the DebugHeaders. - * - * @param bool $debug - * - * @return Swift_Signers_DKIMSigner - */ - public function setDebugHeaders($debug) - { - $this->_debugHeaders = (bool) $debug; - - return $this; - } - - /** - * Start Body. - */ - public function startBody() - { - // Init - switch ($this->_hashAlgorithm) { - case 'rsa-sha256' : - $this->_bodyHashHandler = hash_init('sha256'); - break; - case 'rsa-sha1' : - $this->_bodyHashHandler = hash_init('sha1'); - break; - } - $this->_bodyCanonLine = ''; - } - - /** - * End Body. - */ - public function endBody() - { - $this->_endOfBody(); - } - - /** - * Returns the list of Headers Tampered by this plugin. - * - * @return array - */ - public function getAlteredHeaders() - { - if ($this->_debugHeaders) { - return array('DKIM-Signature', 'X-DebugHash'); - } else { - return array('DKIM-Signature'); - } - } - - /** - * Adds an ignored Header. - * - * @param string $header_name - * - * @return Swift_Signers_DKIMSigner - */ - public function ignoreHeader($header_name) - { - $this->_ignoredHeaders[strtolower($header_name)] = true; - - return $this; - } - - /** - * Set the headers to sign. - * - * @param Swift_Mime_HeaderSet $headers - * - * @return Swift_Signers_DKIMSigner - */ - public function setHeaders(Swift_Mime_HeaderSet $headers) - { - $this->_headerCanonData = ''; - // Loop through Headers - $listHeaders = $headers->listAll(); - foreach ($listHeaders as $hName) { - // Check if we need to ignore Header - if (!isset($this->_ignoredHeaders[strtolower($hName)])) { - if ($headers->has($hName)) { - $tmp = $headers->getAll($hName); - foreach ($tmp as $header) { - if ($header->getFieldBody() != '') { - $this->_addHeader($header->toString()); - $this->_signedHeaders[] = $header->getFieldName(); - } - } - } - } - } - - return $this; - } - - /** - * Add the signature to the given Headers. - * - * @param Swift_Mime_HeaderSet $headers - * - * @return Swift_Signers_DKIMSigner - */ - public function addSignature(Swift_Mime_HeaderSet $headers) - { - // Prepare the DKIM-Signature - $params = array('v' => '1', 'a' => $this->_hashAlgorithm, 'bh' => base64_encode($this->_bodyHash), 'd' => $this->_domainName, 'h' => implode(': ', $this->_signedHeaders), 'i' => $this->_signerIdentity, 's' => $this->_selector); - if ($this->_bodyCanon != 'simple') { - $params['c'] = $this->_headerCanon.'/'.$this->_bodyCanon; - } elseif ($this->_headerCanon != 'simple') { - $params['c'] = $this->_headerCanon; - } - if ($this->_showLen) { - $params['l'] = $this->_bodyLen; - } - if ($this->_signatureTimestamp === true) { - $params['t'] = time(); - if ($this->_signatureExpiration !== false) { - $params['x'] = $params['t'] + $this->_signatureExpiration; - } - } else { - if ($this->_signatureTimestamp !== false) { - $params['t'] = $this->_signatureTimestamp; - } - if ($this->_signatureExpiration !== false) { - $params['x'] = $this->_signatureExpiration; - } - } - if ($this->_debugHeaders) { - $params['z'] = implode('|', $this->_debugHeadersData); - } - $string = ''; - foreach ($params as $k => $v) { - $string .= $k.'='.$v.'; '; - } - $string = trim($string); - $headers->addTextHeader('DKIM-Signature', $string); - // Add the last DKIM-Signature - $tmp = $headers->getAll('DKIM-Signature'); - $this->_dkimHeader = end($tmp); - $this->_addHeader(trim($this->_dkimHeader->toString())."\r\n b=", true); - $this->_endOfHeaders(); - if ($this->_debugHeaders) { - $headers->addTextHeader('X-DebugHash', base64_encode($this->_headerHash)); - } - $this->_dkimHeader->setValue($string.' b='.trim(chunk_split(base64_encode($this->_getEncryptedHash()), 73, ' '))); - - return $this; - } - - /* Private helpers */ - - protected function _addHeader($header, $is_sig = false) - { - switch ($this->_headerCanon) { - case 'relaxed' : - // Prepare Header and cascade - $exploded = explode(':', $header, 2); - $name = strtolower(trim($exploded[0])); - $value = str_replace("\r\n", '', $exploded[1]); - $value = preg_replace("/[ \t][ \t]+/", ' ', $value); - $header = $name.':'.trim($value).($is_sig ? '' : "\r\n"); - case 'simple' : - // Nothing to do - } - $this->_addToHeaderHash($header); - } - - /** - * @deprecated This method is currently useless in this class but it must be - * kept for BC reasons due to its "protected" scope. This method - * might be overriden by custom client code. - */ - protected function _endOfHeaders() - { - } - - protected function _canonicalizeBody($string) - { - $len = strlen($string); - $canon = ''; - $method = ($this->_bodyCanon == 'relaxed'); - for ($i = 0; $i < $len; ++$i) { - if ($this->_bodyCanonIgnoreStart > 0) { - --$this->_bodyCanonIgnoreStart; - continue; - } - switch ($string[$i]) { - case "\r" : - $this->_bodyCanonLastChar = "\r"; - break; - case "\n" : - if ($this->_bodyCanonLastChar == "\r") { - if ($method) { - $this->_bodyCanonSpace = false; - } - if ($this->_bodyCanonLine == '') { - ++$this->_bodyCanonEmptyCounter; - } else { - $this->_bodyCanonLine = ''; - $canon .= "\r\n"; - } - } else { - // Wooops Error - // todo handle it but should never happen - } - break; - case ' ' : - case "\t" : - if ($method) { - $this->_bodyCanonSpace = true; - break; - } - default : - if ($this->_bodyCanonEmptyCounter > 0) { - $canon .= str_repeat("\r\n", $this->_bodyCanonEmptyCounter); - $this->_bodyCanonEmptyCounter = 0; - } - if ($this->_bodyCanonSpace) { - $this->_bodyCanonLine .= ' '; - $canon .= ' '; - $this->_bodyCanonSpace = false; - } - $this->_bodyCanonLine .= $string[$i]; - $canon .= $string[$i]; - } - } - $this->_addToBodyHash($canon); - } - - protected function _endOfBody() - { - // Add trailing Line return if last line is non empty - if (strlen($this->_bodyCanonLine) > 0) { - $this->_addToBodyHash("\r\n"); - } - $this->_bodyHash = hash_final($this->_bodyHashHandler, true); - } - - private function _addToBodyHash($string) - { - $len = strlen($string); - if ($len > ($new_len = ($this->_maxLen - $this->_bodyLen))) { - $string = substr($string, 0, $new_len); - $len = $new_len; - } - hash_update($this->_bodyHashHandler, $string); - $this->_bodyLen += $len; - } - - private function _addToHeaderHash($header) - { - if ($this->_debugHeaders) { - $this->_debugHeadersData[] = trim($header); - } - $this->_headerCanonData .= $header; - } - - /** - * @throws Swift_SwiftException - * - * @return string - */ - private function _getEncryptedHash() - { - $signature = ''; - switch ($this->_hashAlgorithm) { - case 'rsa-sha1': - $algorithm = OPENSSL_ALGO_SHA1; - break; - case 'rsa-sha256': - $algorithm = OPENSSL_ALGO_SHA256; - break; - } - $pkeyId = openssl_get_privatekey($this->_privateKey); - if (!$pkeyId) { - throw new Swift_SwiftException('Unable to load DKIM Private Key ['.openssl_error_string().']'); - } - if (openssl_sign($this->_headerCanonData, $signature, $pkeyId, $algorithm)) { - return $signature; - } - throw new Swift_SwiftException('Unable to sign DKIM Hash ['.openssl_error_string().']'); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Signers/DomainKeySigner.php b/lib/SwiftMailer/classes/Swift/Signers/DomainKeySigner.php deleted file mode 100644 index 43210f0..0000000 --- a/lib/SwiftMailer/classes/Swift/Signers/DomainKeySigner.php +++ /dev/null @@ -1,525 +0,0 @@ - - */ -class Swift_Signers_DomainKeySigner implements Swift_Signers_HeaderSigner -{ - /** - * PrivateKey. - * - * @var string - */ - protected $_privateKey; - - /** - * DomainName. - * - * @var string - */ - protected $_domainName; - - /** - * Selector. - * - * @var string - */ - protected $_selector; - - /** - * Hash algorithm used. - * - * @var string - */ - protected $_hashAlgorithm = 'rsa-sha1'; - - /** - * Canonisation method. - * - * @var string - */ - protected $_canon = 'simple'; - - /** - * Headers not being signed. - * - * @var array - */ - protected $_ignoredHeaders = array(); - - /** - * Signer identity. - * - * @var string - */ - protected $_signerIdentity; - - /** - * Must we embed signed headers? - * - * @var bool - */ - protected $_debugHeaders = false; - - // work variables - /** - * Headers used to generate hash. - * - * @var array - */ - private $_signedHeaders = array(); - - /** - * Stores the signature header. - * - * @var Swift_Mime_Headers_ParameterizedHeader - */ - protected $_domainKeyHeader; - - /** - * Hash Handler. - * - * @var resource|null - */ - private $_hashHandler; - - private $_hash; - - private $_canonData = ''; - - private $_bodyCanonEmptyCounter = 0; - - private $_bodyCanonIgnoreStart = 2; - - private $_bodyCanonSpace = false; - - private $_bodyCanonLastChar = null; - - private $_bodyCanonLine = ''; - - private $_bound = array(); - - /** - * Constructor. - * - * @param string $privateKey - * @param string $domainName - * @param string $selector - */ - public function __construct($privateKey, $domainName, $selector) - { - $this->_privateKey = $privateKey; - $this->_domainName = $domainName; - $this->_signerIdentity = '@'.$domainName; - $this->_selector = $selector; - } - - /** - * Instanciate DomainKeySigner. - * - * @param string $privateKey - * @param string $domainName - * @param string $selector - * - * @return Swift_Signers_DomainKeySigner - */ - public static function newInstance($privateKey, $domainName, $selector) - { - return new static($privateKey, $domainName, $selector); - } - - /** - * Resets internal states. - * - * @return Swift_Signers_DomainKeySigner - */ - public function reset() - { - $this->_hash = null; - $this->_hashHandler = null; - $this->_bodyCanonIgnoreStart = 2; - $this->_bodyCanonEmptyCounter = 0; - $this->_bodyCanonLastChar = null; - $this->_bodyCanonSpace = false; - - return $this; - } - - /** - * Writes $bytes to the end of the stream. - * - * Writing may not happen immediately if the stream chooses to buffer. If - * you want to write these bytes with immediate effect, call {@link commit()} - * after calling write(). - * - * This method returns the sequence ID of the write (i.e. 1 for first, 2 for - * second, etc etc). - * - * @param string $bytes - * - * @throws Swift_IoException - * - * @return int - * @return Swift_Signers_DomainKeySigner - */ - public function write($bytes) - { - $this->_canonicalizeBody($bytes); - foreach ($this->_bound as $is) { - $is->write($bytes); - } - - return $this; - } - - /** - * For any bytes that are currently buffered inside the stream, force them - * off the buffer. - * - * @throws Swift_IoException - * - * @return Swift_Signers_DomainKeySigner - */ - public function commit() - { - // Nothing to do - return $this; - } - - /** - * Attach $is to this stream. - * The stream acts as an observer, receiving all data that is written. - * All {@link write()} and {@link flushBuffers()} operations will be mirrored. - * - * @param Swift_InputByteStream $is - * - * @return Swift_Signers_DomainKeySigner - */ - public function bind(Swift_InputByteStream $is) - { - // Don't have to mirror anything - $this->_bound[] = $is; - - return $this; - } - - /** - * Remove an already bound stream. - * If $is is not bound, no errors will be raised. - * If the stream currently has any buffered data it will be written to $is - * before unbinding occurs. - * - * @param Swift_InputByteStream $is - * - * @return Swift_Signers_DomainKeySigner - */ - public function unbind(Swift_InputByteStream $is) - { - // Don't have to mirror anything - foreach ($this->_bound as $k => $stream) { - if ($stream === $is) { - unset($this->_bound[$k]); - - return; - } - } - - return $this; - } - - /** - * Flush the contents of the stream (empty it) and set the internal pointer - * to the beginning. - * - * @throws Swift_IoException - * - * @return Swift_Signers_DomainKeySigner - */ - public function flushBuffers() - { - $this->reset(); - - return $this; - } - - /** - * Set hash_algorithm, must be one of rsa-sha256 | rsa-sha1 defaults to rsa-sha256. - * - * @param string $hash - * - * @return Swift_Signers_DomainKeySigner - */ - public function setHashAlgorithm($hash) - { - $this->_hashAlgorithm = 'rsa-sha1'; - - return $this; - } - - /** - * Set the canonicalization algorithm. - * - * @param string $canon simple | nofws defaults to simple - * - * @return Swift_Signers_DomainKeySigner - */ - public function setCanon($canon) - { - if ($canon == 'nofws') { - $this->_canon = 'nofws'; - } else { - $this->_canon = 'simple'; - } - - return $this; - } - - /** - * Set the signer identity. - * - * @param string $identity - * - * @return Swift_Signers_DomainKeySigner - */ - public function setSignerIdentity($identity) - { - $this->_signerIdentity = $identity; - - return $this; - } - - /** - * Enable / disable the DebugHeaders. - * - * @param bool $debug - * - * @return Swift_Signers_DomainKeySigner - */ - public function setDebugHeaders($debug) - { - $this->_debugHeaders = (bool) $debug; - - return $this; - } - - /** - * Start Body. - */ - public function startBody() - { - } - - /** - * End Body. - */ - public function endBody() - { - $this->_endOfBody(); - } - - /** - * Returns the list of Headers Tampered by this plugin. - * - * @return array - */ - public function getAlteredHeaders() - { - if ($this->_debugHeaders) { - return array('DomainKey-Signature', 'X-DebugHash'); - } - - return array('DomainKey-Signature'); - } - - /** - * Adds an ignored Header. - * - * @param string $header_name - * - * @return Swift_Signers_DomainKeySigner - */ - public function ignoreHeader($header_name) - { - $this->_ignoredHeaders[strtolower($header_name)] = true; - - return $this; - } - - /** - * Set the headers to sign. - * - * @param Swift_Mime_HeaderSet $headers - * - * @return Swift_Signers_DomainKeySigner - */ - public function setHeaders(Swift_Mime_HeaderSet $headers) - { - $this->_startHash(); - $this->_canonData = ''; - // Loop through Headers - $listHeaders = $headers->listAll(); - foreach ($listHeaders as $hName) { - // Check if we need to ignore Header - if (!isset($this->_ignoredHeaders[strtolower($hName)])) { - if ($headers->has($hName)) { - $tmp = $headers->getAll($hName); - foreach ($tmp as $header) { - if ($header->getFieldBody() != '') { - $this->_addHeader($header->toString()); - $this->_signedHeaders[] = $header->getFieldName(); - } - } - } - } - } - $this->_endOfHeaders(); - - return $this; - } - - /** - * Add the signature to the given Headers. - * - * @param Swift_Mime_HeaderSet $headers - * - * @return Swift_Signers_DomainKeySigner - */ - public function addSignature(Swift_Mime_HeaderSet $headers) - { - // Prepare the DomainKey-Signature Header - $params = array('a' => $this->_hashAlgorithm, 'b' => chunk_split(base64_encode($this->_getEncryptedHash()), 73, ' '), 'c' => $this->_canon, 'd' => $this->_domainName, 'h' => implode(': ', $this->_signedHeaders), 'q' => 'dns', 's' => $this->_selector); - $string = ''; - foreach ($params as $k => $v) { - $string .= $k.'='.$v.'; '; - } - $string = trim($string); - $headers->addTextHeader('DomainKey-Signature', $string); - - return $this; - } - - /* Private helpers */ - - protected function _addHeader($header) - { - switch ($this->_canon) { - case 'nofws' : - // Prepare Header and cascade - $exploded = explode(':', $header, 2); - $name = strtolower(trim($exploded[0])); - $value = str_replace("\r\n", '', $exploded[1]); - $value = preg_replace("/[ \t][ \t]+/", ' ', $value); - $header = $name.':'.trim($value)."\r\n"; - case 'simple' : - // Nothing to do - } - $this->_addToHash($header); - } - - protected function _endOfHeaders() - { - $this->_bodyCanonEmptyCounter = 1; - } - - protected function _canonicalizeBody($string) - { - $len = strlen($string); - $canon = ''; - $nofws = ($this->_canon == 'nofws'); - for ($i = 0; $i < $len; ++$i) { - if ($this->_bodyCanonIgnoreStart > 0) { - --$this->_bodyCanonIgnoreStart; - continue; - } - switch ($string[$i]) { - case "\r" : - $this->_bodyCanonLastChar = "\r"; - break; - case "\n" : - if ($this->_bodyCanonLastChar == "\r") { - if ($nofws) { - $this->_bodyCanonSpace = false; - } - if ($this->_bodyCanonLine == '') { - ++$this->_bodyCanonEmptyCounter; - } else { - $this->_bodyCanonLine = ''; - $canon .= "\r\n"; - } - } else { - // Wooops Error - throw new Swift_SwiftException('Invalid new line sequence in mail found \n without preceding \r'); - } - break; - case ' ' : - case "\t" : - case "\x09": //HTAB - if ($nofws) { - $this->_bodyCanonSpace = true; - break; - } - default : - if ($this->_bodyCanonEmptyCounter > 0) { - $canon .= str_repeat("\r\n", $this->_bodyCanonEmptyCounter); - $this->_bodyCanonEmptyCounter = 0; - } - $this->_bodyCanonLine .= $string[$i]; - $canon .= $string[$i]; - } - } - $this->_addToHash($canon); - } - - protected function _endOfBody() - { - if (strlen($this->_bodyCanonLine) > 0) { - $this->_addToHash("\r\n"); - } - $this->_hash = hash_final($this->_hashHandler, true); - } - - private function _addToHash($string) - { - $this->_canonData .= $string; - hash_update($this->_hashHandler, $string); - } - - private function _startHash() - { - // Init - switch ($this->_hashAlgorithm) { - case 'rsa-sha1' : - $this->_hashHandler = hash_init('sha1'); - break; - } - $this->_bodyCanonLine = ''; - } - - /** - * @throws Swift_SwiftException - * - * @return string - */ - private function _getEncryptedHash() - { - $signature = ''; - $pkeyId = openssl_get_privatekey($this->_privateKey); - if (!$pkeyId) { - throw new Swift_SwiftException('Unable to load DomainKey Private Key ['.openssl_error_string().']'); - } - if (openssl_sign($this->_canonData, $signature, $pkeyId, OPENSSL_ALGO_SHA1)) { - return $signature; - } - throw new Swift_SwiftException('Unable to sign DomainKey Hash ['.openssl_error_string().']'); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Signers/HeaderSigner.php b/lib/SwiftMailer/classes/Swift/Signers/HeaderSigner.php deleted file mode 100644 index c75cb08..0000000 --- a/lib/SwiftMailer/classes/Swift/Signers/HeaderSigner.php +++ /dev/null @@ -1,65 +0,0 @@ - - */ -interface Swift_Signers_HeaderSigner extends Swift_Signer, Swift_InputByteStream -{ - /** - * Exclude an header from the signed headers. - * - * @param string $header_name - * - * @return Swift_Signers_HeaderSigner - */ - public function ignoreHeader($header_name); - - /** - * Prepare the Signer to get a new Body. - * - * @return Swift_Signers_HeaderSigner - */ - public function startBody(); - - /** - * Give the signal that the body has finished streaming. - * - * @return Swift_Signers_HeaderSigner - */ - public function endBody(); - - /** - * Give the headers already given. - * - * @param Swift_Mime_SimpleHeaderSet $headers - * - * @return Swift_Signers_HeaderSigner - */ - public function setHeaders(Swift_Mime_HeaderSet $headers); - - /** - * Add the header(s) to the headerSet. - * - * @param Swift_Mime_HeaderSet $headers - * - * @return Swift_Signers_HeaderSigner - */ - public function addSignature(Swift_Mime_HeaderSet $headers); - - /** - * Return the list of header a signer might tamper. - * - * @return array - */ - public function getAlteredHeaders(); -} diff --git a/lib/SwiftMailer/classes/Swift/Signers/OpenDKIMSigner.php b/lib/SwiftMailer/classes/Swift/Signers/OpenDKIMSigner.php deleted file mode 100644 index 3a35ad5..0000000 --- a/lib/SwiftMailer/classes/Swift/Signers/OpenDKIMSigner.php +++ /dev/null @@ -1,190 +0,0 @@ - - */ -class Swift_Signers_OpenDKIMSigner extends Swift_Signers_DKIMSigner -{ - private $_peclLoaded = false; - - private $_dkimHandler = null; - - private $dropFirstLF = true; - - const CANON_RELAXED = 1; - const CANON_SIMPLE = 2; - const SIG_RSA_SHA1 = 3; - const SIG_RSA_SHA256 = 4; - - public function __construct($privateKey, $domainName, $selector) - { - if (!extension_loaded('opendkim')) { - throw new Swift_SwiftException('php-opendkim extension not found'); - } - - $this->_peclLoaded = true; - - parent::__construct($privateKey, $domainName, $selector); - } - - public static function newInstance($privateKey, $domainName, $selector) - { - return new static($privateKey, $domainName, $selector); - } - - public function addSignature(Swift_Mime_HeaderSet $headers) - { - $header = new Swift_Mime_Headers_OpenDKIMHeader('DKIM-Signature'); - $headerVal = $this->_dkimHandler->getSignatureHeader(); - if (!$headerVal) { - throw new Swift_SwiftException('OpenDKIM Error: '.$this->_dkimHandler->getError()); - } - $header->setValue($headerVal); - $headers->set($header); - - return $this; - } - - public function setHeaders(Swift_Mime_HeaderSet $headers) - { - $bodyLen = $this->_bodyLen; - if (is_bool($bodyLen)) { - $bodyLen = -1; - } - $hash = $this->_hashAlgorithm == 'rsa-sha1' ? OpenDKIMSign::ALG_RSASHA1 : OpenDKIMSign::ALG_RSASHA256; - $bodyCanon = $this->_bodyCanon == 'simple' ? OpenDKIMSign::CANON_SIMPLE : OpenDKIMSign::CANON_RELAXED; - $headerCanon = $this->_headerCanon == 'simple' ? OpenDKIMSign::CANON_SIMPLE : OpenDKIMSign::CANON_RELAXED; - $this->_dkimHandler = new OpenDKIMSign($this->_privateKey, $this->_selector, $this->_domainName, $headerCanon, $bodyCanon, $hash, $bodyLen); - // Hardcode signature Margin for now - $this->_dkimHandler->setMargin(78); - - if (!is_numeric($this->_signatureTimestamp)) { - OpenDKIM::setOption(OpenDKIM::OPTS_FIXEDTIME, time()); - } else { - if (!OpenDKIM::setOption(OpenDKIM::OPTS_FIXEDTIME, $this->_signatureTimestamp)) { - throw new Swift_SwiftException('Unable to force signature timestamp ['.openssl_error_string().']'); - } - } - if (isset($this->_signerIdentity)) { - $this->_dkimHandler->setSigner($this->_signerIdentity); - } - $listHeaders = $headers->listAll(); - foreach ($listHeaders as $hName) { - // Check if we need to ignore Header - if (!isset($this->_ignoredHeaders[strtolower($hName)])) { - $tmp = $headers->getAll($hName); - if ($headers->has($hName)) { - foreach ($tmp as $header) { - if ($header->getFieldBody() != '') { - $htosign = $header->toString(); - $this->_dkimHandler->header($htosign); - $this->_signedHeaders[] = $header->getFieldName(); - } - } - } - } - } - - return $this; - } - - public function startBody() - { - if (!$this->_peclLoaded) { - return parent::startBody(); - } - $this->dropFirstLF = true; - $this->_dkimHandler->eoh(); - - return $this; - } - - public function endBody() - { - if (!$this->_peclLoaded) { - return parent::endBody(); - } - $this->_dkimHandler->eom(); - - return $this; - } - - public function reset() - { - $this->_dkimHandler = null; - parent::reset(); - - return $this; - } - - /** - * Set the signature timestamp. - * - * @param int $time - * - * @return Swift_Signers_DKIMSigner - */ - public function setSignatureTimestamp($time) - { - $this->_signatureTimestamp = $time; - - return $this; - } - - /** - * Set the signature expiration timestamp. - * - * @param int $time - * - * @return Swift_Signers_DKIMSigner - */ - public function setSignatureExpiration($time) - { - $this->_signatureExpiration = $time; - - return $this; - } - - /** - * Enable / disable the DebugHeaders. - * - * @param bool $debug - * - * @return Swift_Signers_DKIMSigner - */ - public function setDebugHeaders($debug) - { - $this->_debugHeaders = (bool) $debug; - - return $this; - } - - // Protected - - protected function _canonicalizeBody($string) - { - if (!$this->_peclLoaded) { - return parent::_canonicalizeBody($string); - } - if (false && $this->dropFirstLF === true) { - if ($string[0] == "\r" && $string[1] == "\n") { - $string = substr($string, 2); - } - } - $this->dropFirstLF = false; - if (strlen($string)) { - $this->_dkimHandler->body($string); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Signers/SMimeSigner.php b/lib/SwiftMailer/classes/Swift/Signers/SMimeSigner.php deleted file mode 100644 index b267099..0000000 --- a/lib/SwiftMailer/classes/Swift/Signers/SMimeSigner.php +++ /dev/null @@ -1,436 +0,0 @@ - - */ -class Swift_Signers_SMimeSigner implements Swift_Signers_BodySigner -{ - protected $signCertificate; - protected $signPrivateKey; - protected $encryptCert; - protected $signThenEncrypt = true; - protected $signLevel; - protected $encryptLevel; - protected $signOptions; - protected $encryptOptions; - protected $encryptCipher; - protected $extraCerts = null; - - /** - * @var Swift_StreamFilters_StringReplacementFilterFactory - */ - protected $replacementFactory; - - /** - * @var Swift_Mime_HeaderFactory - */ - protected $headerFactory; - - /** - * Constructor. - * - * @param string|null $signCertificate - * @param string|null $signPrivateKey - * @param string|null $encryptCertificate - */ - public function __construct($signCertificate = null, $signPrivateKey = null, $encryptCertificate = null) - { - if (null !== $signPrivateKey) { - $this->setSignCertificate($signCertificate, $signPrivateKey); - } - - if (null !== $encryptCertificate) { - $this->setEncryptCertificate($encryptCertificate); - } - - $this->replacementFactory = Swift_DependencyContainer::getInstance() - ->lookup('transport.replacementfactory'); - - $this->signOptions = PKCS7_DETACHED; - - // Supported since php5.4 - if (defined('OPENSSL_CIPHER_AES_128_CBC')) { - $this->encryptCipher = OPENSSL_CIPHER_AES_128_CBC; - } else { - $this->encryptCipher = OPENSSL_CIPHER_RC2_128; - } - } - - /** - * Returns an new Swift_Signers_SMimeSigner instance. - * - * @param string $certificate - * @param string $privateKey - * - * @return Swift_Signers_SMimeSigner - */ - public static function newInstance($certificate = null, $privateKey = null) - { - return new self($certificate, $privateKey); - } - - /** - * Set the certificate location to use for signing. - * - * @link http://www.php.net/manual/en/openssl.pkcs7.flags.php - * - * @param string $certificate - * @param string|array $privateKey If the key needs an passphrase use array('file-location', 'passphrase') instead - * @param int $signOptions Bitwise operator options for openssl_pkcs7_sign() - * @param string $extraCerts A file containing intermediate certificates needed by the signing certificate - * - * @return Swift_Signers_SMimeSigner - */ - public function setSignCertificate($certificate, $privateKey = null, $signOptions = PKCS7_DETACHED, $extraCerts = null) - { - $this->signCertificate = 'file://'.str_replace('\\', '/', realpath($certificate)); - - if (null !== $privateKey) { - if (is_array($privateKey)) { - $this->signPrivateKey = $privateKey; - $this->signPrivateKey[0] = 'file://'.str_replace('\\', '/', realpath($privateKey[0])); - } else { - $this->signPrivateKey = 'file://'.str_replace('\\', '/', realpath($privateKey)); - } - } - - $this->signOptions = $signOptions; - if (null !== $extraCerts) { - $this->extraCerts = str_replace('\\', '/', realpath($extraCerts)); - } - - return $this; - } - - /** - * Set the certificate location to use for encryption. - * - * @link http://www.php.net/manual/en/openssl.pkcs7.flags.php - * @link http://nl3.php.net/manual/en/openssl.ciphers.php - * - * @param string|array $recipientCerts Either an single X.509 certificate, or an assoc array of X.509 certificates. - * @param int $cipher - * - * @return Swift_Signers_SMimeSigner - */ - public function setEncryptCertificate($recipientCerts, $cipher = null) - { - if (is_array($recipientCerts)) { - $this->encryptCert = array(); - - foreach ($recipientCerts as $cert) { - $this->encryptCert[] = 'file://'.str_replace('\\', '/', realpath($cert)); - } - } else { - $this->encryptCert = 'file://'.str_replace('\\', '/', realpath($recipientCerts)); - } - - if (null !== $cipher) { - $this->encryptCipher = $cipher; - } - - return $this; - } - - /** - * @return string - */ - public function getSignCertificate() - { - return $this->signCertificate; - } - - /** - * @return string - */ - public function getSignPrivateKey() - { - return $this->signPrivateKey; - } - - /** - * Set perform signing before encryption. - * - * The default is to first sign the message and then encrypt. - * But some older mail clients, namely Microsoft Outlook 2000 will work when the message first encrypted. - * As this goes against the official specs, its recommended to only use 'encryption -> signing' when specifically targeting these 'broken' clients. - * - * @param bool $signThenEncrypt - * - * @return Swift_Signers_SMimeSigner - */ - public function setSignThenEncrypt($signThenEncrypt = true) - { - $this->signThenEncrypt = $signThenEncrypt; - - return $this; - } - - /** - * @return bool - */ - public function isSignThenEncrypt() - { - return $this->signThenEncrypt; - } - - /** - * Resets internal states. - * - * @return Swift_Signers_SMimeSigner - */ - public function reset() - { - return $this; - } - - /** - * Change the Swift_Message to apply the signing. - * - * @param Swift_Message $message - * - * @return Swift_Signers_SMimeSigner - */ - public function signMessage(Swift_Message $message) - { - if (null === $this->signCertificate && null === $this->encryptCert) { - return $this; - } - - // Store the message using ByteStream to a file{1} - // Remove all Children - // Sign file{1}, parse the new MIME headers and set them on the primary MimeEntity - // Set the singed-body as the new body (without boundary) - - $messageStream = new Swift_ByteStream_TemporaryFileByteStream(); - $this->toSMimeByteStream($messageStream, $message); - $message->setEncoder(Swift_DependencyContainer::getInstance()->lookup('mime.rawcontentencoder')); - - $message->setChildren(array()); - $this->streamToMime($messageStream, $message); - } - - /** - * Return the list of header a signer might tamper. - * - * @return array - */ - public function getAlteredHeaders() - { - return array('Content-Type', 'Content-Transfer-Encoding', 'Content-Disposition'); - } - - /** - * @param Swift_InputByteStream $inputStream - * @param Swift_Message $mimeEntity - */ - protected function toSMimeByteStream(Swift_InputByteStream $inputStream, Swift_Message $message) - { - $mimeEntity = $this->createMessage($message); - $messageStream = new Swift_ByteStream_TemporaryFileByteStream(); - - $mimeEntity->toByteStream($messageStream); - $messageStream->commit(); - - if (null !== $this->signCertificate && null !== $this->encryptCert) { - $temporaryStream = new Swift_ByteStream_TemporaryFileByteStream(); - - if ($this->signThenEncrypt) { - $this->messageStreamToSignedByteStream($messageStream, $temporaryStream); - $this->messageStreamToEncryptedByteStream($temporaryStream, $inputStream); - } else { - $this->messageStreamToEncryptedByteStream($messageStream, $temporaryStream); - $this->messageStreamToSignedByteStream($temporaryStream, $inputStream); - } - } elseif ($this->signCertificate !== null) { - $this->messageStreamToSignedByteStream($messageStream, $inputStream); - } else { - $this->messageStreamToEncryptedByteStream($messageStream, $inputStream); - } - } - - /** - * @param Swift_Message $message - * - * @return Swift_Message - */ - protected function createMessage(Swift_Message $message) - { - $mimeEntity = new Swift_Message('', $message->getBody(), $message->getContentType(), $message->getCharset()); - $mimeEntity->setChildren($message->getChildren()); - - $messageHeaders = $mimeEntity->getHeaders(); - $messageHeaders->remove('Message-ID'); - $messageHeaders->remove('Date'); - $messageHeaders->remove('Subject'); - $messageHeaders->remove('MIME-Version'); - $messageHeaders->remove('To'); - $messageHeaders->remove('From'); - - return $mimeEntity; - } - - /** - * @param Swift_FileStream $outputStream - * @param Swift_InputByteStream $inputStream - * - * @throws Swift_IoException - */ - protected function messageStreamToSignedByteStream(Swift_FileStream $outputStream, Swift_InputByteStream $inputStream) - { - $signedMessageStream = new Swift_ByteStream_TemporaryFileByteStream(); - - $args = array($outputStream->getPath(), $signedMessageStream->getPath(), $this->signCertificate, $this->signPrivateKey, array(), $this->signOptions); - if (null !== $this->extraCerts) { - $args[] = $this->extraCerts; - } - - if (!call_user_func_array('openssl_pkcs7_sign', $args)) { - throw new Swift_IoException(sprintf('Failed to sign S/Mime message. Error: "%s".', openssl_error_string())); - } - - $this->copyFromOpenSSLOutput($signedMessageStream, $inputStream); - } - - /** - * @param Swift_FileStream $outputStream - * @param Swift_InputByteStream $is - * - * @throws Swift_IoException - */ - protected function messageStreamToEncryptedByteStream(Swift_FileStream $outputStream, Swift_InputByteStream $is) - { - $encryptedMessageStream = new Swift_ByteStream_TemporaryFileByteStream(); - - if (!openssl_pkcs7_encrypt($outputStream->getPath(), $encryptedMessageStream->getPath(), $this->encryptCert, array(), 0, $this->encryptCipher)) { - throw new Swift_IoException(sprintf('Failed to encrypt S/Mime message. Error: "%s".', openssl_error_string())); - } - - $this->copyFromOpenSSLOutput($encryptedMessageStream, $is); - } - - /** - * @param Swift_OutputByteStream $fromStream - * @param Swift_InputByteStream $toStream - */ - protected function copyFromOpenSSLOutput(Swift_OutputByteStream $fromStream, Swift_InputByteStream $toStream) - { - $bufferLength = 4096; - $filteredStream = new Swift_ByteStream_TemporaryFileByteStream(); - $filteredStream->addFilter($this->replacementFactory->createFilter("\r\n", "\n"), 'CRLF to LF'); - $filteredStream->addFilter($this->replacementFactory->createFilter("\n", "\r\n"), 'LF to CRLF'); - - while (false !== ($buffer = $fromStream->read($bufferLength))) { - $filteredStream->write($buffer); - } - - $filteredStream->flushBuffers(); - - while (false !== ($buffer = $filteredStream->read($bufferLength))) { - $toStream->write($buffer); - } - - $toStream->commit(); - } - - /** - * Merges an OutputByteStream to Swift_Message. - * - * @param Swift_OutputByteStream $fromStream - * @param Swift_Message $message - */ - protected function streamToMime(Swift_OutputByteStream $fromStream, Swift_Message $message) - { - $bufferLength = 78; - $headerData = ''; - - $fromStream->setReadPointer(0); - - while (($buffer = $fromStream->read($bufferLength)) !== false) { - $headerData .= $buffer; - - if (false !== strpos($buffer, "\r\n\r\n")) { - break; - } - } - - $headersPosEnd = strpos($headerData, "\r\n\r\n"); - $headerData = trim($headerData); - $headerData = substr($headerData, 0, $headersPosEnd); - $headerLines = explode("\r\n", $headerData); - unset($headerData); - - $headers = array(); - $currentHeaderName = ''; - - foreach ($headerLines as $headerLine) { - // Line separated - if (ctype_space($headerLines[0]) || false === strpos($headerLine, ':')) { - $headers[$currentHeaderName] .= ' '.trim($headerLine); - continue; - } - - $header = explode(':', $headerLine, 2); - $currentHeaderName = strtolower($header[0]); - $headers[$currentHeaderName] = trim($header[1]); - } - - $messageStream = new Swift_ByteStream_TemporaryFileByteStream(); - $messageStream->addFilter($this->replacementFactory->createFilter("\r\n", "\n"), 'CRLF to LF'); - $messageStream->addFilter($this->replacementFactory->createFilter("\n", "\r\n"), 'LF to CRLF'); - - $messageHeaders = $message->getHeaders(); - - // No need to check for 'application/pkcs7-mime', as this is always base64 - if ('multipart/signed;' === substr($headers['content-type'], 0, 17)) { - if (!preg_match('/boundary=("[^"]+"|(?:[^\s]+|$))/is', $headers['content-type'], $contentTypeData)) { - throw new Swift_SwiftException('Failed to find Boundary parameter'); - } - - $boundary = trim($contentTypeData['1'], '"'); - - // Skip the header and CRLF CRLF - $fromStream->setReadPointer($headersPosEnd + 4); - - while (false !== ($buffer = $fromStream->read($bufferLength))) { - $messageStream->write($buffer); - } - - $messageStream->commit(); - - $messageHeaders->remove('Content-Transfer-Encoding'); - $message->setContentType($headers['content-type']); - $message->setBoundary($boundary); - $message->setBody($messageStream); - } else { - $fromStream->setReadPointer($headersPosEnd + 4); - - if (null === $this->headerFactory) { - $this->headerFactory = Swift_DependencyContainer::getInstance()->lookup('mime.headerfactory'); - } - - $message->setContentType($headers['content-type']); - $messageHeaders->set($this->headerFactory->createTextHeader('Content-Transfer-Encoding', $headers['content-transfer-encoding'])); - $messageHeaders->set($this->headerFactory->createTextHeader('Content-Disposition', $headers['content-disposition'])); - - while (false !== ($buffer = $fromStream->read($bufferLength))) { - $messageStream->write($buffer); - } - - $messageStream->commit(); - $message->setBody($messageStream); - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/SmtpTransport.php b/lib/SwiftMailer/classes/Swift/SmtpTransport.php deleted file mode 100644 index 6251611..0000000 --- a/lib/SwiftMailer/classes/Swift/SmtpTransport.php +++ /dev/null @@ -1,58 +0,0 @@ -createDependenciesFor('transport.smtp') - ); - - $this->setHost($host); - $this->setPort($port); - $this->setEncryption($security); - } - - /** - * Create a new SmtpTransport instance. - * - * @param string $host - * @param int $port - * @param string $security - * - * @return Swift_SmtpTransport - */ - public static function newInstance($host = 'localhost', $port = 25, $security = null) - { - return new self($host, $port, $security); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Spool.php b/lib/SwiftMailer/classes/Swift/Spool.php deleted file mode 100644 index c16ab4b..0000000 --- a/lib/SwiftMailer/classes/Swift/Spool.php +++ /dev/null @@ -1,53 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Interface for spools. - * - * @author Fabien Potencier - */ -interface Swift_Spool -{ - /** - * Starts this Spool mechanism. - */ - public function start(); - - /** - * Stops this Spool mechanism. - */ - public function stop(); - - /** - * Tests if this Spool mechanism has started. - * - * @return bool - */ - public function isStarted(); - - /** - * Queues a message. - * - * @param Swift_Mime_Message $message The message to store - * - * @return bool Whether the operation has succeeded - */ - public function queueMessage(Swift_Mime_Message $message); - - /** - * Sends messages using the given transport instance. - * - * @param Swift_Transport $transport A transport instance - * @param string[] $failedRecipients An array of failures by-reference - * - * @return int The number of sent emails - */ - public function flushQueue(Swift_Transport $transport, &$failedRecipients = null); -} diff --git a/lib/SwiftMailer/classes/Swift/SpoolTransport.php b/lib/SwiftMailer/classes/Swift/SpoolTransport.php deleted file mode 100644 index cf9bf78..0000000 --- a/lib/SwiftMailer/classes/Swift/SpoolTransport.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Stores Messages in a queue. - * - * @author Fabien Potencier - */ -class Swift_SpoolTransport extends Swift_Transport_SpoolTransport -{ - /** - * Create a new SpoolTransport. - * - * @param Swift_Spool $spool - */ - public function __construct(Swift_Spool $spool) - { - $arguments = Swift_DependencyContainer::getInstance() - ->createDependenciesFor('transport.spool'); - - $arguments[] = $spool; - - call_user_func_array( - array($this, 'Swift_Transport_SpoolTransport::__construct'), - $arguments - ); - } - - /** - * Create a new SpoolTransport instance. - * - * @param Swift_Spool $spool - * - * @return Swift_SpoolTransport - */ - public static function newInstance(Swift_Spool $spool) - { - return new self($spool); - } -} diff --git a/lib/SwiftMailer/classes/Swift/StreamFilter.php b/lib/SwiftMailer/classes/Swift/StreamFilter.php deleted file mode 100644 index 362be2e..0000000 --- a/lib/SwiftMailer/classes/Swift/StreamFilter.php +++ /dev/null @@ -1,35 +0,0 @@ -_search = $search; - $this->_index = array(); - $this->_tree = array(); - $this->_replace = array(); - $this->_repSize = array(); - - $tree = null; - $i = null; - $last_size = $size = 0; - foreach ($search as $i => $search_element) { - if ($tree !== null) { - $tree[-1] = min(count($replace) - 1, $i - 1); - $tree[-2] = $last_size; - } - $tree = &$this->_tree; - if (is_array($search_element)) { - foreach ($search_element as $k => $char) { - $this->_index[$char] = true; - if (!isset($tree[$char])) { - $tree[$char] = array(); - } - $tree = &$tree[$char]; - } - $last_size = $k + 1; - $size = max($size, $last_size); - } else { - $last_size = 1; - if (!isset($tree[$search_element])) { - $tree[$search_element] = array(); - } - $tree = &$tree[$search_element]; - $size = max($last_size, $size); - $this->_index[$search_element] = true; - } - } - if ($i !== null) { - $tree[-1] = min(count($replace) - 1, $i); - $tree[-2] = $last_size; - $this->_treeMaxLen = $size; - } - foreach ($replace as $rep) { - if (!is_array($rep)) { - $rep = array($rep); - } - $this->_replace[] = $rep; - } - for ($i = count($this->_replace) - 1; $i >= 0; --$i) { - $this->_replace[$i] = $rep = $this->filter($this->_replace[$i], $i); - $this->_repSize[$i] = count($rep); - } - } - - /** - * Returns true if based on the buffer passed more bytes should be buffered. - * - * @param array $buffer - * - * @return bool - */ - public function shouldBuffer($buffer) - { - $endOfBuffer = end($buffer); - - return isset($this->_index[$endOfBuffer]); - } - - /** - * Perform the actual replacements on $buffer and return the result. - * - * @param array $buffer - * @param int $_minReplaces - * - * @return array - */ - public function filter($buffer, $_minReplaces = -1) - { - if ($this->_treeMaxLen == 0) { - return $buffer; - } - - $newBuffer = array(); - $buf_size = count($buffer); - $last_size = 0; - for ($i = 0; $i < $buf_size; ++$i) { - $search_pos = $this->_tree; - $last_found = PHP_INT_MAX; - // We try to find if the next byte is part of a search pattern - for ($j = 0; $j <= $this->_treeMaxLen; ++$j) { - // We have a new byte for a search pattern - if (isset($buffer [$p = $i + $j]) && isset($search_pos[$buffer[$p]])) { - $search_pos = $search_pos[$buffer[$p]]; - // We have a complete pattern, save, in case we don't find a better match later - if (isset($search_pos[-1]) && $search_pos[-1] < $last_found - && $search_pos[-1] > $_minReplaces) { - $last_found = $search_pos[-1]; - $last_size = $search_pos[-2]; - } - } - // We got a complete pattern - elseif ($last_found !== PHP_INT_MAX) { - // Adding replacement datas to output buffer - $rep_size = $this->_repSize[$last_found]; - for ($j = 0; $j < $rep_size; ++$j) { - $newBuffer[] = $this->_replace[$last_found][$j]; - } - // We Move cursor forward - $i += $last_size - 1; - // Edge Case, last position in buffer - if ($i >= $buf_size) { - $newBuffer[] = $buffer[$i]; - } - - // We start the next loop - continue 2; - } else { - // this byte is not in a pattern and we haven't found another pattern - break; - } - } - // Normal byte, move it to output buffer - $newBuffer[] = $buffer[$i]; - } - - return $newBuffer; - } -} diff --git a/lib/SwiftMailer/classes/Swift/StreamFilters/StringReplacementFilter.php b/lib/SwiftMailer/classes/Swift/StreamFilters/StringReplacementFilter.php deleted file mode 100644 index d0db8b9..0000000 --- a/lib/SwiftMailer/classes/Swift/StreamFilters/StringReplacementFilter.php +++ /dev/null @@ -1,66 +0,0 @@ -_search = $search; - $this->_replace = $replace; - } - - /** - * Returns true if based on the buffer passed more bytes should be buffered. - * - * @param string $buffer - * - * @return bool - */ - public function shouldBuffer($buffer) - { - $endOfBuffer = substr($buffer, -1); - foreach ((array) $this->_search as $needle) { - if (false !== strpos($needle, $endOfBuffer)) { - return true; - } - } - - return false; - } - - /** - * Perform the actual replacements on $buffer and return the result. - * - * @param string $buffer - * - * @return string - */ - public function filter($buffer) - { - return str_replace($this->_search, $this->_replace, $buffer); - } -} diff --git a/lib/SwiftMailer/classes/Swift/StreamFilters/StringReplacementFilterFactory.php b/lib/SwiftMailer/classes/Swift/StreamFilters/StringReplacementFilterFactory.php deleted file mode 100644 index e98240b..0000000 --- a/lib/SwiftMailer/classes/Swift/StreamFilters/StringReplacementFilterFactory.php +++ /dev/null @@ -1,45 +0,0 @@ -_filters[$search][$replace])) { - if (!isset($this->_filters[$search])) { - $this->_filters[$search] = array(); - } - - if (!isset($this->_filters[$search][$replace])) { - $this->_filters[$search][$replace] = array(); - } - - $this->_filters[$search][$replace] = new Swift_StreamFilters_StringReplacementFilter($search, $replace); - } - - return $this->_filters[$search][$replace]; - } -} diff --git a/lib/SwiftMailer/classes/Swift/SwiftException.php b/lib/SwiftMailer/classes/Swift/SwiftException.php deleted file mode 100644 index db3d310..0000000 --- a/lib/SwiftMailer/classes/Swift/SwiftException.php +++ /dev/null @@ -1,29 +0,0 @@ -_eventDispatcher = $dispatcher; - $this->_buffer = $buf; - $this->_lookupHostname(); - } - - /** - * Set the name of the local domain which Swift will identify itself as. - * - * This should be a fully-qualified domain name and should be truly the domain - * you're using. - * - * If your server doesn't have a domain name, use the IP in square - * brackets (i.e. [127.0.0.1]). - * - * @param string $domain - * - * @return Swift_Transport_AbstractSmtpTransport - */ - public function setLocalDomain($domain) - { - $this->_domain = $domain; - - return $this; - } - - /** - * Get the name of the domain Swift will identify as. - * - * @return string - */ - public function getLocalDomain() - { - return $this->_domain; - } - - /** - * Sets the source IP. - * - * @param string $source - */ - public function setSourceIp($source) - { - $this->_sourceIp = $source; - } - - /** - * Returns the IP used to connect to the destination. - * - * @return string - */ - public function getSourceIp() - { - return $this->_sourceIp; - } - - /** - * Start the SMTP connection. - */ - public function start() - { - if (!$this->_started) { - if ($evt = $this->_eventDispatcher->createTransportChangeEvent($this)) { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeTransportStarted'); - if ($evt->bubbleCancelled()) { - return; - } - } - - try { - $this->_buffer->initialize($this->_getBufferParams()); - } catch (Swift_TransportException $e) { - $this->_throwException($e); - } - $this->_readGreeting(); - $this->_doHeloCommand(); - - if ($evt) { - $this->_eventDispatcher->dispatchEvent($evt, 'transportStarted'); - } - - $this->_started = true; - } - } - - /** - * Test if an SMTP connection has been established. - * - * @return bool - */ - public function isStarted() - { - return $this->_started; - } - - /** - * Send the given Message. - * - * Recipient/sender data will be retrieved from the Message API. - * The return value is the number of recipients who were accepted for delivery. - * - * @param Swift_Mime_Message $message - * @param string[] $failedRecipients An array of failures by-reference - * - * @return int - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - $sent = 0; - $failedRecipients = (array) $failedRecipients; - - if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); - if ($evt->bubbleCancelled()) { - return 0; - } - } - - if (!$reversePath = $this->_getReversePath($message)) { - $this->_throwException(new Swift_TransportException( - 'Cannot send message without a sender address' - ) - ); - } - - $to = (array) $message->getTo(); - $cc = (array) $message->getCc(); - $tos = array_merge($to, $cc); - $bcc = (array) $message->getBcc(); - - $message->setBcc(array()); - - try { - $sent += $this->_sendTo($message, $reversePath, $tos, $failedRecipients); - $sent += $this->_sendBcc($message, $reversePath, $bcc, $failedRecipients); - } catch (Exception $e) { - $message->setBcc($bcc); - throw $e; - } - - $message->setBcc($bcc); - - if ($evt) { - if ($sent == count($to) + count($cc) + count($bcc)) { - $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); - } elseif ($sent > 0) { - $evt->setResult(Swift_Events_SendEvent::RESULT_TENTATIVE); - } else { - $evt->setResult(Swift_Events_SendEvent::RESULT_FAILED); - } - $evt->setFailedRecipients($failedRecipients); - $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); - } - - $message->generateId(); //Make sure a new Message ID is used - - return $sent; - } - - /** - * Stop the SMTP connection. - */ - public function stop() - { - if ($this->_started) { - if ($evt = $this->_eventDispatcher->createTransportChangeEvent($this)) { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeTransportStopped'); - if ($evt->bubbleCancelled()) { - return; - } - } - - try { - $this->executeCommand("QUIT\r\n", array(221)); - } catch (Swift_TransportException $e) { - } - - try { - $this->_buffer->terminate(); - - if ($evt) { - $this->_eventDispatcher->dispatchEvent($evt, 'transportStopped'); - } - } catch (Swift_TransportException $e) { - $this->_throwException($e); - } - } - $this->_started = false; - } - - /** - * Register a plugin. - * - * @param Swift_Events_EventListener $plugin - */ - public function registerPlugin(Swift_Events_EventListener $plugin) - { - $this->_eventDispatcher->bindEventListener($plugin); - } - - /** - * Reset the current mail transaction. - */ - public function reset() - { - $this->executeCommand("RSET\r\n", array(250)); - } - - /** - * Get the IoBuffer where read/writes are occurring. - * - * @return Swift_Transport_IoBuffer - */ - public function getBuffer() - { - return $this->_buffer; - } - - /** - * Run a command against the buffer, expecting the given response codes. - * - * If no response codes are given, the response will not be validated. - * If codes are given, an exception will be thrown on an invalid response. - * - * @param string $command - * @param int[] $codes - * @param string[] $failures An array of failures by-reference - * - * @return string - */ - public function executeCommand($command, $codes = array(), &$failures = null) - { - $failures = (array) $failures; - $seq = $this->_buffer->write($command); - $response = $this->_getFullResponse($seq); - if ($evt = $this->_eventDispatcher->createCommandEvent($this, $command, $codes)) { - $this->_eventDispatcher->dispatchEvent($evt, 'commandSent'); - } - $this->_assertResponseCode($response, $codes); - - return $response; - } - - /** Read the opening SMTP greeting */ - protected function _readGreeting() - { - $this->_assertResponseCode($this->_getFullResponse(0), array(220)); - } - - /** Send the HELO welcome */ - protected function _doHeloCommand() - { - $this->executeCommand( - sprintf("HELO %s\r\n", $this->_domain), array(250) - ); - } - - /** Send the MAIL FROM command */ - protected function _doMailFromCommand($address) - { - $this->executeCommand( - sprintf("MAIL FROM:<%s>\r\n", $address), array(250) - ); - } - - /** Send the RCPT TO command */ - protected function _doRcptToCommand($address) - { - $this->executeCommand( - sprintf("RCPT TO:<%s>\r\n", $address), array(250, 251, 252) - ); - } - - /** Send the DATA command */ - protected function _doDataCommand() - { - $this->executeCommand("DATA\r\n", array(354)); - } - - /** Stream the contents of the message over the buffer */ - protected function _streamMessage(Swift_Mime_Message $message) - { - $this->_buffer->setWriteTranslations(array("\r\n." => "\r\n..")); - try { - $message->toByteStream($this->_buffer); - $this->_buffer->flushBuffers(); - } catch (Swift_TransportException $e) { - $this->_throwException($e); - } - $this->_buffer->setWriteTranslations(array()); - $this->executeCommand("\r\n.\r\n", array(250)); - } - - /** Determine the best-use reverse path for this message */ - protected function _getReversePath(Swift_Mime_Message $message) - { - $return = $message->getReturnPath(); - $sender = $message->getSender(); - $from = $message->getFrom(); - $path = null; - if (!empty($return)) { - $path = $return; - } elseif (!empty($sender)) { - // Don't use array_keys - reset($sender); // Reset Pointer to first pos - $path = key($sender); // Get key - } elseif (!empty($from)) { - reset($from); // Reset Pointer to first pos - $path = key($from); // Get key - } - - return $path; - } - - /** Throw a TransportException, first sending it to any listeners */ - protected function _throwException(Swift_TransportException $e) - { - if ($evt = $this->_eventDispatcher->createTransportExceptionEvent($this, $e)) { - $this->_eventDispatcher->dispatchEvent($evt, 'exceptionThrown'); - if (!$evt->bubbleCancelled()) { - throw $e; - } - } else { - throw $e; - } - } - - /** Throws an Exception if a response code is incorrect */ - protected function _assertResponseCode($response, $wanted) - { - list($code) = sscanf($response, '%3d'); - $valid = (empty($wanted) || in_array($code, $wanted)); - - if ($evt = $this->_eventDispatcher->createResponseEvent($this, $response, - $valid)) { - $this->_eventDispatcher->dispatchEvent($evt, 'responseReceived'); - } - - if (!$valid) { - $this->_throwException( - new Swift_TransportException( - 'Expected response code '.implode('/', $wanted).' but got code '. - '"'.$code.'", with message "'.$response.'"', - $code) - ); - } - } - - /** Get an entire multi-line response using its sequence number */ - protected function _getFullResponse($seq) - { - $response = ''; - try { - do { - $line = $this->_buffer->readLine($seq); - $response .= $line; - } while (null !== $line && false !== $line && ' ' != $line[3]); - } catch (Swift_TransportException $e) { - $this->_throwException($e); - } catch (Swift_IoException $e) { - $this->_throwException( - new Swift_TransportException( - $e->getMessage()) - ); - } - - return $response; - } - - /** Send an email to the given recipients from the given reverse path */ - private function _doMailTransaction($message, $reversePath, array $recipients, array &$failedRecipients) - { - $sent = 0; - $this->_doMailFromCommand($reversePath); - foreach ($recipients as $forwardPath) { - try { - $this->_doRcptToCommand($forwardPath); - ++$sent; - } catch (Swift_TransportException $e) { - $failedRecipients[] = $forwardPath; - } - } - - if ($sent != 0) { - $this->_doDataCommand(); - $this->_streamMessage($message); - } else { - $this->reset(); - } - - return $sent; - } - - /** Send a message to the given To: recipients */ - private function _sendTo(Swift_Mime_Message $message, $reversePath, array $to, array &$failedRecipients) - { - if (empty($to)) { - return 0; - } - - return $this->_doMailTransaction($message, $reversePath, array_keys($to), - $failedRecipients); - } - - /** Send a message to all Bcc: recipients */ - private function _sendBcc(Swift_Mime_Message $message, $reversePath, array $bcc, array &$failedRecipients) - { - $sent = 0; - foreach ($bcc as $forwardPath => $name) { - $message->setBcc(array($forwardPath => $name)); - $sent += $this->_doMailTransaction( - $message, $reversePath, array($forwardPath), $failedRecipients - ); - } - - return $sent; - } - - /** Try to determine the hostname of the server this is run on */ - private function _lookupHostname() - { - if (!empty($_SERVER['SERVER_NAME']) && $this->_isFqdn($_SERVER['SERVER_NAME'])) { - $this->_domain = $_SERVER['SERVER_NAME']; - } elseif (!empty($_SERVER['SERVER_ADDR'])) { - // Set the address literal tag (See RFC 5321, section: 4.1.3) - if (false === strpos($_SERVER['SERVER_ADDR'], ':')) { - $prefix = ''; // IPv4 addresses are not tagged. - } else { - $prefix = 'IPv6:'; // Adding prefix in case of IPv6. - } - - $this->_domain = sprintf('[%s%s]', $prefix, $_SERVER['SERVER_ADDR']); - } - } - - /** Determine is the $hostname is a fully-qualified name */ - private function _isFqdn($hostname) - { - // We could do a really thorough check, but there's really no point - if (false !== $dotPos = strpos($hostname, '.')) { - return ($dotPos > 0) && ($dotPos != strlen($hostname) - 1); - } - - return false; - } - - /** - * Destructor. - */ - public function __destruct() - { - $this->stop(); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php b/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php deleted file mode 100644 index 53f721d..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php +++ /dev/null @@ -1,81 +0,0 @@ -executeCommand("AUTH CRAM-MD5\r\n", array(334)); - $challenge = base64_decode(substr($challenge, 4)); - $message = base64_encode( - $username.' '.$this->_getResponse($password, $challenge) - ); - $agent->executeCommand(sprintf("%s\r\n", $message), array(235)); - - return true; - } catch (Swift_TransportException $e) { - $agent->executeCommand("RSET\r\n", array(250)); - - return false; - } - } - - /** - * Generate a CRAM-MD5 response from a server challenge. - * - * @param string $secret - * @param string $challenge - * - * @return string - */ - private function _getResponse($secret, $challenge) - { - if (strlen($secret) > 64) { - $secret = pack('H32', md5($secret)); - } - - if (strlen($secret) < 64) { - $secret = str_pad($secret, 64, chr(0)); - } - - $k_ipad = substr($secret, 0, 64) ^ str_repeat(chr(0x36), 64); - $k_opad = substr($secret, 0, 64) ^ str_repeat(chr(0x5C), 64); - - $inner = pack('H32', md5($k_ipad.$challenge)); - $digest = md5($k_opad.$inner); - - return $digest; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php b/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php deleted file mode 100644 index 6ab6e33..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php +++ /dev/null @@ -1,51 +0,0 @@ -executeCommand("AUTH LOGIN\r\n", array(334)); - $agent->executeCommand(sprintf("%s\r\n", base64_encode($username)), array(334)); - $agent->executeCommand(sprintf("%s\r\n", base64_encode($password)), array(235)); - - return true; - } catch (Swift_TransportException $e) { - $agent->executeCommand("RSET\r\n", array(250)); - - return false; - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php b/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php deleted file mode 100644 index eb04acf..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php +++ /dev/null @@ -1,720 +0,0 @@ - - */ -class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Esmtp_Authenticator -{ - const NTLMSIG = "NTLMSSP\x00"; - const DESCONST = 'KGS!@#$%'; - - /** - * Get the name of the AUTH mechanism this Authenticator handles. - * - * @return string - */ - public function getAuthKeyword() - { - return 'NTLM'; - } - - /** - * Try to authenticate the user with $username and $password. - * - * @param Swift_Transport_SmtpAgent $agent - * @param string $username - * @param string $password - * - * @return bool - */ - public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password) - { - if (!function_exists('openssl_random_pseudo_bytes') || !function_exists('openssl_encrypt')) { - throw new LogicException('The OpenSSL extension must be enabled to use the NTLM authenticator.'); - } - - if (!function_exists('bcmul')) { - throw new LogicException('The BCMath functions must be enabled to use the NTLM authenticator.'); - } - - try { - // execute AUTH command and filter out the code at the beginning - // AUTH NTLM xxxx - $response = base64_decode(substr(trim($this->sendMessage1($agent)), 4)); - - // extra parameters for our unit cases - $timestamp = func_num_args() > 3 ? func_get_arg(3) : $this->getCorrectTimestamp(bcmul(microtime(true), '1000')); - $client = func_num_args() > 4 ? func_get_arg(4) : $this->getRandomBytes(8); - - // Message 3 response - $this->sendMessage3($response, $username, $password, $timestamp, $client, $agent); - - return true; - } catch (Swift_TransportException $e) { - $agent->executeCommand("RSET\r\n", array(250)); - - return false; - } - } - - protected function si2bin($si, $bits = 32) - { - $bin = null; - if ($si >= -pow(2, $bits - 1) && ($si <= pow(2, $bits - 1))) { - // positive or zero - if ($si >= 0) { - $bin = base_convert($si, 10, 2); - // pad to $bits bit - $bin_length = strlen($bin); - if ($bin_length < $bits) { - $bin = str_repeat('0', $bits - $bin_length).$bin; - } - } else { - // negative - $si = -$si - pow(2, $bits); - $bin = base_convert($si, 10, 2); - $bin_length = strlen($bin); - if ($bin_length > $bits) { - $bin = str_repeat('1', $bits - $bin_length).$bin; - } - } - } - - return $bin; - } - - /** - * Send our auth message and returns the response. - * - * @param Swift_Transport_SmtpAgent $agent - * - * @return string SMTP Response - */ - protected function sendMessage1(Swift_Transport_SmtpAgent $agent) - { - $message = $this->createMessage1(); - - return $agent->executeCommand(sprintf("AUTH %s %s\r\n", $this->getAuthKeyword(), base64_encode($message)), array(334)); - } - - /** - * Fetch all details of our response (message 2). - * - * @param string $response - * - * @return array our response parsed - */ - protected function parseMessage2($response) - { - $responseHex = bin2hex($response); - $length = floor(hexdec(substr($responseHex, 28, 4)) / 256) * 2; - $offset = floor(hexdec(substr($responseHex, 32, 4)) / 256) * 2; - $challenge = $this->hex2bin(substr($responseHex, 48, 16)); - $context = $this->hex2bin(substr($responseHex, 64, 16)); - $targetInfoH = $this->hex2bin(substr($responseHex, 80, 16)); - $targetName = $this->hex2bin(substr($responseHex, $offset, $length)); - $offset = floor(hexdec(substr($responseHex, 88, 4)) / 256) * 2; - $targetInfoBlock = substr($responseHex, $offset); - list($domainName, $serverName, $DNSDomainName, $DNSServerName, $terminatorByte) = $this->readSubBlock($targetInfoBlock); - - return array( - $challenge, - $context, - $targetInfoH, - $targetName, - $domainName, - $serverName, - $DNSDomainName, - $DNSServerName, - $this->hex2bin($targetInfoBlock), - $terminatorByte, - ); - } - - /** - * Read the blob information in from message2. - * - * @param $block - * - * @return array - */ - protected function readSubBlock($block) - { - // remove terminatorByte cause it's always the same - $block = substr($block, 0, -8); - - $length = strlen($block); - $offset = 0; - $data = array(); - while ($offset < $length) { - $blockLength = hexdec(substr(substr($block, $offset, 8), -4)) / 256; - $offset += 8; - $data[] = $this->hex2bin(substr($block, $offset, $blockLength * 2)); - $offset += $blockLength * 2; - } - - if (count($data) == 3) { - $data[] = $data[2]; - $data[2] = ''; - } - - $data[] = $this->createByte('00'); - - return $data; - } - - /** - * Send our final message with all our data. - * - * @param string $response Message 1 response (message 2) - * @param string $username - * @param string $password - * @param string $timestamp - * @param string $client - * @param Swift_Transport_SmtpAgent $agent - * @param bool $v2 Use version2 of the protocol - * - * @return string - */ - protected function sendMessage3($response, $username, $password, $timestamp, $client, Swift_Transport_SmtpAgent $agent, $v2 = true) - { - list($domain, $username) = $this->getDomainAndUsername($username); - //$challenge, $context, $targetInfoH, $targetName, $domainName, $workstation, $DNSDomainName, $DNSServerName, $blob, $ter - list($challenge, , , , , $workstation, , , $blob) = $this->parseMessage2($response); - - if (!$v2) { - // LMv1 - $lmResponse = $this->createLMPassword($password, $challenge); - // NTLMv1 - $ntlmResponse = $this->createNTLMPassword($password, $challenge); - } else { - // LMv2 - $lmResponse = $this->createLMv2Password($password, $username, $domain, $challenge, $client); - // NTLMv2 - $ntlmResponse = $this->createNTLMv2Hash($password, $username, $domain, $challenge, $blob, $timestamp, $client); - } - - $message = $this->createMessage3($domain, $username, $workstation, $lmResponse, $ntlmResponse); - - return $agent->executeCommand(sprintf("%s\r\n", base64_encode($message)), array(235)); - } - - /** - * Create our message 1. - * - * @return string - */ - protected function createMessage1() - { - return self::NTLMSIG - .$this->createByte('01') // Message 1 -.$this->createByte('0702'); // Flags - } - - /** - * Create our message 3. - * - * @param string $domain - * @param string $username - * @param string $workstation - * @param string $lmResponse - * @param string $ntlmResponse - * - * @return string - */ - protected function createMessage3($domain, $username, $workstation, $lmResponse, $ntlmResponse) - { - // Create security buffers - $domainSec = $this->createSecurityBuffer($domain, 64); - $domainInfo = $this->readSecurityBuffer(bin2hex($domainSec)); - $userSec = $this->createSecurityBuffer($username, ($domainInfo[0] + $domainInfo[1]) / 2); - $userInfo = $this->readSecurityBuffer(bin2hex($userSec)); - $workSec = $this->createSecurityBuffer($workstation, ($userInfo[0] + $userInfo[1]) / 2); - $workInfo = $this->readSecurityBuffer(bin2hex($workSec)); - $lmSec = $this->createSecurityBuffer($lmResponse, ($workInfo[0] + $workInfo[1]) / 2, true); - $lmInfo = $this->readSecurityBuffer(bin2hex($lmSec)); - $ntlmSec = $this->createSecurityBuffer($ntlmResponse, ($lmInfo[0] + $lmInfo[1]) / 2, true); - - return self::NTLMSIG - .$this->createByte('03') // TYPE 3 message -.$lmSec // LM response header -.$ntlmSec // NTLM response header -.$domainSec // Domain header -.$userSec // User header -.$workSec // Workstation header -.$this->createByte('000000009a', 8) // session key header (empty) -.$this->createByte('01020000') // FLAGS -.$this->convertTo16bit($domain) // domain name -.$this->convertTo16bit($username) // username -.$this->convertTo16bit($workstation) // workstation -.$lmResponse - .$ntlmResponse; - } - - /** - * @param string $timestamp Epoch timestamp in microseconds - * @param string $client Random bytes - * @param string $targetInfo - * - * @return string - */ - protected function createBlob($timestamp, $client, $targetInfo) - { - return $this->createByte('0101') - .$this->createByte('00') - .$timestamp - .$client - .$this->createByte('00') - .$targetInfo - .$this->createByte('00'); - } - - /** - * Get domain and username from our username. - * - * @example DOMAIN\username - * - * @param string $name - * - * @return array - */ - protected function getDomainAndUsername($name) - { - if (strpos($name, '\\') !== false) { - return explode('\\', $name); - } - - list($user, $domain) = explode('@', $name); - - return array($domain, $user); - } - - /** - * Create LMv1 response. - * - * @param string $password - * @param string $challenge - * - * @return string - */ - protected function createLMPassword($password, $challenge) - { - // FIRST PART - $password = $this->createByte(strtoupper($password), 14, false); - list($key1, $key2) = str_split($password, 7); - - $desKey1 = $this->createDesKey($key1); - $desKey2 = $this->createDesKey($key2); - - $constantDecrypt = $this->createByte($this->desEncrypt(self::DESCONST, $desKey1).$this->desEncrypt(self::DESCONST, $desKey2), 21, false); - - // SECOND PART - list($key1, $key2, $key3) = str_split($constantDecrypt, 7); - - $desKey1 = $this->createDesKey($key1); - $desKey2 = $this->createDesKey($key2); - $desKey3 = $this->createDesKey($key3); - - return $this->desEncrypt($challenge, $desKey1).$this->desEncrypt($challenge, $desKey2).$this->desEncrypt($challenge, $desKey3); - } - - /** - * Create NTLMv1 response. - * - * @param string $password - * @param string $challenge - * - * @return string - */ - protected function createNTLMPassword($password, $challenge) - { - // FIRST PART - $ntlmHash = $this->createByte($this->md4Encrypt($password), 21, false); - list($key1, $key2, $key3) = str_split($ntlmHash, 7); - - $desKey1 = $this->createDesKey($key1); - $desKey2 = $this->createDesKey($key2); - $desKey3 = $this->createDesKey($key3); - - return $this->desEncrypt($challenge, $desKey1).$this->desEncrypt($challenge, $desKey2).$this->desEncrypt($challenge, $desKey3); - } - - /** - * Convert a normal timestamp to a tenth of a microtime epoch time. - * - * @param string $time - * - * @return string - */ - protected function getCorrectTimestamp($time) - { - // Get our timestamp (tricky!) - bcscale(0); - - $time = number_format($time, 0, '.', ''); // save microtime to string - $time = bcadd($time, '11644473600000'); // add epoch time - $time = bcmul($time, 10000); // tenths of a microsecond. - - $binary = $this->si2bin($time, 64); // create 64 bit binary string - $timestamp = ''; - for ($i = 0; $i < 8; ++$i) { - $timestamp .= chr(bindec(substr($binary, -(($i + 1) * 8), 8))); - } - - return $timestamp; - } - - /** - * Create LMv2 response. - * - * @param string $password - * @param string $username - * @param string $domain - * @param string $challenge NTLM Challenge - * @param string $client Random string - * - * @return string - */ - protected function createLMv2Password($password, $username, $domain, $challenge, $client) - { - $lmPass = '00'; // by default 00 - // if $password > 15 than we can't use this method - if (strlen($password) <= 15) { - $ntlmHash = $this->md4Encrypt($password); - $ntml2Hash = $this->md5Encrypt($ntlmHash, $this->convertTo16bit(strtoupper($username).$domain)); - - $lmPass = bin2hex($this->md5Encrypt($ntml2Hash, $challenge.$client).$client); - } - - return $this->createByte($lmPass, 24); - } - - /** - * Create NTLMv2 response. - * - * @param string $password - * @param string $username - * @param string $domain - * @param string $challenge Hex values - * @param string $targetInfo Hex values - * @param string $timestamp - * @param string $client Random bytes - * - * @return string - * - * @see http://davenport.sourceforge.net/ntlm.html#theNtlmResponse - */ - protected function createNTLMv2Hash($password, $username, $domain, $challenge, $targetInfo, $timestamp, $client) - { - $ntlmHash = $this->md4Encrypt($password); - $ntml2Hash = $this->md5Encrypt($ntlmHash, $this->convertTo16bit(strtoupper($username).$domain)); - - // create blob - $blob = $this->createBlob($timestamp, $client, $targetInfo); - - $ntlmv2Response = $this->md5Encrypt($ntml2Hash, $challenge.$blob); - - return $ntlmv2Response.$blob; - } - - protected function createDesKey($key) - { - $material = array(bin2hex($key[0])); - $len = strlen($key); - for ($i = 1; $i < $len; ++$i) { - list($high, $low) = str_split(bin2hex($key[$i])); - $v = $this->castToByte(ord($key[$i - 1]) << (7 + 1 - $i) | $this->uRShift(hexdec(dechex(hexdec($high) & 0xf).dechex(hexdec($low) & 0xf)), $i)); - $material[] = str_pad(substr(dechex($v), -2), 2, '0', STR_PAD_LEFT); // cast to byte - } - $material[] = str_pad(substr(dechex($this->castToByte(ord($key[6]) << 1)), -2), 2, '0'); - - // odd parity - foreach ($material as $k => $v) { - $b = $this->castToByte(hexdec($v)); - $needsParity = (($this->uRShift($b, 7) ^ $this->uRShift($b, 6) ^ $this->uRShift($b, 5) - ^ $this->uRShift($b, 4) ^ $this->uRShift($b, 3) ^ $this->uRShift($b, 2) - ^ $this->uRShift($b, 1)) & 0x01) == 0; - - list($high, $low) = str_split($v); - if ($needsParity) { - $material[$k] = dechex(hexdec($high) | 0x0).dechex(hexdec($low) | 0x1); - } else { - $material[$k] = dechex(hexdec($high) & 0xf).dechex(hexdec($low) & 0xe); - } - } - - return $this->hex2bin(implode('', $material)); - } - - /** HELPER FUNCTIONS */ - /** - * Create our security buffer depending on length and offset. - * - * @param string $value Value we want to put in - * @param int $offset start of value - * @param bool $is16 Do we 16bit string or not? - * - * @return string - */ - protected function createSecurityBuffer($value, $offset, $is16 = false) - { - $length = strlen(bin2hex($value)); - $length = $is16 ? $length / 2 : $length; - $length = $this->createByte(str_pad(dechex($length), 2, '0', STR_PAD_LEFT), 2); - - return $length.$length.$this->createByte(dechex($offset), 4); - } - - /** - * Read our security buffer to fetch length and offset of our value. - * - * @param string $value Securitybuffer in hex - * - * @return array array with length and offset - */ - protected function readSecurityBuffer($value) - { - $length = floor(hexdec(substr($value, 0, 4)) / 256) * 2; - $offset = floor(hexdec(substr($value, 8, 4)) / 256) * 2; - - return array($length, $offset); - } - - /** - * Cast to byte java equivalent to (byte). - * - * @param int $v - * - * @return int - */ - protected function castToByte($v) - { - return (($v + 128) % 256) - 128; - } - - /** - * Java unsigned right bitwise - * $a >>> $b. - * - * @param int $a - * @param int $b - * - * @return int - */ - protected function uRShift($a, $b) - { - if ($b == 0) { - return $a; - } - - return ($a >> $b) & ~(1 << (8 * PHP_INT_SIZE - 1) >> ($b - 1)); - } - - /** - * Right padding with 0 to certain length. - * - * @param string $input - * @param int $bytes Length of bytes - * @param bool $isHex Did we provided hex value - * - * @return string - */ - protected function createByte($input, $bytes = 4, $isHex = true) - { - if ($isHex) { - $byte = $this->hex2bin(str_pad($input, $bytes * 2, '00')); - } else { - $byte = str_pad($input, $bytes, "\x00"); - } - - return $byte; - } - - /** - * Create random bytes. - * - * @param $length - * - * @return string - */ - protected function getRandomBytes($length) - { - $bytes = openssl_random_pseudo_bytes($length, $strong); - - if (false !== $bytes && true === $strong) { - return $bytes; - } - - throw new RuntimeException('OpenSSL did not produce a secure random number.'); - } - - /** ENCRYPTION ALGORITHMS */ - /** - * DES Encryption. - * - * @param string $value An 8-byte string - * @param string $key - * - * @return string - */ - protected function desEncrypt($value, $key) - { - // 1 == OPENSSL_RAW_DATA - but constant is only available as of PHP 5.4. - return substr(openssl_encrypt($value, 'DES-ECB', $key, 1), 0, 8); - } - - /** - * MD5 Encryption. - * - * @param string $key Encryption key - * @param string $msg Message to encrypt - * - * @return string - */ - protected function md5Encrypt($key, $msg) - { - $blocksize = 64; - if (strlen($key) > $blocksize) { - $key = pack('H*', md5($key)); - } - - $key = str_pad($key, $blocksize, "\0"); - $ipadk = $key ^ str_repeat("\x36", $blocksize); - $opadk = $key ^ str_repeat("\x5c", $blocksize); - - return pack('H*', md5($opadk.pack('H*', md5($ipadk.$msg)))); - } - - /** - * MD4 Encryption. - * - * @param string $input - * - * @return string - * - * @see http://php.net/manual/en/ref.hash.php - */ - protected function md4Encrypt($input) - { - $input = $this->convertTo16bit($input); - - return function_exists('hash') ? $this->hex2bin(hash('md4', $input)) : mhash(MHASH_MD4, $input); - } - - /** - * Convert UTF-8 to UTF-16. - * - * @param string $input - * - * @return string - */ - protected function convertTo16bit($input) - { - return iconv('UTF-8', 'UTF-16LE', $input); - } - - /** - * Hex2bin replacement for < PHP 5.4. - * - * @param string $hex - * - * @return string Binary - */ - protected function hex2bin($hex) - { - if (function_exists('hex2bin')) { - return hex2bin($hex); - } else { - return pack('H*', $hex); - } - } - - /** - * @param string $message - */ - protected function debug($message) - { - $message = bin2hex($message); - $messageId = substr($message, 16, 8); - echo substr($message, 0, 16)." NTLMSSP Signature
\n"; - echo $messageId." Type Indicator
\n"; - - if ($messageId == '02000000') { - $map = array( - 'Challenge', - 'Context', - 'Target Information Security Buffer', - 'Target Name Data', - 'NetBIOS Domain Name', - 'NetBIOS Server Name', - 'DNS Domain Name', - 'DNS Server Name', - 'BLOB', - 'Target Information Terminator', - ); - - $data = $this->parseMessage2($this->hex2bin($message)); - - foreach ($map as $key => $value) { - echo bin2hex($data[$key]).' - '.$data[$key].' ||| '.$value."
\n"; - } - } elseif ($messageId == '03000000') { - $i = 0; - $data[$i++] = substr($message, 24, 16); - list($lmLength, $lmOffset) = $this->readSecurityBuffer($data[$i - 1]); - - $data[$i++] = substr($message, 40, 16); - list($ntmlLength, $ntmlOffset) = $this->readSecurityBuffer($data[$i - 1]); - - $data[$i++] = substr($message, 56, 16); - list($targetLength, $targetOffset) = $this->readSecurityBuffer($data[$i - 1]); - - $data[$i++] = substr($message, 72, 16); - list($userLength, $userOffset) = $this->readSecurityBuffer($data[$i - 1]); - - $data[$i++] = substr($message, 88, 16); - list($workLength, $workOffset) = $this->readSecurityBuffer($data[$i - 1]); - - $data[$i++] = substr($message, 104, 16); - $data[$i++] = substr($message, 120, 8); - $data[$i++] = substr($message, $targetOffset, $targetLength); - $data[$i++] = substr($message, $userOffset, $userLength); - $data[$i++] = substr($message, $workOffset, $workLength); - $data[$i++] = substr($message, $lmOffset, $lmLength); - $data[$i] = substr($message, $ntmlOffset, $ntmlLength); - - $map = array( - 'LM Response Security Buffer', - 'NTLM Response Security Buffer', - 'Target Name Security Buffer', - 'User Name Security Buffer', - 'Workstation Name Security Buffer', - 'Session Key Security Buffer', - 'Flags', - 'Target Name Data', - 'User Name Data', - 'Workstation Name Data', - 'LM Response Data', - 'NTLM Response Data', - ); - - foreach ($map as $key => $value) { - echo $data[$key].' - '.$this->hex2bin($data[$key]).' ||| '.$value."
\n"; - } - } - - echo '

'; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php b/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php deleted file mode 100644 index 43219f9..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php +++ /dev/null @@ -1,50 +0,0 @@ -executeCommand(sprintf("AUTH PLAIN %s\r\n", $message), array(235)); - - return true; - } catch (Swift_TransportException $e) { - $agent->executeCommand("RSET\r\n", array(250)); - - return false; - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/XOAuth2Authenticator.php b/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/XOAuth2Authenticator.php deleted file mode 100644 index ca35e7b..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Auth/XOAuth2Authenticator.php +++ /dev/null @@ -1,70 +0,0 @@ - - * $transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 587, 'tls') - * ->setAuthMode('XOAUTH2') - * ->setUsername('YOUR_EMAIL_ADDRESS') - * ->setPassword('YOUR_ACCESS_TOKEN'); - * - * - * @author xu.li - * - * @see https://developers.google.com/google-apps/gmail/xoauth2_protocol - */ -class Swift_Transport_Esmtp_Auth_XOAuth2Authenticator implements Swift_Transport_Esmtp_Authenticator -{ - /** - * Get the name of the AUTH mechanism this Authenticator handles. - * - * @return string - */ - public function getAuthKeyword() - { - return 'XOAUTH2'; - } - - /** - * Try to authenticate the user with $email and $token. - * - * @param Swift_Transport_SmtpAgent $agent - * @param string $email - * @param string $token - * - * @return bool - */ - public function authenticate(Swift_Transport_SmtpAgent $agent, $email, $token) - { - try { - $param = $this->constructXOAuth2Params($email, $token); - $agent->executeCommand('AUTH XOAUTH2 '.$param."\r\n", array(235)); - - return true; - } catch (Swift_TransportException $e) { - $agent->executeCommand("RSET\r\n", array(250)); - - return false; - } - } - - /** - * Construct the auth parameter. - * - * @see https://developers.google.com/google-apps/gmail/xoauth2_protocol#the_sasl_xoauth2_mechanism - */ - protected function constructXOAuth2Params($email, $token) - { - return base64_encode("user=$email\1auth=Bearer $token\1\1"); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/AuthHandler.php b/lib/SwiftMailer/classes/Swift/Transport/Esmtp/AuthHandler.php deleted file mode 100644 index cb36133..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/AuthHandler.php +++ /dev/null @@ -1,263 +0,0 @@ -setAuthenticators($authenticators); - } - - /** - * Set the Authenticators which can process a login request. - * - * @param Swift_Transport_Esmtp_Authenticator[] $authenticators - */ - public function setAuthenticators(array $authenticators) - { - $this->_authenticators = $authenticators; - } - - /** - * Get the Authenticators which can process a login request. - * - * @return Swift_Transport_Esmtp_Authenticator[] - */ - public function getAuthenticators() - { - return $this->_authenticators; - } - - /** - * Set the username to authenticate with. - * - * @param string $username - */ - public function setUsername($username) - { - $this->_username = $username; - } - - /** - * Get the username to authenticate with. - * - * @return string - */ - public function getUsername() - { - return $this->_username; - } - - /** - * Set the password to authenticate with. - * - * @param string $password - */ - public function setPassword($password) - { - $this->_password = $password; - } - - /** - * Get the password to authenticate with. - * - * @return string - */ - public function getPassword() - { - return $this->_password; - } - - /** - * Set the auth mode to use to authenticate. - * - * @param string $mode - */ - public function setAuthMode($mode) - { - $this->_auth_mode = $mode; - } - - /** - * Get the auth mode to use to authenticate. - * - * @return string - */ - public function getAuthMode() - { - return $this->_auth_mode; - } - - /** - * Get the name of the ESMTP extension this handles. - * - * @return bool - */ - public function getHandledKeyword() - { - return 'AUTH'; - } - - /** - * Set the parameters which the EHLO greeting indicated. - * - * @param string[] $parameters - */ - public function setKeywordParams(array $parameters) - { - $this->_esmtpParams = $parameters; - } - - /** - * Runs immediately after a EHLO has been issued. - * - * @param Swift_Transport_SmtpAgent $agent to read/write - */ - public function afterEhlo(Swift_Transport_SmtpAgent $agent) - { - if ($this->_username) { - $count = 0; - foreach ($this->_getAuthenticatorsForAgent() as $authenticator) { - if (in_array(strtolower($authenticator->getAuthKeyword()), - array_map('strtolower', $this->_esmtpParams))) { - ++$count; - if ($authenticator->authenticate($agent, $this->_username, $this->_password)) { - return; - } - } - } - throw new Swift_TransportException( - 'Failed to authenticate on SMTP server with username "'. - $this->_username.'" using '.$count.' possible authenticators' - ); - } - } - - /** - * Not used. - */ - public function getMailParams() - { - return array(); - } - - /** - * Not used. - */ - public function getRcptParams() - { - return array(); - } - - /** - * Not used. - */ - public function onCommand(Swift_Transport_SmtpAgent $agent, $command, $codes = array(), &$failedRecipients = null, &$stop = false) - { - } - - /** - * Returns +1, -1 or 0 according to the rules for usort(). - * - * This method is called to ensure extensions can be execute in an appropriate order. - * - * @param string $esmtpKeyword to compare with - * - * @return int - */ - public function getPriorityOver($esmtpKeyword) - { - return 0; - } - - /** - * Returns an array of method names which are exposed to the Esmtp class. - * - * @return string[] - */ - public function exposeMixinMethods() - { - return array('setUsername', 'getUsername', 'setPassword', 'getPassword', 'setAuthMode', 'getAuthMode'); - } - - /** - * Not used. - */ - public function resetState() - { - } - - /** - * Returns the authenticator list for the given agent. - * - * @param Swift_Transport_SmtpAgent $agent - * - * @return array - */ - protected function _getAuthenticatorsForAgent() - { - if (!$mode = strtolower($this->_auth_mode)) { - return $this->_authenticators; - } - - foreach ($this->_authenticators as $authenticator) { - if (strtolower($authenticator->getAuthKeyword()) == $mode) { - return array($authenticator); - } - } - - throw new Swift_TransportException('Auth mode '.$mode.' is invalid'); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Authenticator.php b/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Authenticator.php deleted file mode 100644 index 12a9abf..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/Esmtp/Authenticator.php +++ /dev/null @@ -1,35 +0,0 @@ -. - * - * @return string[] - */ - public function getMailParams(); - - /** - * Get params which are appended to RCPT TO:<>. - * - * @return string[] - */ - public function getRcptParams(); - - /** - * Runs when a command is due to be sent. - * - * @param Swift_Transport_SmtpAgent $agent to read/write - * @param string $command to send - * @param int[] $codes expected in response - * @param string[] $failedRecipients to collect failures - * @param bool $stop to be set true by-reference if the command is now sent - */ - public function onCommand(Swift_Transport_SmtpAgent $agent, $command, $codes = array(), &$failedRecipients = null, &$stop = false); - - /** - * Returns +1, -1 or 0 according to the rules for usort(). - * - * This method is called to ensure extensions can be execute in an appropriate order. - * - * @param string $esmtpKeyword to compare with - * - * @return int - */ - public function getPriorityOver($esmtpKeyword); - - /** - * Returns an array of method names which are exposed to the Esmtp class. - * - * @return string[] - */ - public function exposeMixinMethods(); - - /** - * Tells this handler to clear any buffers and reset its state. - */ - public function resetState(); -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/EsmtpTransport.php b/lib/SwiftMailer/classes/Swift/Transport/EsmtpTransport.php deleted file mode 100644 index a220e6f..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/EsmtpTransport.php +++ /dev/null @@ -1,413 +0,0 @@ - 'tcp', - 'host' => 'localhost', - 'port' => 25, - 'timeout' => 30, - 'blocking' => 1, - 'tls' => false, - 'type' => Swift_Transport_IoBuffer::TYPE_SOCKET, - 'stream_context_options' => array(), - ); - - /** - * Creates a new EsmtpTransport using the given I/O buffer. - * - * @param Swift_Transport_IoBuffer $buf - * @param Swift_Transport_EsmtpHandler[] $extensionHandlers - * @param Swift_Events_EventDispatcher $dispatcher - */ - public function __construct(Swift_Transport_IoBuffer $buf, array $extensionHandlers, Swift_Events_EventDispatcher $dispatcher) - { - parent::__construct($buf, $dispatcher); - $this->setExtensionHandlers($extensionHandlers); - } - - /** - * Set the host to connect to. - * - * @param string $host - * - * @return Swift_Transport_EsmtpTransport - */ - public function setHost($host) - { - $this->_params['host'] = $host; - - return $this; - } - - /** - * Get the host to connect to. - * - * @return string - */ - public function getHost() - { - return $this->_params['host']; - } - - /** - * Set the port to connect to. - * - * @param int $port - * - * @return Swift_Transport_EsmtpTransport - */ - public function setPort($port) - { - $this->_params['port'] = (int) $port; - - return $this; - } - - /** - * Get the port to connect to. - * - * @return int - */ - public function getPort() - { - return $this->_params['port']; - } - - /** - * Set the connection timeout. - * - * @param int $timeout seconds - * - * @return Swift_Transport_EsmtpTransport - */ - public function setTimeout($timeout) - { - $this->_params['timeout'] = (int) $timeout; - $this->_buffer->setParam('timeout', (int) $timeout); - - return $this; - } - - /** - * Get the connection timeout. - * - * @return int - */ - public function getTimeout() - { - return $this->_params['timeout']; - } - - /** - * Set the encryption type (tls or ssl). - * - * @param string $encryption - * - * @return Swift_Transport_EsmtpTransport - */ - public function setEncryption($encryption) - { - $encryption = strtolower($encryption); - if ('tls' == $encryption) { - $this->_params['protocol'] = 'tcp'; - $this->_params['tls'] = true; - } else { - $this->_params['protocol'] = $encryption; - $this->_params['tls'] = false; - } - - return $this; - } - - /** - * Get the encryption type. - * - * @return string - */ - public function getEncryption() - { - return $this->_params['tls'] ? 'tls' : $this->_params['protocol']; - } - - /** - * Sets the stream context options. - * - * @param array $options - * - * @return Swift_Transport_EsmtpTransport - */ - public function setStreamOptions($options) - { - $this->_params['stream_context_options'] = $options; - - return $this; - } - - /** - * Returns the stream context options. - * - * @return array - */ - public function getStreamOptions() - { - return $this->_params['stream_context_options']; - } - - /** - * Sets the source IP. - * - * @param string $source - * - * @return Swift_Transport_EsmtpTransport - */ - public function setSourceIp($source) - { - $this->_params['sourceIp'] = $source; - - return $this; - } - - /** - * Returns the IP used to connect to the destination. - * - * @return string - */ - public function getSourceIp() - { - return isset($this->_params['sourceIp']) ? $this->_params['sourceIp'] : null; - } - - /** - * Set ESMTP extension handlers. - * - * @param Swift_Transport_EsmtpHandler[] $handlers - * - * @return Swift_Transport_EsmtpTransport - */ - public function setExtensionHandlers(array $handlers) - { - $assoc = array(); - foreach ($handlers as $handler) { - $assoc[$handler->getHandledKeyword()] = $handler; - } - - @uasort($assoc, array($this, '_sortHandlers')); - $this->_handlers = $assoc; - $this->_setHandlerParams(); - - return $this; - } - - /** - * Get ESMTP extension handlers. - * - * @return Swift_Transport_EsmtpHandler[] - */ - public function getExtensionHandlers() - { - return array_values($this->_handlers); - } - - /** - * Run a command against the buffer, expecting the given response codes. - * - * If no response codes are given, the response will not be validated. - * If codes are given, an exception will be thrown on an invalid response. - * - * @param string $command - * @param int[] $codes - * @param string[] $failures An array of failures by-reference - * - * @return string - */ - public function executeCommand($command, $codes = array(), &$failures = null) - { - $failures = (array) $failures; - $stopSignal = false; - $response = null; - foreach ($this->_getActiveHandlers() as $handler) { - $response = $handler->onCommand( - $this, $command, $codes, $failures, $stopSignal - ); - if ($stopSignal) { - return $response; - } - } - - return parent::executeCommand($command, $codes, $failures); - } - - // -- Mixin invocation code - - /** Mixin handling method for ESMTP handlers */ - public function __call($method, $args) - { - foreach ($this->_handlers as $handler) { - if (in_array(strtolower($method), - array_map('strtolower', (array) $handler->exposeMixinMethods()) - )) { - $return = call_user_func_array(array($handler, $method), $args); - // Allow fluid method calls - if (is_null($return) && substr($method, 0, 3) == 'set') { - return $this; - } else { - return $return; - } - } - } - trigger_error('Call to undefined method '.$method, E_USER_ERROR); - } - - /** Get the params to initialize the buffer */ - protected function _getBufferParams() - { - return $this->_params; - } - - /** Overridden to perform EHLO instead */ - protected function _doHeloCommand() - { - try { - $response = $this->executeCommand( - sprintf("EHLO %s\r\n", $this->_domain), array(250) - ); - } catch (Swift_TransportException $e) { - return parent::_doHeloCommand(); - } - - if ($this->_params['tls']) { - try { - $this->executeCommand("STARTTLS\r\n", array(220)); - - if (!$this->_buffer->startTLS()) { - throw new Swift_TransportException('Unable to connect with TLS encryption'); - } - - try { - $response = $this->executeCommand( - sprintf("EHLO %s\r\n", $this->_domain), array(250) - ); - } catch (Swift_TransportException $e) { - return parent::_doHeloCommand(); - } - } catch (Swift_TransportException $e) { - $this->_throwException($e); - } - } - - $this->_capabilities = $this->_getCapabilities($response); - $this->_setHandlerParams(); - foreach ($this->_getActiveHandlers() as $handler) { - $handler->afterEhlo($this); - } - } - - /** Overridden to add Extension support */ - protected function _doMailFromCommand($address) - { - $handlers = $this->_getActiveHandlers(); - $params = array(); - foreach ($handlers as $handler) { - $params = array_merge($params, (array) $handler->getMailParams()); - } - $paramStr = !empty($params) ? ' '.implode(' ', $params) : ''; - $this->executeCommand( - sprintf("MAIL FROM:<%s>%s\r\n", $address, $paramStr), array(250) - ); - } - - /** Overridden to add Extension support */ - protected function _doRcptToCommand($address) - { - $handlers = $this->_getActiveHandlers(); - $params = array(); - foreach ($handlers as $handler) { - $params = array_merge($params, (array) $handler->getRcptParams()); - } - $paramStr = !empty($params) ? ' '.implode(' ', $params) : ''; - $this->executeCommand( - sprintf("RCPT TO:<%s>%s\r\n", $address, $paramStr), array(250, 251, 252) - ); - } - - /** Determine ESMTP capabilities by function group */ - private function _getCapabilities($ehloResponse) - { - $capabilities = array(); - $ehloResponse = trim($ehloResponse); - $lines = explode("\r\n", $ehloResponse); - array_shift($lines); - foreach ($lines as $line) { - if (preg_match('/^[0-9]{3}[ -]([A-Z0-9-]+)((?:[ =].*)?)$/Di', $line, $matches)) { - $keyword = strtoupper($matches[1]); - $paramStr = strtoupper(ltrim($matches[2], ' =')); - $params = !empty($paramStr) ? explode(' ', $paramStr) : array(); - $capabilities[$keyword] = $params; - } - } - - return $capabilities; - } - - /** Set parameters which are used by each extension handler */ - private function _setHandlerParams() - { - foreach ($this->_handlers as $keyword => $handler) { - if (array_key_exists($keyword, $this->_capabilities)) { - $handler->setKeywordParams($this->_capabilities[$keyword]); - } - } - } - - /** Get ESMTP handlers which are currently ok to use */ - private function _getActiveHandlers() - { - $handlers = array(); - foreach ($this->_handlers as $keyword => $handler) { - if (array_key_exists($keyword, $this->_capabilities)) { - $handlers[] = $handler; - } - } - - return $handlers; - } - - /** Custom sort for extension handler ordering */ - private function _sortHandlers($a, $b) - { - return $a->getPriorityOver($b->getHandledKeyword()); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/FailoverTransport.php b/lib/SwiftMailer/classes/Swift/Transport/FailoverTransport.php deleted file mode 100644 index 311a0f2..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/FailoverTransport.php +++ /dev/null @@ -1,88 +0,0 @@ -_transports); - $sent = 0; - $this->_lastUsedTransport = null; - - for ($i = 0; $i < $maxTransports - && $transport = $this->_getNextTransport(); ++$i) { - try { - if (!$transport->isStarted()) { - $transport->start(); - } - - if ($sent = $transport->send($message, $failedRecipients)) { - $this->_lastUsedTransport = $transport; - - return $sent; - } - } catch (Swift_TransportException $e) { - $this->_killCurrentTransport(); - } - } - - if (count($this->_transports) == 0) { - throw new Swift_TransportException( - 'All Transports in FailoverTransport failed, or no Transports available' - ); - } - - return $sent; - } - - protected function _getNextTransport() - { - if (!isset($this->_currentTransport)) { - $this->_currentTransport = parent::_getNextTransport(); - } - - return $this->_currentTransport; - } - - protected function _killCurrentTransport() - { - $this->_currentTransport = null; - parent::_killCurrentTransport(); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/IoBuffer.php b/lib/SwiftMailer/classes/Swift/Transport/IoBuffer.php deleted file mode 100644 index af97adf..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/IoBuffer.php +++ /dev/null @@ -1,67 +0,0 @@ -_transports = $transports; - $this->_deadTransports = array(); - } - - /** - * Get $transports to delegate to. - * - * @return Swift_Transport[] - */ - public function getTransports() - { - return array_merge($this->_transports, $this->_deadTransports); - } - - /** - * Get the Transport used in the last successful send operation. - * - * @return Swift_Transport - */ - public function getLastUsedTransport() - { - return $this->_lastUsedTransport; - } - - /** - * Test if this Transport mechanism has started. - * - * @return bool - */ - public function isStarted() - { - return count($this->_transports) > 0; - } - - /** - * Start this Transport mechanism. - */ - public function start() - { - $this->_transports = array_merge($this->_transports, $this->_deadTransports); - } - - /** - * Stop this Transport mechanism. - */ - public function stop() - { - foreach ($this->_transports as $transport) { - $transport->stop(); - } - } - - /** - * Send the given Message. - * - * Recipient/sender data will be retrieved from the Message API. - * The return value is the number of recipients who were accepted for delivery. - * - * @param Swift_Mime_Message $message - * @param string[] $failedRecipients An array of failures by-reference - * - * @return int - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - $maxTransports = count($this->_transports); - $sent = 0; - $this->_lastUsedTransport = null; - - for ($i = 0; $i < $maxTransports - && $transport = $this->_getNextTransport(); ++$i) { - try { - if (!$transport->isStarted()) { - $transport->start(); - } - if ($sent = $transport->send($message, $failedRecipients)) { - $this->_lastUsedTransport = $transport; - break; - } - } catch (Swift_TransportException $e) { - $this->_killCurrentTransport(); - } - } - - if (count($this->_transports) == 0) { - throw new Swift_TransportException( - 'All Transports in LoadBalancedTransport failed, or no Transports available' - ); - } - - return $sent; - } - - /** - * Register a plugin. - * - * @param Swift_Events_EventListener $plugin - */ - public function registerPlugin(Swift_Events_EventListener $plugin) - { - foreach ($this->_transports as $transport) { - $transport->registerPlugin($plugin); - } - } - - /** - * Rotates the transport list around and returns the first instance. - * - * @return Swift_Transport - */ - protected function _getNextTransport() - { - if ($next = array_shift($this->_transports)) { - $this->_transports[] = $next; - } - - return $next; - } - - /** - * Tag the currently used (top of stack) transport as dead/useless. - */ - protected function _killCurrentTransport() - { - if ($transport = array_pop($this->_transports)) { - try { - $transport->stop(); - } catch (Exception $e) { - } - $this->_deadTransports[] = $transport; - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/MailInvoker.php b/lib/SwiftMailer/classes/Swift/Transport/MailInvoker.php deleted file mode 100644 index 77489ce..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/MailInvoker.php +++ /dev/null @@ -1,32 +0,0 @@ -_invoker = $invoker; - $this->_eventDispatcher = $eventDispatcher; - } - - /** - * Not used. - */ - public function isStarted() - { - return false; - } - - /** - * Not used. - */ - public function start() - { - } - - /** - * Not used. - */ - public function stop() - { - } - - /** - * Set the additional parameters used on the mail() function. - * - * This string is formatted for sprintf() where %s is the sender address. - * - * @param string $params - * - * @return Swift_Transport_MailTransport - */ - public function setExtraParams($params) - { - $this->_extraParams = $params; - - return $this; - } - - /** - * Get the additional parameters used on the mail() function. - * - * This string is formatted for sprintf() where %s is the sender address. - * - * @return string - */ - public function getExtraParams() - { - return $this->_extraParams; - } - - /** - * Send the given Message. - * - * Recipient/sender data will be retrieved from the Message API. - * The return value is the number of recipients who were accepted for delivery. - * - * @param Swift_Mime_Message $message - * @param string[] $failedRecipients An array of failures by-reference - * - * @return int - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - $failedRecipients = (array) $failedRecipients; - - if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); - if ($evt->bubbleCancelled()) { - return 0; - } - } - - $count = ( - count((array) $message->getTo()) - + count((array) $message->getCc()) - + count((array) $message->getBcc()) - ); - - $toHeader = $message->getHeaders()->get('To'); - $subjectHeader = $message->getHeaders()->get('Subject'); - - if (0 === $count) { - $this->_throwException(new Swift_TransportException('Cannot send message without a recipient')); - } - $to = $toHeader ? $toHeader->getFieldBody() : ''; - $subject = $subjectHeader ? $subjectHeader->getFieldBody() : ''; - - $reversePath = $this->_getReversePath($message); - - // Remove headers that would otherwise be duplicated - $message->getHeaders()->remove('To'); - $message->getHeaders()->remove('Subject'); - - $messageStr = $message->toString(); - - if ($toHeader) { - $message->getHeaders()->set($toHeader); - } - $message->getHeaders()->set($subjectHeader); - - // Separate headers from body - if (false !== $endHeaders = strpos($messageStr, "\r\n\r\n")) { - $headers = substr($messageStr, 0, $endHeaders)."\r\n"; //Keep last EOL - $body = substr($messageStr, $endHeaders + 4); - } else { - $headers = $messageStr."\r\n"; - $body = ''; - } - - unset($messageStr); - - if ("\r\n" != PHP_EOL) { - // Non-windows (not using SMTP) - $headers = str_replace("\r\n", PHP_EOL, $headers); - $subject = str_replace("\r\n", PHP_EOL, $subject); - $body = str_replace("\r\n", PHP_EOL, $body); - } else { - // Windows, using SMTP - $headers = str_replace("\r\n.", "\r\n..", $headers); - $subject = str_replace("\r\n.", "\r\n..", $subject); - $body = str_replace("\r\n.", "\r\n..", $body); - } - - if ($this->_invoker->mail($to, $subject, $body, $headers, $this->_formatExtraParams($this->_extraParams, $reversePath))) { - if ($evt) { - $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); - $evt->setFailedRecipients($failedRecipients); - $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); - } - } else { - $failedRecipients = array_merge( - $failedRecipients, - array_keys((array) $message->getTo()), - array_keys((array) $message->getCc()), - array_keys((array) $message->getBcc()) - ); - - if ($evt) { - $evt->setResult(Swift_Events_SendEvent::RESULT_FAILED); - $evt->setFailedRecipients($failedRecipients); - $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); - } - - $message->generateId(); - - $count = 0; - } - - return $count; - } - - /** - * Register a plugin. - * - * @param Swift_Events_EventListener $plugin - */ - public function registerPlugin(Swift_Events_EventListener $plugin) - { - $this->_eventDispatcher->bindEventListener($plugin); - } - - /** Throw a TransportException, first sending it to any listeners */ - protected function _throwException(Swift_TransportException $e) - { - if ($evt = $this->_eventDispatcher->createTransportExceptionEvent($this, $e)) { - $this->_eventDispatcher->dispatchEvent($evt, 'exceptionThrown'); - if (!$evt->bubbleCancelled()) { - throw $e; - } - } else { - throw $e; - } - } - - /** Determine the best-use reverse path for this message */ - private function _getReversePath(Swift_Mime_Message $message) - { - $return = $message->getReturnPath(); - $sender = $message->getSender(); - $from = $message->getFrom(); - $path = null; - if (!empty($return)) { - $path = $return; - } elseif (!empty($sender)) { - $keys = array_keys($sender); - $path = array_shift($keys); - } elseif (!empty($from)) { - $keys = array_keys($from); - $path = array_shift($keys); - } - - return $path; - } - - /** - * Return php mail extra params to use for invoker->mail. - * - * @param $extraParams - * @param $reversePath - * - * @return string|null - */ - private function _formatExtraParams($extraParams, $reversePath) - { - if (false !== strpos($extraParams, '-f%s')) { - $extraParams = empty($reversePath) ? str_replace('-f%s', '', $extraParams) : sprintf($extraParams, escapeshellarg($reversePath)); - } - - return !empty($extraParams) ? $extraParams : null; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/NullTransport.php b/lib/SwiftMailer/classes/Swift/Transport/NullTransport.php deleted file mode 100644 index ad20e0e..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/NullTransport.php +++ /dev/null @@ -1,93 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Pretends messages have been sent, but just ignores them. - * - * @author Fabien Potencier - */ -class Swift_Transport_NullTransport implements Swift_Transport -{ - /** The event dispatcher from the plugin API */ - private $_eventDispatcher; - - /** - * Constructor. - */ - public function __construct(Swift_Events_EventDispatcher $eventDispatcher) - { - $this->_eventDispatcher = $eventDispatcher; - } - - /** - * Tests if this Transport mechanism has started. - * - * @return bool - */ - public function isStarted() - { - return true; - } - - /** - * Starts this Transport mechanism. - */ - public function start() - { - } - - /** - * Stops this Transport mechanism. - */ - public function stop() - { - } - - /** - * Sends the given message. - * - * @param Swift_Mime_Message $message - * @param string[] $failedRecipients An array of failures by-reference - * - * @return int The number of sent emails - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); - if ($evt->bubbleCancelled()) { - return 0; - } - } - - if ($evt) { - $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); - $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); - } - - $count = ( - count((array) $message->getTo()) - + count((array) $message->getCc()) - + count((array) $message->getBcc()) - ); - - return $count; - } - - /** - * Register a plugin. - * - * @param Swift_Events_EventListener $plugin - */ - public function registerPlugin(Swift_Events_EventListener $plugin) - { - $this->_eventDispatcher->bindEventListener($plugin); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/SendmailTransport.php b/lib/SwiftMailer/classes/Swift/Transport/SendmailTransport.php deleted file mode 100644 index 34ac4ce..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/SendmailTransport.php +++ /dev/null @@ -1,160 +0,0 @@ - 30, - 'blocking' => 1, - 'command' => '/usr/sbin/sendmail -bs', - 'type' => Swift_Transport_IoBuffer::TYPE_PROCESS, - ); - - /** - * Create a new SendmailTransport with $buf for I/O. - * - * @param Swift_Transport_IoBuffer $buf - * @param Swift_Events_EventDispatcher $dispatcher - */ - public function __construct(Swift_Transport_IoBuffer $buf, Swift_Events_EventDispatcher $dispatcher) - { - parent::__construct($buf, $dispatcher); - } - - /** - * Start the standalone SMTP session if running in -bs mode. - */ - public function start() - { - if (false !== strpos($this->getCommand(), ' -bs')) { - parent::start(); - } - } - - /** - * Set the command to invoke. - * - * If using -t mode you are strongly advised to include -oi or -i in the flags. - * For example: /usr/sbin/sendmail -oi -t - * Swift will append a -f flag if one is not present. - * - * The recommended mode is "-bs" since it is interactive and failure notifications - * are hence possible. - * - * @param string $command - * - * @return Swift_Transport_SendmailTransport - */ - public function setCommand($command) - { - $this->_params['command'] = $command; - - return $this; - } - - /** - * Get the sendmail command which will be invoked. - * - * @return string - */ - public function getCommand() - { - return $this->_params['command']; - } - - /** - * Send the given Message. - * - * Recipient/sender data will be retrieved from the Message API. - * - * The return value is the number of recipients who were accepted for delivery. - * NOTE: If using 'sendmail -t' you will not be aware of any failures until - * they bounce (i.e. send() will always return 100% success). - * - * @param Swift_Mime_Message $message - * @param string[] $failedRecipients An array of failures by-reference - * - * @return int - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - $failedRecipients = (array) $failedRecipients; - $command = $this->getCommand(); - $buffer = $this->getBuffer(); - $count = 0; - - if (false !== strpos($command, ' -t')) { - if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); - if ($evt->bubbleCancelled()) { - return 0; - } - } - - if (false === strpos($command, ' -f')) { - $command .= ' -f'.escapeshellarg($this->_getReversePath($message)); - } - - $buffer->initialize(array_merge($this->_params, array('command' => $command))); - - if (false === strpos($command, ' -i') && false === strpos($command, ' -oi')) { - $buffer->setWriteTranslations(array("\r\n" => "\n", "\n." => "\n..")); - } else { - $buffer->setWriteTranslations(array("\r\n" => "\n")); - } - - $count = count((array) $message->getTo()) - + count((array) $message->getCc()) - + count((array) $message->getBcc()) - ; - $message->toByteStream($buffer); - $buffer->flushBuffers(); - $buffer->setWriteTranslations(array()); - $buffer->terminate(); - - if ($evt) { - $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); - $evt->setFailedRecipients($failedRecipients); - $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); - } - - $message->generateId(); - } elseif (false !== strpos($command, ' -bs')) { - $count = parent::send($message, $failedRecipients); - } else { - $this->_throwException(new Swift_TransportException( - 'Unsupported sendmail command flags ['.$command.']. '. - 'Must be one of "-bs" or "-t" but can include additional flags.' - )); - } - - return $count; - } - - /** Get the params to initialize the buffer */ - protected function _getBufferParams() - { - return $this->_params; - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/SimpleMailInvoker.php b/lib/SwiftMailer/classes/Swift/Transport/SimpleMailInvoker.php deleted file mode 100644 index 4cab66b..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/SimpleMailInvoker.php +++ /dev/null @@ -1,39 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Stores Messages in a queue. - * - * @author Fabien Potencier - */ -class Swift_Transport_SpoolTransport implements Swift_Transport -{ - /** The spool instance */ - private $_spool; - - /** The event dispatcher from the plugin API */ - private $_eventDispatcher; - - /** - * Constructor. - */ - public function __construct(Swift_Events_EventDispatcher $eventDispatcher, Swift_Spool $spool = null) - { - $this->_eventDispatcher = $eventDispatcher; - $this->_spool = $spool; - } - - /** - * Sets the spool object. - * - * @param Swift_Spool $spool - * - * @return Swift_Transport_SpoolTransport - */ - public function setSpool(Swift_Spool $spool) - { - $this->_spool = $spool; - - return $this; - } - - /** - * Get the spool object. - * - * @return Swift_Spool - */ - public function getSpool() - { - return $this->_spool; - } - - /** - * Tests if this Transport mechanism has started. - * - * @return bool - */ - public function isStarted() - { - return true; - } - - /** - * Starts this Transport mechanism. - */ - public function start() - { - } - - /** - * Stops this Transport mechanism. - */ - public function stop() - { - } - - /** - * Sends the given message. - * - * @param Swift_Mime_Message $message - * @param string[] $failedRecipients An array of failures by-reference - * - * @return int The number of sent e-mail's - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); - if ($evt->bubbleCancelled()) { - return 0; - } - } - - $success = $this->_spool->queueMessage($message); - - if ($evt) { - $evt->setResult($success ? Swift_Events_SendEvent::RESULT_SPOOLED : Swift_Events_SendEvent::RESULT_FAILED); - $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); - } - - return 1; - } - - /** - * Register a plugin. - * - * @param Swift_Events_EventListener $plugin - */ - public function registerPlugin(Swift_Events_EventListener $plugin) - { - $this->_eventDispatcher->bindEventListener($plugin); - } -} diff --git a/lib/SwiftMailer/classes/Swift/Transport/StreamBuffer.php b/lib/SwiftMailer/classes/Swift/Transport/StreamBuffer.php deleted file mode 100644 index 32ec97c..0000000 --- a/lib/SwiftMailer/classes/Swift/Transport/StreamBuffer.php +++ /dev/null @@ -1,334 +0,0 @@ -_replacementFactory = $replacementFactory; - } - - /** - * Perform any initialization needed, using the given $params. - * - * Parameters will vary depending upon the type of IoBuffer used. - * - * @param array $params - */ - public function initialize(array $params) - { - $this->_params = $params; - switch ($params['type']) { - case self::TYPE_PROCESS: - $this->_establishProcessConnection(); - break; - case self::TYPE_SOCKET: - default: - $this->_establishSocketConnection(); - break; - } - } - - /** - * Set an individual param on the buffer (e.g. switching to SSL). - * - * @param string $param - * @param mixed $value - */ - public function setParam($param, $value) - { - if (isset($this->_stream)) { - switch ($param) { - case 'timeout': - if ($this->_stream) { - stream_set_timeout($this->_stream, $value); - } - break; - - case 'blocking': - if ($this->_stream) { - stream_set_blocking($this->_stream, 1); - } - - } - } - $this->_params[$param] = $value; - } - - public function startTLS() - { - return stream_socket_enable_crypto($this->_stream, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); - } - - /** - * Perform any shutdown logic needed. - */ - public function terminate() - { - if (isset($this->_stream)) { - switch ($this->_params['type']) { - case self::TYPE_PROCESS: - fclose($this->_in); - fclose($this->_out); - proc_close($this->_stream); - break; - case self::TYPE_SOCKET: - default: - fclose($this->_stream); - break; - } - } - $this->_stream = null; - $this->_out = null; - $this->_in = null; - } - - /** - * Set an array of string replacements which should be made on data written - * to the buffer. - * - * This could replace LF with CRLF for example. - * - * @param string[] $replacements - */ - public function setWriteTranslations(array $replacements) - { - foreach ($this->_translations as $search => $replace) { - if (!isset($replacements[$search])) { - $this->removeFilter($search); - unset($this->_translations[$search]); - } - } - - foreach ($replacements as $search => $replace) { - if (!isset($this->_translations[$search])) { - $this->addFilter( - $this->_replacementFactory->createFilter($search, $replace), $search - ); - $this->_translations[$search] = true; - } - } - } - - /** - * Get a line of output (including any CRLF). - * - * The $sequence number comes from any writes and may or may not be used - * depending upon the implementation. - * - * @param int $sequence of last write to scan from - * - * @throws Swift_IoException - * - * @return string - */ - public function readLine($sequence) - { - if (isset($this->_out) && !feof($this->_out)) { - $line = fgets($this->_out); - if (strlen($line) == 0) { - $metas = stream_get_meta_data($this->_out); - if ($metas['timed_out']) { - throw new Swift_IoException( - 'Connection to '. - $this->_getReadConnectionDescription(). - ' Timed Out' - ); - } - } - - return $line; - } - } - - /** - * Reads $length bytes from the stream into a string and moves the pointer - * through the stream by $length. - * - * If less bytes exist than are requested the remaining bytes are given instead. - * If no bytes are remaining at all, boolean false is returned. - * - * @param int $length - * - * @throws Swift_IoException - * - * @return string|bool - */ - public function read($length) - { - if (isset($this->_out) && !feof($this->_out)) { - $ret = fread($this->_out, $length); - if (strlen($ret) == 0) { - $metas = stream_get_meta_data($this->_out); - if ($metas['timed_out']) { - throw new Swift_IoException( - 'Connection to '. - $this->_getReadConnectionDescription(). - ' Timed Out' - ); - } - } - - return $ret; - } - } - - /** Not implemented */ - public function setReadPointer($byteOffset) - { - } - - /** Flush the stream contents */ - protected function _flush() - { - if (isset($this->_in)) { - fflush($this->_in); - } - } - - /** Write this bytes to the stream */ - protected function _commit($bytes) - { - if (isset($this->_in)) { - $bytesToWrite = strlen($bytes); - $totalBytesWritten = 0; - - while ($totalBytesWritten < $bytesToWrite) { - $bytesWritten = fwrite($this->_in, substr($bytes, $totalBytesWritten)); - if (false === $bytesWritten || 0 === $bytesWritten) { - break; - } - - $totalBytesWritten += $bytesWritten; - } - - if ($totalBytesWritten > 0) { - return ++$this->_sequence; - } - } - } - - /** - * Establishes a connection to a remote server. - */ - private function _establishSocketConnection() -{ - - $host = $this->_params['host']; - if (!empty($this->_params['protocol'])) { - $host = $this->_params['protocol'].'://'.$host; - } - - $timeout = 15; - if (!empty($this->_params['timeout'])) { - $timeout = $this->_params['timeout']; - } - - $options = array(); - if (!empty($this->_params['sourceIp'])) { - $options['socket']['bindto'] = $this->_params['sourceIp'].':0'; - } - - if (isset($this->_params['stream_context_options'])) { - $options = array_merge($options, $this->_params['stream_context_options']); - } - -$options['ssl']['verify_peer'] = FALSE; -$options['ssl']['verify_peer_name'] = FALSE; - - $streamContext = stream_context_create($options); - - $this->_stream = @stream_socket_client($host.':'.$this->_params['port'], $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $streamContext); - if (false === $this->_stream) { - throw new Swift_TransportException( - 'Connection could not be established with host '.$this->_params['host']. - ' ['.$errstr.' #'.$errno.']' - ); - } - if (!empty($this->_params['blocking'])) { - stream_set_blocking($this->_stream, 1); - } else { - stream_set_blocking($this->_stream, 0); - } - stream_set_timeout($this->_stream, $timeout); - $this->_in = &$this->_stream; - $this->_out = &$this->_stream; -} - - /** - * Opens a process for input/output. - */ - private function _establishProcessConnection() - { - $command = $this->_params['command']; - $descriptorSpec = array( - 0 => array('pipe', 'r'), - 1 => array('pipe', 'w'), - 2 => array('pipe', 'w'), - ); - $this->_stream = proc_open($command, $descriptorSpec, $pipes); - stream_set_blocking($pipes[2], 0); - if ($err = stream_get_contents($pipes[2])) { - throw new Swift_TransportException( - 'Process could not be started ['.$err.']' - ); - } - $this->_in = &$pipes[0]; - $this->_out = &$pipes[1]; - } - - private function _getReadConnectionDescription() - { - switch ($this->_params['type']) { - case self::TYPE_PROCESS: - return 'Process '.$this->_params['command']; - break; - - case self::TYPE_SOCKET: - default: - $host = $this->_params['host']; - if (!empty($this->_params['protocol'])) { - $host = $this->_params['protocol'].'://'.$host; - } - $host .= ':'.$this->_params['port']; - - return $host; - break; - } - } -} diff --git a/lib/SwiftMailer/classes/Swift/TransportException.php b/lib/SwiftMailer/classes/Swift/TransportException.php deleted file mode 100644 index 4ae2412..0000000 --- a/lib/SwiftMailer/classes/Swift/TransportException.php +++ /dev/null @@ -1,29 +0,0 @@ - - */ -class Swift_Validate -{ - /** - * Grammar Object. - * - * @var Swift_Mime_Grammar - */ - private static $grammar = null; - - /** - * Checks if an e-mail address matches the current grammars. - * - * @param string $email - * - * @return bool - */ - public static function email($email) - { - if (self::$grammar === null) { - self::$grammar = Swift_DependencyContainer::getInstance() - ->lookup('mime.grammar'); - } - - return (bool) preg_match( - '/^'.self::$grammar->getDefinition('addr-spec').'$/D', - $email - ); - } -} diff --git a/lib/SwiftMailer/dependency_maps/cache_deps.php b/lib/SwiftMailer/dependency_maps/cache_deps.php deleted file mode 100644 index 6023448..0000000 --- a/lib/SwiftMailer/dependency_maps/cache_deps.php +++ /dev/null @@ -1,23 +0,0 @@ -register('cache') - ->asAliasOf('cache.array') - - ->register('tempdir') - ->asValue('/tmp') - - ->register('cache.null') - ->asSharedInstanceOf('Swift_KeyCache_NullKeyCache') - - ->register('cache.array') - ->asSharedInstanceOf('Swift_KeyCache_ArrayKeyCache') - ->withDependencies(array('cache.inputstream')) - - ->register('cache.disk') - ->asSharedInstanceOf('Swift_KeyCache_DiskKeyCache') - ->withDependencies(array('cache.inputstream', 'tempdir')) - - ->register('cache.inputstream') - ->asNewInstanceOf('Swift_KeyCache_SimpleKeyCacheInputStream') -; diff --git a/lib/SwiftMailer/dependency_maps/message_deps.php b/lib/SwiftMailer/dependency_maps/message_deps.php deleted file mode 100644 index 64d69d2..0000000 --- a/lib/SwiftMailer/dependency_maps/message_deps.php +++ /dev/null @@ -1,9 +0,0 @@ -register('message.message') - ->asNewInstanceOf('Swift_Message') - - ->register('message.mimepart') - ->asNewInstanceOf('Swift_MimePart') -; diff --git a/lib/SwiftMailer/dependency_maps/mime_deps.php b/lib/SwiftMailer/dependency_maps/mime_deps.php deleted file mode 100644 index 56169c9..0000000 --- a/lib/SwiftMailer/dependency_maps/mime_deps.php +++ /dev/null @@ -1,123 +0,0 @@ -register('properties.charset') - ->asValue('utf-8') - - ->register('mime.grammar') - ->asSharedInstanceOf('Swift_Mime_Grammar') - - ->register('mime.message') - ->asNewInstanceOf('Swift_Mime_SimpleMessage') - ->withDependencies(array( - 'mime.headerset', - 'mime.qpcontentencoder', - 'cache', - 'mime.grammar', - 'properties.charset', - )) - - ->register('mime.part') - ->asNewInstanceOf('Swift_Mime_MimePart') - ->withDependencies(array( - 'mime.headerset', - 'mime.qpcontentencoder', - 'cache', - 'mime.grammar', - 'properties.charset', - )) - - ->register('mime.attachment') - ->asNewInstanceOf('Swift_Mime_Attachment') - ->withDependencies(array( - 'mime.headerset', - 'mime.base64contentencoder', - 'cache', - 'mime.grammar', - )) - ->addConstructorValue($swift_mime_types) - - ->register('mime.embeddedfile') - ->asNewInstanceOf('Swift_Mime_EmbeddedFile') - ->withDependencies(array( - 'mime.headerset', - 'mime.base64contentencoder', - 'cache', - 'mime.grammar', - )) - ->addConstructorValue($swift_mime_types) - - ->register('mime.headerfactory') - ->asNewInstanceOf('Swift_Mime_SimpleHeaderFactory') - ->withDependencies(array( - 'mime.qpheaderencoder', - 'mime.rfc2231encoder', - 'mime.grammar', - 'properties.charset', - )) - - ->register('mime.headerset') - ->asNewInstanceOf('Swift_Mime_SimpleHeaderSet') - ->withDependencies(array('mime.headerfactory', 'properties.charset')) - - ->register('mime.qpheaderencoder') - ->asNewInstanceOf('Swift_Mime_HeaderEncoder_QpHeaderEncoder') - ->withDependencies(array('mime.charstream')) - - ->register('mime.base64headerencoder') - ->asNewInstanceOf('Swift_Mime_HeaderEncoder_Base64HeaderEncoder') - ->withDependencies(array('mime.charstream')) - - ->register('mime.charstream') - ->asNewInstanceOf('Swift_CharacterStream_NgCharacterStream') - ->withDependencies(array('mime.characterreaderfactory', 'properties.charset')) - - ->register('mime.bytecanonicalizer') - ->asSharedInstanceOf('Swift_StreamFilters_ByteArrayReplacementFilter') - ->addConstructorValue(array(array(0x0D, 0x0A), array(0x0D), array(0x0A))) - ->addConstructorValue(array(array(0x0A), array(0x0A), array(0x0D, 0x0A))) - - ->register('mime.characterreaderfactory') - ->asSharedInstanceOf('Swift_CharacterReaderFactory_SimpleCharacterReaderFactory') - - ->register('mime.safeqpcontentencoder') - ->asNewInstanceOf('Swift_Mime_ContentEncoder_QpContentEncoder') - ->withDependencies(array('mime.charstream', 'mime.bytecanonicalizer')) - - ->register('mime.rawcontentencoder') - ->asNewInstanceOf('Swift_Mime_ContentEncoder_RawContentEncoder') - - ->register('mime.nativeqpcontentencoder') - ->withDependencies(array('properties.charset')) - ->asNewInstanceOf('Swift_Mime_ContentEncoder_NativeQpContentEncoder') - - ->register('mime.qpcontentencoderproxy') - ->asNewInstanceOf('Swift_Mime_ContentEncoder_QpContentEncoderProxy') - ->withDependencies(array('mime.safeqpcontentencoder', 'mime.nativeqpcontentencoder', 'properties.charset')) - - ->register('mime.7bitcontentencoder') - ->asNewInstanceOf('Swift_Mime_ContentEncoder_PlainContentEncoder') - ->addConstructorValue('7bit') - ->addConstructorValue(true) - - ->register('mime.8bitcontentencoder') - ->asNewInstanceOf('Swift_Mime_ContentEncoder_PlainContentEncoder') - ->addConstructorValue('8bit') - ->addConstructorValue(true) - - ->register('mime.base64contentencoder') - ->asSharedInstanceOf('Swift_Mime_ContentEncoder_Base64ContentEncoder') - - ->register('mime.rfc2231encoder') - ->asNewInstanceOf('Swift_Encoder_Rfc2231Encoder') - ->withDependencies(array('mime.charstream')) - - // As of PHP 5.4.7, the quoted_printable_encode() function behaves correctly. - // see https://github.com/php/php-src/commit/18bb426587d62f93c54c40bf8535eb8416603629 - ->register('mime.qpcontentencoder') - ->asAliasOf(version_compare(phpversion(), '5.4.7', '>=') ? 'mime.qpcontentencoderproxy' : 'mime.safeqpcontentencoder') -; - -unset($swift_mime_types); diff --git a/lib/SwiftMailer/dependency_maps/transport_deps.php b/lib/SwiftMailer/dependency_maps/transport_deps.php deleted file mode 100644 index 77e432c..0000000 --- a/lib/SwiftMailer/dependency_maps/transport_deps.php +++ /dev/null @@ -1,76 +0,0 @@ -register('transport.smtp') - ->asNewInstanceOf('Swift_Transport_EsmtpTransport') - ->withDependencies(array( - 'transport.buffer', - array('transport.authhandler'), - 'transport.eventdispatcher', - )) - - ->register('transport.sendmail') - ->asNewInstanceOf('Swift_Transport_SendmailTransport') - ->withDependencies(array( - 'transport.buffer', - 'transport.eventdispatcher', - )) - - ->register('transport.mail') - ->asNewInstanceOf('Swift_Transport_MailTransport') - ->withDependencies(array('transport.mailinvoker', 'transport.eventdispatcher')) - - ->register('transport.loadbalanced') - ->asNewInstanceOf('Swift_Transport_LoadBalancedTransport') - - ->register('transport.failover') - ->asNewInstanceOf('Swift_Transport_FailoverTransport') - - ->register('transport.spool') - ->asNewInstanceOf('Swift_Transport_SpoolTransport') - ->withDependencies(array('transport.eventdispatcher')) - - ->register('transport.null') - ->asNewInstanceOf('Swift_Transport_NullTransport') - ->withDependencies(array('transport.eventdispatcher')) - - ->register('transport.mailinvoker') - ->asSharedInstanceOf('Swift_Transport_SimpleMailInvoker') - - ->register('transport.buffer') - ->asNewInstanceOf('Swift_Transport_StreamBuffer') - ->withDependencies(array('transport.replacementfactory')) - - ->register('transport.authhandler') - ->asNewInstanceOf('Swift_Transport_Esmtp_AuthHandler') - ->withDependencies(array( - array( - 'transport.crammd5auth', - 'transport.loginauth', - 'transport.plainauth', - 'transport.ntlmauth', - 'transport.xoauth2auth', - ), - )) - - ->register('transport.crammd5auth') - ->asNewInstanceOf('Swift_Transport_Esmtp_Auth_CramMd5Authenticator') - - ->register('transport.loginauth') - ->asNewInstanceOf('Swift_Transport_Esmtp_Auth_LoginAuthenticator') - - ->register('transport.plainauth') - ->asNewInstanceOf('Swift_Transport_Esmtp_Auth_PlainAuthenticator') - - ->register('transport.xoauth2auth') - ->asNewInstanceOf('Swift_Transport_Esmtp_Auth_XOAuth2Authenticator') - - ->register('transport.ntlmauth') - ->asNewInstanceOf('Swift_Transport_Esmtp_Auth_NTLMAuthenticator') - - ->register('transport.eventdispatcher') - ->asNewInstanceOf('Swift_Events_SimpleEventDispatcher') - - ->register('transport.replacementfactory') - ->asSharedInstanceOf('Swift_StreamFilters_StringReplacementFilterFactory') -; diff --git a/lib/SwiftMailer/mime_types.php b/lib/SwiftMailer/mime_types.php deleted file mode 100644 index 2d7b98d..0000000 --- a/lib/SwiftMailer/mime_types.php +++ /dev/null @@ -1,1007 +0,0 @@ - 'text/vnd.in3d.3dml', - '3ds' => 'image/x-3ds', - '3g2' => 'video/3gpp2', - '3gp' => 'video/3gpp', - '7z' => 'application/x-7z-compressed', - 'aab' => 'application/x-authorware-bin', - 'aac' => 'audio/x-aac', - 'aam' => 'application/x-authorware-map', - 'aas' => 'application/x-authorware-seg', - 'abw' => 'application/x-abiword', - 'ac' => 'application/pkix-attr-cert', - 'acc' => 'application/vnd.americandynamics.acc', - 'ace' => 'application/x-ace-compressed', - 'acu' => 'application/vnd.acucobol', - 'acutc' => 'application/vnd.acucorp', - 'adp' => 'audio/adpcm', - 'aep' => 'application/vnd.audiograph', - 'afm' => 'application/x-font-type1', - 'afp' => 'application/vnd.ibm.modcap', - 'ahead' => 'application/vnd.ahead.space', - 'ai' => 'application/postscript', - 'aif' => 'audio/x-aiff', - 'aifc' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'air' => 'application/vnd.adobe.air-application-installer-package+zip', - 'ait' => 'application/vnd.dvb.ait', - 'ami' => 'application/vnd.amiga.ami', - 'apk' => 'application/vnd.android.package-archive', - 'appcache' => 'text/cache-manifest', - 'apr' => 'application/vnd.lotus-approach', - 'aps' => 'application/postscript', - 'arc' => 'application/x-freearc', - 'asc' => 'application/pgp-signature', - 'asf' => 'video/x-ms-asf', - 'asm' => 'text/x-asm', - 'aso' => 'application/vnd.accpac.simply.aso', - 'asx' => 'video/x-ms-asf', - 'atc' => 'application/vnd.acucorp', - 'atom' => 'application/atom+xml', - 'atomcat' => 'application/atomcat+xml', - 'atomsvc' => 'application/atomsvc+xml', - 'atx' => 'application/vnd.antix.game-component', - 'au' => 'audio/basic', - 'avi' => 'video/x-msvideo', - 'aw' => 'application/applixware', - 'azf' => 'application/vnd.airzip.filesecure.azf', - 'azs' => 'application/vnd.airzip.filesecure.azs', - 'azw' => 'application/vnd.amazon.ebook', - 'bat' => 'application/x-msdownload', - 'bcpio' => 'application/x-bcpio', - 'bdf' => 'application/x-font-bdf', - 'bdm' => 'application/vnd.syncml.dm+wbxml', - 'bed' => 'application/vnd.realvnc.bed', - 'bh2' => 'application/vnd.fujitsu.oasysprs', - 'bin' => 'application/octet-stream', - 'blb' => 'application/x-blorb', - 'blorb' => 'application/x-blorb', - 'bmi' => 'application/vnd.bmi', - 'bmp' => 'image/bmp', - 'book' => 'application/vnd.framemaker', - 'box' => 'application/vnd.previewsystems.box', - 'boz' => 'application/x-bzip2', - 'bpk' => 'application/octet-stream', - 'btif' => 'image/prs.btif', - 'bz' => 'application/x-bzip', - 'bz2' => 'application/x-bzip2', - 'c' => 'text/x-c', - 'c11amc' => 'application/vnd.cluetrust.cartomobile-config', - 'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg', - 'c4d' => 'application/vnd.clonk.c4group', - 'c4f' => 'application/vnd.clonk.c4group', - 'c4g' => 'application/vnd.clonk.c4group', - 'c4p' => 'application/vnd.clonk.c4group', - 'c4u' => 'application/vnd.clonk.c4group', - 'cab' => 'application/vnd.ms-cab-compressed', - 'caf' => 'audio/x-caf', - 'cap' => 'application/vnd.tcpdump.pcap', - 'car' => 'application/vnd.curl.car', - 'cat' => 'application/vnd.ms-pki.seccat', - 'cb7' => 'application/x-cbr', - 'cba' => 'application/x-cbr', - 'cbr' => 'application/x-cbr', - 'cbt' => 'application/x-cbr', - 'cbz' => 'application/x-cbr', - 'cc' => 'text/x-c', - 'cct' => 'application/x-director', - 'ccxml' => 'application/ccxml+xml', - 'cdbcmsg' => 'application/vnd.contact.cmsg', - 'cdf' => 'application/x-netcdf', - 'cdkey' => 'application/vnd.mediastation.cdkey', - 'cdmia' => 'application/cdmi-capability', - 'cdmic' => 'application/cdmi-container', - 'cdmid' => 'application/cdmi-domain', - 'cdmio' => 'application/cdmi-object', - 'cdmiq' => 'application/cdmi-queue', - 'cdx' => 'chemical/x-cdx', - 'cdxml' => 'application/vnd.chemdraw+xml', - 'cdy' => 'application/vnd.cinderella', - 'cer' => 'application/pkix-cert', - 'cfs' => 'application/x-cfs-compressed', - 'cgm' => 'image/cgm', - 'chat' => 'application/x-chat', - 'chm' => 'application/vnd.ms-htmlhelp', - 'chrt' => 'application/vnd.kde.kchart', - 'cif' => 'chemical/x-cif', - 'cii' => 'application/vnd.anser-web-certificate-issue-initiation', - 'cil' => 'application/vnd.ms-artgalry', - 'cla' => 'application/vnd.claymore', - 'class' => 'application/java-vm', - 'clkk' => 'application/vnd.crick.clicker.keyboard', - 'clkp' => 'application/vnd.crick.clicker.palette', - 'clkt' => 'application/vnd.crick.clicker.template', - 'clkw' => 'application/vnd.crick.clicker.wordbank', - 'clkx' => 'application/vnd.crick.clicker', - 'clp' => 'application/x-msclip', - 'cmc' => 'application/vnd.cosmocaller', - 'cmdf' => 'chemical/x-cmdf', - 'cml' => 'chemical/x-cml', - 'cmp' => 'application/vnd.yellowriver-custom-menu', - 'cmx' => 'image/x-cmx', - 'cod' => 'application/vnd.rim.cod', - 'com' => 'application/x-msdownload', - 'conf' => 'text/plain', - 'cpio' => 'application/x-cpio', - 'cpp' => 'text/x-c', - 'cpt' => 'application/mac-compactpro', - 'crd' => 'application/x-mscardfile', - 'crl' => 'application/pkix-crl', - 'crt' => 'application/x-x509-ca-cert', - 'csh' => 'application/x-csh', - 'csml' => 'chemical/x-csml', - 'csp' => 'application/vnd.commonspace', - 'css' => 'text/css', - 'cst' => 'application/x-director', - 'csv' => 'text/csv', - 'cu' => 'application/cu-seeme', - 'curl' => 'text/vnd.curl', - 'cww' => 'application/prs.cww', - 'cxt' => 'application/x-director', - 'cxx' => 'text/x-c', - 'dae' => 'model/vnd.collada+xml', - 'daf' => 'application/vnd.mobius.daf', - 'dart' => 'application/vnd.dart', - 'dataless' => 'application/vnd.fdsn.seed', - 'davmount' => 'application/davmount+xml', - 'dbk' => 'application/docbook+xml', - 'dcr' => 'application/x-director', - 'dcurl' => 'text/vnd.curl.dcurl', - 'dd2' => 'application/vnd.oma.dd2+xml', - 'ddd' => 'application/vnd.fujixerox.ddd', - 'deb' => 'application/x-debian-package', - 'def' => 'text/plain', - 'deploy' => 'application/octet-stream', - 'der' => 'application/x-x509-ca-cert', - 'dfac' => 'application/vnd.dreamfactory', - 'dgc' => 'application/x-dgc-compressed', - 'dic' => 'text/x-c', - 'dir' => 'application/x-director', - 'dis' => 'application/vnd.mobius.dis', - 'dist' => 'application/octet-stream', - 'distz' => 'application/octet-stream', - 'djv' => 'image/vnd.djvu', - 'djvu' => 'image/vnd.djvu', - 'dll' => 'application/x-msdownload', - 'dmg' => 'application/x-apple-diskimage', - 'dmp' => 'application/vnd.tcpdump.pcap', - 'dms' => 'application/octet-stream', - 'dna' => 'application/vnd.dna', - 'doc' => 'application/msword', - 'docm' => 'application/vnd.ms-word.document.macroenabled.12', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'dot' => 'application/msword', - 'dotm' => 'application/vnd.ms-word.template.macroenabled.12', - 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', - 'dp' => 'application/vnd.osgi.dp', - 'dpg' => 'application/vnd.dpgraph', - 'dra' => 'audio/vnd.dra', - 'dsc' => 'text/prs.lines.tag', - 'dssc' => 'application/dssc+der', - 'dtb' => 'application/x-dtbook+xml', - 'dtd' => 'application/xml-dtd', - 'dts' => 'audio/vnd.dts', - 'dtshd' => 'audio/vnd.dts.hd', - 'dump' => 'application/octet-stream', - 'dvb' => 'video/vnd.dvb.file', - 'dvi' => 'application/x-dvi', - 'dwf' => 'model/vnd.dwf', - 'dwg' => 'image/vnd.dwg', - 'dxf' => 'image/vnd.dxf', - 'dxp' => 'application/vnd.spotfire.dxp', - 'dxr' => 'application/x-director', - 'ecelp4800' => 'audio/vnd.nuera.ecelp4800', - 'ecelp7470' => 'audio/vnd.nuera.ecelp7470', - 'ecelp9600' => 'audio/vnd.nuera.ecelp9600', - 'ecma' => 'application/ecmascript', - 'edm' => 'application/vnd.novadigm.edm', - 'edx' => 'application/vnd.novadigm.edx', - 'efif' => 'application/vnd.picsel', - 'ei6' => 'application/vnd.pg.osasli', - 'elc' => 'application/octet-stream', - 'emf' => 'application/x-msmetafile', - 'eml' => 'message/rfc822', - 'emma' => 'application/emma+xml', - 'emz' => 'application/x-msmetafile', - 'eol' => 'audio/vnd.digital-winds', - 'eot' => 'application/vnd.ms-fontobject', - 'eps' => 'application/postscript', - 'epub' => 'application/epub+zip', - 'es3' => 'application/vnd.eszigno3+xml', - 'esa' => 'application/vnd.osgi.subsystem', - 'esf' => 'application/vnd.epson.esf', - 'et3' => 'application/vnd.eszigno3+xml', - 'etx' => 'text/x-setext', - 'eva' => 'application/x-eva', - 'evy' => 'application/x-envoy', - 'exe' => 'application/x-msdownload', - 'exi' => 'application/exi', - 'ext' => 'application/vnd.novadigm.ext', - 'ez' => 'application/andrew-inset', - 'ez2' => 'application/vnd.ezpix-album', - 'ez3' => 'application/vnd.ezpix-package', - 'f' => 'text/x-fortran', - 'f4v' => 'video/x-f4v', - 'f77' => 'text/x-fortran', - 'f90' => 'text/x-fortran', - 'fbs' => 'image/vnd.fastbidsheet', - 'fcdt' => 'application/vnd.adobe.formscentral.fcdt', - 'fcs' => 'application/vnd.isac.fcs', - 'fdf' => 'application/vnd.fdf', - 'fe_launch' => 'application/vnd.denovo.fcselayout-link', - 'fg5' => 'application/vnd.fujitsu.oasysgp', - 'fgd' => 'application/x-director', - 'fh' => 'image/x-freehand', - 'fh4' => 'image/x-freehand', - 'fh5' => 'image/x-freehand', - 'fh7' => 'image/x-freehand', - 'fhc' => 'image/x-freehand', - 'fig' => 'application/x-xfig', - 'flac' => 'audio/x-flac', - 'fli' => 'video/x-fli', - 'flo' => 'application/vnd.micrografx.flo', - 'flv' => 'video/x-flv', - 'flw' => 'application/vnd.kde.kivio', - 'flx' => 'text/vnd.fmi.flexstor', - 'fly' => 'text/vnd.fly', - 'fm' => 'application/vnd.framemaker', - 'fnc' => 'application/vnd.frogans.fnc', - 'for' => 'text/x-fortran', - 'fpx' => 'image/vnd.fpx', - 'frame' => 'application/vnd.framemaker', - 'fsc' => 'application/vnd.fsc.weblaunch', - 'fst' => 'image/vnd.fst', - 'ftc' => 'application/vnd.fluxtime.clip', - 'fti' => 'application/vnd.anser-web-funds-transfer-initiation', - 'fvt' => 'video/vnd.fvt', - 'fxp' => 'application/vnd.adobe.fxp', - 'fxpl' => 'application/vnd.adobe.fxp', - 'fzs' => 'application/vnd.fuzzysheet', - 'g2w' => 'application/vnd.geoplan', - 'g3' => 'image/g3fax', - 'g3w' => 'application/vnd.geospace', - 'gac' => 'application/vnd.groove-account', - 'gam' => 'application/x-tads', - 'gbr' => 'application/rpki-ghostbusters', - 'gca' => 'application/x-gca-compressed', - 'gdl' => 'model/vnd.gdl', - 'geo' => 'application/vnd.dynageo', - 'gex' => 'application/vnd.geometry-explorer', - 'ggb' => 'application/vnd.geogebra.file', - 'ggt' => 'application/vnd.geogebra.tool', - 'ghf' => 'application/vnd.groove-help', - 'gif' => 'image/gif', - 'gim' => 'application/vnd.groove-identity-message', - 'gml' => 'application/gml+xml', - 'gmx' => 'application/vnd.gmx', - 'gnumeric' => 'application/x-gnumeric', - 'gph' => 'application/vnd.flographit', - 'gpx' => 'application/gpx+xml', - 'gqf' => 'application/vnd.grafeq', - 'gqs' => 'application/vnd.grafeq', - 'gram' => 'application/srgs', - 'gramps' => 'application/x-gramps-xml', - 'gre' => 'application/vnd.geometry-explorer', - 'grv' => 'application/vnd.groove-injector', - 'grxml' => 'application/srgs+xml', - 'gsf' => 'application/x-font-ghostscript', - 'gtar' => 'application/x-gtar', - 'gtm' => 'application/vnd.groove-tool-message', - 'gtw' => 'model/vnd.gtw', - 'gv' => 'text/vnd.graphviz', - 'gxf' => 'application/gxf', - 'gxt' => 'application/vnd.geonext', - 'gz' => 'application/x-gzip', - 'h' => 'text/x-c', - 'h261' => 'video/h261', - 'h263' => 'video/h263', - 'h264' => 'video/h264', - 'hal' => 'application/vnd.hal+xml', - 'hbci' => 'application/vnd.hbci', - 'hdf' => 'application/x-hdf', - 'hh' => 'text/x-c', - 'hlp' => 'application/winhlp', - 'hpgl' => 'application/vnd.hp-hpgl', - 'hpid' => 'application/vnd.hp-hpid', - 'hps' => 'application/vnd.hp-hps', - 'hqx' => 'application/mac-binhex40', - 'htke' => 'application/vnd.kenameaapp', - 'htm' => 'text/html', - 'html' => 'text/html', - 'hvd' => 'application/vnd.yamaha.hv-dic', - 'hvp' => 'application/vnd.yamaha.hv-voice', - 'hvs' => 'application/vnd.yamaha.hv-script', - 'i2g' => 'application/vnd.intergeo', - 'icc' => 'application/vnd.iccprofile', - 'ice' => 'x-conference/x-cooltalk', - 'icm' => 'application/vnd.iccprofile', - 'ico' => 'image/x-icon', - 'ics' => 'text/calendar', - 'ief' => 'image/ief', - 'ifb' => 'text/calendar', - 'ifm' => 'application/vnd.shana.informed.formdata', - 'iges' => 'model/iges', - 'igl' => 'application/vnd.igloader', - 'igm' => 'application/vnd.insors.igm', - 'igs' => 'model/iges', - 'igx' => 'application/vnd.micrografx.igx', - 'iif' => 'application/vnd.shana.informed.interchange', - 'imp' => 'application/vnd.accpac.simply.imp', - 'ims' => 'application/vnd.ms-ims', - 'in' => 'text/plain', - 'ink' => 'application/inkml+xml', - 'inkml' => 'application/inkml+xml', - 'install' => 'application/x-install-instructions', - 'iota' => 'application/vnd.astraea-software.iota', - 'ipfix' => 'application/ipfix', - 'ipk' => 'application/vnd.shana.informed.package', - 'irm' => 'application/vnd.ibm.rights-management', - 'irp' => 'application/vnd.irepository.package+xml', - 'iso' => 'application/x-iso9660-image', - 'itp' => 'application/vnd.shana.informed.formtemplate', - 'ivp' => 'application/vnd.immervision-ivp', - 'ivu' => 'application/vnd.immervision-ivu', - 'jad' => 'text/vnd.sun.j2me.app-descriptor', - 'jam' => 'application/vnd.jam', - 'jar' => 'application/java-archive', - 'java' => 'text/x-java-source', - 'jisp' => 'application/vnd.jisp', - 'jlt' => 'application/vnd.hp-jlyt', - 'jnlp' => 'application/x-java-jnlp-file', - 'joda' => 'application/vnd.joost.joda-archive', - 'jpe' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'jpgm' => 'video/jpm', - 'jpgv' => 'video/jpeg', - 'jpm' => 'video/jpm', - 'js' => 'application/javascript', - 'json' => 'application/json', - 'jsonml' => 'application/jsonml+json', - 'kar' => 'audio/midi', - 'karbon' => 'application/vnd.kde.karbon', - 'kfo' => 'application/vnd.kde.kformula', - 'kia' => 'application/vnd.kidspiration', - 'kml' => 'application/vnd.google-earth.kml+xml', - 'kmz' => 'application/vnd.google-earth.kmz', - 'kne' => 'application/vnd.kinar', - 'knp' => 'application/vnd.kinar', - 'kon' => 'application/vnd.kde.kontour', - 'kpr' => 'application/vnd.kde.kpresenter', - 'kpt' => 'application/vnd.kde.kpresenter', - 'kpxx' => 'application/vnd.ds-keypoint', - 'ksp' => 'application/vnd.kde.kspread', - 'ktr' => 'application/vnd.kahootz', - 'ktx' => 'image/ktx', - 'ktz' => 'application/vnd.kahootz', - 'kwd' => 'application/vnd.kde.kword', - 'kwt' => 'application/vnd.kde.kword', - 'lasxml' => 'application/vnd.las.las+xml', - 'latex' => 'application/x-latex', - 'lbd' => 'application/vnd.llamagraphics.life-balance.desktop', - 'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml', - 'les' => 'application/vnd.hhe.lesson-player', - 'lha' => 'application/x-lzh-compressed', - 'link66' => 'application/vnd.route66.link66+xml', - 'list' => 'text/plain', - 'list3820' => 'application/vnd.ibm.modcap', - 'listafp' => 'application/vnd.ibm.modcap', - 'lnk' => 'application/x-ms-shortcut', - 'log' => 'text/plain', - 'lostxml' => 'application/lost+xml', - 'lrf' => 'application/octet-stream', - 'lrm' => 'application/vnd.ms-lrm', - 'ltf' => 'application/vnd.frogans.ltf', - 'lvp' => 'audio/vnd.lucent.voice', - 'lwp' => 'application/vnd.lotus-wordpro', - 'lzh' => 'application/x-lzh-compressed', - 'm13' => 'application/x-msmediaview', - 'm14' => 'application/x-msmediaview', - 'm1v' => 'video/mpeg', - 'm21' => 'application/mp21', - 'm2a' => 'audio/mpeg', - 'm2v' => 'video/mpeg', - 'm3a' => 'audio/mpeg', - 'm3u' => 'audio/x-mpegurl', - 'm3u8' => 'application/vnd.apple.mpegurl', - 'm4a' => 'audio/mp4', - 'm4u' => 'video/vnd.mpegurl', - 'm4v' => 'video/x-m4v', - 'ma' => 'application/mathematica', - 'mads' => 'application/mads+xml', - 'mag' => 'application/vnd.ecowin.chart', - 'maker' => 'application/vnd.framemaker', - 'man' => 'text/troff', - 'mar' => 'application/octet-stream', - 'mathml' => 'application/mathml+xml', - 'mb' => 'application/mathematica', - 'mbk' => 'application/vnd.mobius.mbk', - 'mbox' => 'application/mbox', - 'mc1' => 'application/vnd.medcalcdata', - 'mcd' => 'application/vnd.mcd', - 'mcurl' => 'text/vnd.curl.mcurl', - 'mdb' => 'application/x-msaccess', - 'mdi' => 'image/vnd.ms-modi', - 'me' => 'text/troff', - 'mesh' => 'model/mesh', - 'meta4' => 'application/metalink4+xml', - 'metalink' => 'application/metalink+xml', - 'mets' => 'application/mets+xml', - 'mfm' => 'application/vnd.mfmp', - 'mft' => 'application/rpki-manifest', - 'mgp' => 'application/vnd.osgeo.mapguide.package', - 'mgz' => 'application/vnd.proteus.magazine', - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mie' => 'application/x-mie', - 'mif' => 'application/vnd.mif', - 'mime' => 'message/rfc822', - 'mj2' => 'video/mj2', - 'mjp2' => 'video/mj2', - 'mk3d' => 'video/x-matroska', - 'mka' => 'audio/x-matroska', - 'mks' => 'video/x-matroska', - 'mkv' => 'video/x-matroska', - 'mlp' => 'application/vnd.dolby.mlp', - 'mmd' => 'application/vnd.chipnuts.karaoke-mmd', - 'mmf' => 'application/vnd.smaf', - 'mmr' => 'image/vnd.fujixerox.edmics-mmr', - 'mng' => 'video/x-mng', - 'mny' => 'application/x-msmoney', - 'mobi' => 'application/x-mobipocket-ebook', - 'mods' => 'application/mods+xml', - 'mov' => 'video/quicktime', - 'movie' => 'video/x-sgi-movie', - 'mp2' => 'audio/mpeg', - 'mp21' => 'application/mp21', - 'mp2a' => 'audio/mpeg', - 'mp3' => 'audio/mpeg', - 'mp4' => 'video/mp4', - 'mp4a' => 'audio/mp4', - 'mp4s' => 'application/mp4', - 'mp4v' => 'video/mp4', - 'mpc' => 'application/vnd.mophun.certificate', - 'mpe' => 'video/mpeg', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpg4' => 'video/mp4', - 'mpga' => 'audio/mpeg', - 'mpkg' => 'application/vnd.apple.installer+xml', - 'mpm' => 'application/vnd.blueice.multipass', - 'mpn' => 'application/vnd.mophun.application', - 'mpp' => 'application/vnd.ms-project', - 'mpt' => 'application/vnd.ms-project', - 'mpy' => 'application/vnd.ibm.minipay', - 'mqy' => 'application/vnd.mobius.mqy', - 'mrc' => 'application/marc', - 'mrcx' => 'application/marcxml+xml', - 'ms' => 'text/troff', - 'mscml' => 'application/mediaservercontrol+xml', - 'mseed' => 'application/vnd.fdsn.mseed', - 'mseq' => 'application/vnd.mseq', - 'msf' => 'application/vnd.epson.msf', - 'msh' => 'model/mesh', - 'msi' => 'application/x-msdownload', - 'msl' => 'application/vnd.mobius.msl', - 'msty' => 'application/vnd.muvee.style', - 'mts' => 'model/vnd.mts', - 'mus' => 'application/vnd.musician', - 'musicxml' => 'application/vnd.recordare.musicxml+xml', - 'mvb' => 'application/x-msmediaview', - 'mwf' => 'application/vnd.mfer', - 'mxf' => 'application/mxf', - 'mxl' => 'application/vnd.recordare.musicxml', - 'mxml' => 'application/xv+xml', - 'mxs' => 'application/vnd.triscape.mxs', - 'mxu' => 'video/vnd.mpegurl', - 'n-gage' => 'application/vnd.nokia.n-gage.symbian.install', - 'n3' => 'text/n3', - 'nb' => 'application/mathematica', - 'nbp' => 'application/vnd.wolfram.player', - 'nc' => 'application/x-netcdf', - 'ncx' => 'application/x-dtbncx+xml', - 'nfo' => 'text/x-nfo', - 'ngdat' => 'application/vnd.nokia.n-gage.data', - 'nitf' => 'application/vnd.nitf', - 'nlu' => 'application/vnd.neurolanguage.nlu', - 'nml' => 'application/vnd.enliven', - 'nnd' => 'application/vnd.noblenet-directory', - 'nns' => 'application/vnd.noblenet-sealer', - 'nnw' => 'application/vnd.noblenet-web', - 'npx' => 'image/vnd.net-fpx', - 'nsc' => 'application/x-conference', - 'nsf' => 'application/vnd.lotus-notes', - 'ntf' => 'application/vnd.nitf', - 'nzb' => 'application/x-nzb', - 'oa2' => 'application/vnd.fujitsu.oasys2', - 'oa3' => 'application/vnd.fujitsu.oasys3', - 'oas' => 'application/vnd.fujitsu.oasys', - 'obd' => 'application/x-msbinder', - 'obj' => 'application/x-tgif', - 'oda' => 'application/oda', - 'odb' => 'application/vnd.oasis.opendocument.database', - 'odc' => 'application/vnd.oasis.opendocument.chart', - 'odf' => 'application/vnd.oasis.opendocument.formula', - 'odft' => 'application/vnd.oasis.opendocument.formula-template', - 'odg' => 'application/vnd.oasis.opendocument.graphics', - 'odi' => 'application/vnd.oasis.opendocument.image', - 'odm' => 'application/vnd.oasis.opendocument.text-master', - 'odp' => 'application/vnd.oasis.opendocument.presentation', - 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', - 'odt' => 'application/vnd.oasis.opendocument.text', - 'oga' => 'audio/ogg', - 'ogg' => 'audio/ogg', - 'ogv' => 'video/ogg', - 'ogx' => 'application/ogg', - 'omdoc' => 'application/omdoc+xml', - 'onepkg' => 'application/onenote', - 'onetmp' => 'application/onenote', - 'onetoc' => 'application/onenote', - 'onetoc2' => 'application/onenote', - 'opf' => 'application/oebps-package+xml', - 'opml' => 'text/x-opml', - 'oprc' => 'application/vnd.palm', - 'org' => 'application/vnd.lotus-organizer', - 'osf' => 'application/vnd.yamaha.openscoreformat', - 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml', - 'otc' => 'application/vnd.oasis.opendocument.chart-template', - 'otf' => 'application/x-font-otf', - 'otg' => 'application/vnd.oasis.opendocument.graphics-template', - 'oth' => 'application/vnd.oasis.opendocument.text-web', - 'oti' => 'application/vnd.oasis.opendocument.image-template', - 'otp' => 'application/vnd.oasis.opendocument.presentation-template', - 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', - 'ott' => 'application/vnd.oasis.opendocument.text-template', - 'oxps' => 'application/oxps', - 'oxt' => 'application/vnd.openofficeorg.extension', - 'p' => 'text/x-pascal', - 'p10' => 'application/pkcs10', - 'p12' => 'application/x-pkcs12', - 'p7b' => 'application/x-pkcs7-certificates', - 'p7c' => 'application/pkcs7-mime', - 'p7m' => 'application/pkcs7-mime', - 'p7r' => 'application/x-pkcs7-certreqresp', - 'p7s' => 'application/pkcs7-signature', - 'p8' => 'application/pkcs8', - 'pas' => 'text/x-pascal', - 'paw' => 'application/vnd.pawaafile', - 'pbd' => 'application/vnd.powerbuilder6', - 'pbm' => 'image/x-portable-bitmap', - 'pcap' => 'application/vnd.tcpdump.pcap', - 'pcf' => 'application/x-font-pcf', - 'pcl' => 'application/vnd.hp-pcl', - 'pclxl' => 'application/vnd.hp-pclxl', - 'pct' => 'image/x-pict', - 'pcurl' => 'application/vnd.curl.pcurl', - 'pcx' => 'image/x-pcx', - 'pdb' => 'application/vnd.palm', - 'pdf' => 'application/pdf', - 'pfa' => 'application/x-font-type1', - 'pfb' => 'application/x-font-type1', - 'pfm' => 'application/x-font-type1', - 'pfr' => 'application/font-tdpfr', - 'pfx' => 'application/x-pkcs12', - 'pgm' => 'image/x-portable-graymap', - 'pgn' => 'application/x-chess-pgn', - 'pgp' => 'application/pgp-encrypted', - 'php' => 'application/x-php', - 'php3' => 'application/x-php', - 'php4' => 'application/x-php', - 'php5' => 'application/x-php', - 'pic' => 'image/x-pict', - 'pkg' => 'application/octet-stream', - 'pki' => 'application/pkixcmp', - 'pkipath' => 'application/pkix-pkipath', - 'plb' => 'application/vnd.3gpp.pic-bw-large', - 'plc' => 'application/vnd.mobius.plc', - 'plf' => 'application/vnd.pocketlearn', - 'pls' => 'application/pls+xml', - 'pml' => 'application/vnd.ctc-posml', - 'png' => 'image/png', - 'pnm' => 'image/x-portable-anymap', - 'portpkg' => 'application/vnd.macports.portpkg', - 'pot' => 'application/vnd.ms-powerpoint', - 'potm' => 'application/vnd.ms-powerpoint.template.macroenabled.12', - 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', - 'ppam' => 'application/vnd.ms-powerpoint.addin.macroenabled.12', - 'ppd' => 'application/vnd.cups-ppd', - 'ppm' => 'image/x-portable-pixmap', - 'pps' => 'application/vnd.ms-powerpoint', - 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroenabled.12', - 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', - 'ppt' => 'application/vnd.ms-powerpoint', - 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroenabled.12', - 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'pqa' => 'application/vnd.palm', - 'prc' => 'application/x-mobipocket-ebook', - 'pre' => 'application/vnd.lotus-freelance', - 'prf' => 'application/pics-rules', - 'ps' => 'application/postscript', - 'psb' => 'application/vnd.3gpp.pic-bw-small', - 'psd' => 'image/vnd.adobe.photoshop', - 'psf' => 'application/x-font-linux-psf', - 'pskcxml' => 'application/pskc+xml', - 'ptid' => 'application/vnd.pvi.ptid1', - 'pub' => 'application/x-mspublisher', - 'pvb' => 'application/vnd.3gpp.pic-bw-var', - 'pwn' => 'application/vnd.3m.post-it-notes', - 'pya' => 'audio/vnd.ms-playready.media.pya', - 'pyv' => 'video/vnd.ms-playready.media.pyv', - 'qam' => 'application/vnd.epson.quickanime', - 'qbo' => 'application/vnd.intu.qbo', - 'qfx' => 'application/vnd.intu.qfx', - 'qps' => 'application/vnd.publishare-delta-tree', - 'qt' => 'video/quicktime', - 'qwd' => 'application/vnd.quark.quarkxpress', - 'qwt' => 'application/vnd.quark.quarkxpress', - 'qxb' => 'application/vnd.quark.quarkxpress', - 'qxd' => 'application/vnd.quark.quarkxpress', - 'qxl' => 'application/vnd.quark.quarkxpress', - 'qxt' => 'application/vnd.quark.quarkxpress', - 'ra' => 'audio/x-pn-realaudio', - 'ram' => 'audio/x-pn-realaudio', - 'rar' => 'application/x-rar-compressed', - 'ras' => 'image/x-cmu-raster', - 'rcprofile' => 'application/vnd.ipunplugged.rcprofile', - 'rdf' => 'application/rdf+xml', - 'rdz' => 'application/vnd.data-vision.rdz', - 'rep' => 'application/vnd.businessobjects', - 'res' => 'application/x-dtbresource+xml', - 'rgb' => 'image/x-rgb', - 'rif' => 'application/reginfo+xml', - 'rip' => 'audio/vnd.rip', - 'ris' => 'application/x-research-info-systems', - 'rl' => 'application/resource-lists+xml', - 'rlc' => 'image/vnd.fujixerox.edmics-rlc', - 'rld' => 'application/resource-lists-diff+xml', - 'rm' => 'application/vnd.rn-realmedia', - 'rmi' => 'audio/midi', - 'rmp' => 'audio/x-pn-realaudio-plugin', - 'rms' => 'application/vnd.jcp.javame.midlet-rms', - 'rmvb' => 'application/vnd.rn-realmedia-vbr', - 'rnc' => 'application/relax-ng-compact-syntax', - 'roa' => 'application/rpki-roa', - 'roff' => 'text/troff', - 'rp9' => 'application/vnd.cloanto.rp9', - 'rpss' => 'application/vnd.nokia.radio-presets', - 'rpst' => 'application/vnd.nokia.radio-preset', - 'rq' => 'application/sparql-query', - 'rs' => 'application/rls-services+xml', - 'rsd' => 'application/rsd+xml', - 'rss' => 'application/rss+xml', - 'rtf' => 'application/rtf', - 'rtx' => 'text/richtext', - 's' => 'text/x-asm', - 's3m' => 'audio/s3m', - 'saf' => 'application/vnd.yamaha.smaf-audio', - 'sbml' => 'application/sbml+xml', - 'sc' => 'application/vnd.ibm.secure-container', - 'scd' => 'application/x-msschedule', - 'scm' => 'application/vnd.lotus-screencam', - 'scq' => 'application/scvp-cv-request', - 'scs' => 'application/scvp-cv-response', - 'scurl' => 'text/vnd.curl.scurl', - 'sda' => 'application/vnd.stardivision.draw', - 'sdc' => 'application/vnd.stardivision.calc', - 'sdd' => 'application/vnd.stardivision.impress', - 'sdkd' => 'application/vnd.solent.sdkm+xml', - 'sdkm' => 'application/vnd.solent.sdkm+xml', - 'sdp' => 'application/sdp', - 'sdw' => 'application/vnd.stardivision.writer', - 'see' => 'application/vnd.seemail', - 'seed' => 'application/vnd.fdsn.seed', - 'sema' => 'application/vnd.sema', - 'semd' => 'application/vnd.semd', - 'semf' => 'application/vnd.semf', - 'ser' => 'application/java-serialized-object', - 'setpay' => 'application/set-payment-initiation', - 'setreg' => 'application/set-registration-initiation', - 'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data', - 'sfs' => 'application/vnd.spotfire.sfs', - 'sfv' => 'text/x-sfv', - 'sgi' => 'image/sgi', - 'sgl' => 'application/vnd.stardivision.writer-global', - 'sgm' => 'text/sgml', - 'sgml' => 'text/sgml', - 'sh' => 'application/x-sh', - 'shar' => 'application/x-shar', - 'shf' => 'application/shf+xml', - 'sid' => 'image/x-mrsid-image', - 'sig' => 'application/pgp-signature', - 'sil' => 'audio/silk', - 'silo' => 'model/mesh', - 'sis' => 'application/vnd.symbian.install', - 'sisx' => 'application/vnd.symbian.install', - 'sit' => 'application/x-stuffit', - 'sitx' => 'application/x-stuffitx', - 'skd' => 'application/vnd.koan', - 'skm' => 'application/vnd.koan', - 'skp' => 'application/vnd.koan', - 'skt' => 'application/vnd.koan', - 'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12', - 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', - 'slt' => 'application/vnd.epson.salt', - 'sm' => 'application/vnd.stepmania.stepchart', - 'smf' => 'application/vnd.stardivision.math', - 'smi' => 'application/smil+xml', - 'smil' => 'application/smil+xml', - 'smv' => 'video/x-smv', - 'smzip' => 'application/vnd.stepmania.package', - 'snd' => 'audio/basic', - 'snf' => 'application/x-font-snf', - 'so' => 'application/octet-stream', - 'spc' => 'application/x-pkcs7-certificates', - 'spf' => 'application/vnd.yamaha.smaf-phrase', - 'spl' => 'application/x-futuresplash', - 'spot' => 'text/vnd.in3d.spot', - 'spp' => 'application/scvp-vp-response', - 'spq' => 'application/scvp-vp-request', - 'spx' => 'audio/ogg', - 'sql' => 'application/x-sql', - 'src' => 'application/x-wais-source', - 'srt' => 'application/x-subrip', - 'sru' => 'application/sru+xml', - 'srx' => 'application/sparql-results+xml', - 'ssdl' => 'application/ssdl+xml', - 'sse' => 'application/vnd.kodak-descriptor', - 'ssf' => 'application/vnd.epson.ssf', - 'ssml' => 'application/ssml+xml', - 'st' => 'application/vnd.sailingtracker.track', - 'stc' => 'application/vnd.sun.xml.calc.template', - 'std' => 'application/vnd.sun.xml.draw.template', - 'stf' => 'application/vnd.wt.stf', - 'sti' => 'application/vnd.sun.xml.impress.template', - 'stk' => 'application/hyperstudio', - 'stl' => 'application/vnd.ms-pki.stl', - 'str' => 'application/vnd.pg.format', - 'stw' => 'application/vnd.sun.xml.writer.template', - 'sub' => 'text/vnd.dvb.subtitle', - 'sus' => 'application/vnd.sus-calendar', - 'susp' => 'application/vnd.sus-calendar', - 'sv4cpio' => 'application/x-sv4cpio', - 'sv4crc' => 'application/x-sv4crc', - 'svc' => 'application/vnd.dvb.service', - 'svd' => 'application/vnd.svd', - 'svg' => 'image/svg+xml', - 'svgz' => 'image/svg+xml', - 'swa' => 'application/x-director', - 'swf' => 'application/x-shockwave-flash', - 'swi' => 'application/vnd.aristanetworks.swi', - 'sxc' => 'application/vnd.sun.xml.calc', - 'sxd' => 'application/vnd.sun.xml.draw', - 'sxg' => 'application/vnd.sun.xml.writer.global', - 'sxi' => 'application/vnd.sun.xml.impress', - 'sxm' => 'application/vnd.sun.xml.math', - 'sxw' => 'application/vnd.sun.xml.writer', - 't' => 'text/troff', - 't3' => 'application/x-t3vm-image', - 'taglet' => 'application/vnd.mynfc', - 'tao' => 'application/vnd.tao.intent-module-archive', - 'tar' => 'application/x-tar', - 'tcap' => 'application/vnd.3gpp2.tcap', - 'tcl' => 'application/x-tcl', - 'teacher' => 'application/vnd.smart.teacher', - 'tei' => 'application/tei+xml', - 'teicorpus' => 'application/tei+xml', - 'tex' => 'application/x-tex', - 'texi' => 'application/x-texinfo', - 'texinfo' => 'application/x-texinfo', - 'text' => 'text/plain', - 'tfi' => 'application/thraud+xml', - 'tfm' => 'application/x-tex-tfm', - 'tga' => 'image/x-tga', - 'thmx' => 'application/vnd.ms-officetheme', - 'tif' => 'image/tiff', - 'tiff' => 'image/tiff', - 'tmo' => 'application/vnd.tmobile-livetv', - 'torrent' => 'application/x-bittorrent', - 'tpl' => 'application/vnd.groove-tool-template', - 'tpt' => 'application/vnd.trid.tpt', - 'tr' => 'text/troff', - 'tra' => 'application/vnd.trueapp', - 'trm' => 'application/x-msterminal', - 'tsd' => 'application/timestamped-data', - 'tsv' => 'text/tab-separated-values', - 'ttc' => 'application/x-font-ttf', - 'ttf' => 'application/x-font-ttf', - 'ttl' => 'text/turtle', - 'twd' => 'application/vnd.simtech-mindmapper', - 'twds' => 'application/vnd.simtech-mindmapper', - 'txd' => 'application/vnd.genomatix.tuxedo', - 'txf' => 'application/vnd.mobius.txf', - 'txt' => 'text/plain', - 'u32' => 'application/x-authorware-bin', - 'udeb' => 'application/x-debian-package', - 'ufd' => 'application/vnd.ufdl', - 'ufdl' => 'application/vnd.ufdl', - 'ulx' => 'application/x-glulx', - 'umj' => 'application/vnd.umajin', - 'unityweb' => 'application/vnd.unity', - 'uoml' => 'application/vnd.uoml+xml', - 'uri' => 'text/uri-list', - 'uris' => 'text/uri-list', - 'urls' => 'text/uri-list', - 'ustar' => 'application/x-ustar', - 'utz' => 'application/vnd.uiq.theme', - 'uu' => 'text/x-uuencode', - 'uva' => 'audio/vnd.dece.audio', - 'uvd' => 'application/vnd.dece.data', - 'uvf' => 'application/vnd.dece.data', - 'uvg' => 'image/vnd.dece.graphic', - 'uvh' => 'video/vnd.dece.hd', - 'uvi' => 'image/vnd.dece.graphic', - 'uvm' => 'video/vnd.dece.mobile', - 'uvp' => 'video/vnd.dece.pd', - 'uvs' => 'video/vnd.dece.sd', - 'uvt' => 'application/vnd.dece.ttml+xml', - 'uvu' => 'video/vnd.uvvu.mp4', - 'uvv' => 'video/vnd.dece.video', - 'uvva' => 'audio/vnd.dece.audio', - 'uvvd' => 'application/vnd.dece.data', - 'uvvf' => 'application/vnd.dece.data', - 'uvvg' => 'image/vnd.dece.graphic', - 'uvvh' => 'video/vnd.dece.hd', - 'uvvi' => 'image/vnd.dece.graphic', - 'uvvm' => 'video/vnd.dece.mobile', - 'uvvp' => 'video/vnd.dece.pd', - 'uvvs' => 'video/vnd.dece.sd', - 'uvvt' => 'application/vnd.dece.ttml+xml', - 'uvvu' => 'video/vnd.uvvu.mp4', - 'uvvv' => 'video/vnd.dece.video', - 'uvvx' => 'application/vnd.dece.unspecified', - 'uvvz' => 'application/vnd.dece.zip', - 'uvx' => 'application/vnd.dece.unspecified', - 'uvz' => 'application/vnd.dece.zip', - 'vcard' => 'text/vcard', - 'vcd' => 'application/x-cdlink', - 'vcf' => 'text/x-vcard', - 'vcg' => 'application/vnd.groove-vcard', - 'vcs' => 'text/x-vcalendar', - 'vcx' => 'application/vnd.vcx', - 'vis' => 'application/vnd.visionary', - 'viv' => 'video/vnd.vivo', - 'vob' => 'video/x-ms-vob', - 'vor' => 'application/vnd.stardivision.writer', - 'vox' => 'application/x-authorware-bin', - 'vrml' => 'model/vrml', - 'vsd' => 'application/vnd.visio', - 'vsf' => 'application/vnd.vsf', - 'vss' => 'application/vnd.visio', - 'vst' => 'application/vnd.visio', - 'vsw' => 'application/vnd.visio', - 'vtu' => 'model/vnd.vtu', - 'vxml' => 'application/voicexml+xml', - 'w3d' => 'application/x-director', - 'wad' => 'application/x-doom', - 'wav' => 'audio/x-wav', - 'wax' => 'audio/x-ms-wax', - 'wbmp' => 'image/vnd.wap.wbmp', - 'wbs' => 'application/vnd.criticaltools.wbs+xml', - 'wbxml' => 'application/vnd.wap.wbxml', - 'wcm' => 'application/vnd.ms-works', - 'wdb' => 'application/vnd.ms-works', - 'wdp' => 'image/vnd.ms-photo', - 'weba' => 'audio/webm', - 'webm' => 'video/webm', - 'webp' => 'image/webp', - 'wg' => 'application/vnd.pmi.widget', - 'wgt' => 'application/widget', - 'wks' => 'application/vnd.ms-works', - 'wm' => 'video/x-ms-wm', - 'wma' => 'audio/x-ms-wma', - 'wmd' => 'application/x-ms-wmd', - 'wmf' => 'application/x-msmetafile', - 'wml' => 'text/vnd.wap.wml', - 'wmlc' => 'application/vnd.wap.wmlc', - 'wmls' => 'text/vnd.wap.wmlscript', - 'wmlsc' => 'application/vnd.wap.wmlscriptc', - 'wmv' => 'video/x-ms-wmv', - 'wmx' => 'video/x-ms-wmx', - 'wmz' => 'application/x-msmetafile', - 'woff' => 'application/font-woff', - 'wpd' => 'application/vnd.wordperfect', - 'wpl' => 'application/vnd.ms-wpl', - 'wps' => 'application/vnd.ms-works', - 'wqd' => 'application/vnd.wqd', - 'wri' => 'application/x-mswrite', - 'wrl' => 'model/vrml', - 'wsdl' => 'application/wsdl+xml', - 'wspolicy' => 'application/wspolicy+xml', - 'wtb' => 'application/vnd.webturbo', - 'wvx' => 'video/x-ms-wvx', - 'x32' => 'application/x-authorware-bin', - 'x3d' => 'model/x3d+xml', - 'x3db' => 'model/x3d+binary', - 'x3dbz' => 'model/x3d+binary', - 'x3dv' => 'model/x3d+vrml', - 'x3dvz' => 'model/x3d+vrml', - 'x3dz' => 'model/x3d+xml', - 'xaml' => 'application/xaml+xml', - 'xap' => 'application/x-silverlight-app', - 'xar' => 'application/vnd.xara', - 'xbap' => 'application/x-ms-xbap', - 'xbd' => 'application/vnd.fujixerox.docuworks.binder', - 'xbm' => 'image/x-xbitmap', - 'xdf' => 'application/xcap-diff+xml', - 'xdm' => 'application/vnd.syncml.dm+xml', - 'xdp' => 'application/vnd.adobe.xdp+xml', - 'xdssc' => 'application/dssc+xml', - 'xdw' => 'application/vnd.fujixerox.docuworks', - 'xenc' => 'application/xenc+xml', - 'xer' => 'application/patch-ops-error+xml', - 'xfdf' => 'application/vnd.adobe.xfdf', - 'xfdl' => 'application/vnd.xfdl', - 'xht' => 'application/xhtml+xml', - 'xhtml' => 'application/xhtml+xml', - 'xhvml' => 'application/xv+xml', - 'xif' => 'image/vnd.xiff', - 'xla' => 'application/vnd.ms-excel', - 'xlam' => 'application/vnd.ms-excel.addin.macroenabled.12', - 'xlc' => 'application/vnd.ms-excel', - 'xlf' => 'application/x-xliff+xml', - 'xlm' => 'application/vnd.ms-excel', - 'xls' => 'application/vnd.ms-excel', - 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroenabled.12', - 'xlsm' => 'application/vnd.ms-excel.sheet.macroenabled.12', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'xlt' => 'application/vnd.ms-excel', - 'xltm' => 'application/vnd.ms-excel.template.macroenabled.12', - 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', - 'xlw' => 'application/vnd.ms-excel', - 'xm' => 'audio/xm', - 'xml' => 'application/xml', - 'xo' => 'application/vnd.olpc-sugar', - 'xop' => 'application/xop+xml', - 'xpi' => 'application/x-xpinstall', - 'xpl' => 'application/xproc+xml', - 'xpm' => 'image/x-xpixmap', - 'xpr' => 'application/vnd.is-xpr', - 'xps' => 'application/vnd.ms-xpsdocument', - 'xpw' => 'application/vnd.intercon.formnet', - 'xpx' => 'application/vnd.intercon.formnet', - 'xsl' => 'application/xml', - 'xslt' => 'application/xslt+xml', - 'xsm' => 'application/vnd.syncml+xml', - 'xspf' => 'application/xspf+xml', - 'xul' => 'application/vnd.mozilla.xul+xml', - 'xvm' => 'application/xv+xml', - 'xvml' => 'application/xv+xml', - 'xwd' => 'image/x-xwindowdump', - 'xyz' => 'chemical/x-xyz', - 'xz' => 'application/x-xz', - 'yang' => 'application/yang', - 'yin' => 'application/yin+xml', - 'z1' => 'application/x-zmachine', - 'z2' => 'application/x-zmachine', - 'z3' => 'application/x-zmachine', - 'z4' => 'application/x-zmachine', - 'z5' => 'application/x-zmachine', - 'z6' => 'application/x-zmachine', - 'z7' => 'application/x-zmachine', - 'z8' => 'application/x-zmachine', - 'zaz' => 'application/vnd.zzazz.deck+xml', - 'zip' => 'application/zip', - 'zir' => 'application/vnd.zul', - 'zirz' => 'application/vnd.zul', - 'zmm' => 'application/vnd.handheld-entertainment+xml', - '123' => 'application/vnd.lotus-1-2-3', -); diff --git a/lib/SwiftMailer/preferences.php b/lib/SwiftMailer/preferences.php deleted file mode 100644 index e519501..0000000 --- a/lib/SwiftMailer/preferences.php +++ /dev/null @@ -1,25 +0,0 @@ -setCharset('utf-8'); - -// Without these lines the default caching mechanism is "array" but this uses a lot of memory. -// If possible, use a disk cache to enable attaching large attachments etc. -// You can override the default temporary directory by setting the TMPDIR environment variable. -if (@is_writable($tmpDir = sys_get_temp_dir())) { - $preferences->setTempDir($tmpDir)->setCacheType('disk'); -} - -// this should only be done when Swiftmailer won't use the native QP content encoder -// see mime_deps.php -if (version_compare(phpversion(), '5.4.7', '<')) { - $preferences->setQPDotEscape(false); -} diff --git a/lib/SwiftMailer/swift_init.php b/lib/SwiftMailer/swift_init.php deleted file mode 100644 index ff71963..0000000 --- a/lib/SwiftMailer/swift_init.php +++ /dev/null @@ -1,28 +0,0 @@ - 'application/x-php', - 'php3' => 'application/x-php', - 'php4' => 'application/x-php', - 'php5' => 'application/x-php', - 'zip' => 'application/zip', - 'gif' => 'image/gif', - 'png' => 'image/png', - 'css' => 'text/css', - 'js' => 'text/javascript', - 'txt' => 'text/plain', - 'aif' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'avi' => 'video/avi', - 'bmp' => 'image/bmp', - 'bz2' => 'application/x-bz2', - 'csv' => 'text/csv', - 'dmg' => 'application/x-apple-diskimage', - 'doc' => 'application/msword', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'eml' => 'message/rfc822', - 'aps' => 'application/postscript', - 'exe' => 'application/x-ms-dos-executable', - 'flv' => 'video/x-flv', - 'gz' => 'application/x-gzip', - 'hqx' => 'application/stuffit', - 'htm' => 'text/html', - 'html' => 'text/html', - 'jar' => 'application/x-java-archive', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'm3u' => 'audio/x-mpegurl', - 'm4a' => 'audio/mp4', - 'mdb' => 'application/x-msaccess', - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mov' => 'video/quicktime', - 'mp3' => 'audio/mpeg', - 'mp4' => 'video/mp4', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'odg' => 'vnd.oasis.opendocument.graphics', - 'odp' => 'vnd.oasis.opendocument.presentation', - 'odt' => 'vnd.oasis.opendocument.text', - 'ods' => 'vnd.oasis.opendocument.spreadsheet', - 'ogg' => 'audio/ogg', - 'pdf' => 'application/pdf', - 'ppt' => 'application/vnd.ms-powerpoint', - 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'ps' => 'application/postscript', - 'rar' => 'application/x-rar-compressed', - 'rtf' => 'application/rtf', - 'tar' => 'application/x-tar', - 'sit' => 'application/x-stuffit', - 'svg' => 'image/svg+xml', - 'tif' => 'image/tiff', - 'tiff' => 'image/tiff', - 'ttf' => 'application/x-font-truetype', - 'vcf' => 'text/x-vcard', - 'wav' => 'audio/wav', - 'wma' => 'audio/x-ms-wma', - 'wmv' => 'audio/x-ms-wmv', - 'xls' => 'application/excel', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'xml' => 'application/xml', - ); - - // wrap array for generating file - foreach ($valid_mime_types_preset as $extension => $mime_type) { - // generate array for mimetype to extension resolver (only first match) - $valid_mime_types[$extension] = "'{$extension}' => '{$mime_type}'"; - } - - // collect extensions - $valid_extensions = array(); - - // all extensions from second match - foreach ($matches[2] as $i => $extensions) { - // explode multiple extensions from string - $extensions = explode(' ', strtolower($extensions)); - - // force array for foreach - if (!is_array($extensions)) { - $extensions = array($extensions); - } - - foreach ($extensions as $extension) { - // get mime type - $mime_type = $matches[1][$i]; - - // check if string length lower than 10 - if (strlen($extension) < 10) { - // add extension - $valid_extensions[] = $extension; - - if (!isset($valid_mime_types[$mime_type])) { - // generate array for mimetype to extension resolver (only first match) - $valid_mime_types[$extension] = "'{$extension}' => '{$mime_type}'"; - } - } - } - } - } - - $xml = simplexml_load_string($mime_xml); - - foreach ($xml as $node) { - // check if there is no pattern - if (!isset($node->glob['pattern'])) { - continue; - } - - // get all matching extensions from match - foreach ((array) $node->glob['pattern'] as $extension) { - // skip none glob extensions - if (strpos($extension, '.') === false) { - continue; - } - - // remove get only last part - $extension = explode('.', strtolower($extension)); - $extension = end($extension); - - // maximum length in database column - if (strlen($extension) <= 9) { - $valid_extensions[] = $extension; - } - } - - if (isset($node->glob['pattern'][0])) { - // mime type - $mime_type = strtolower((string) $node['type']); - - // get first extension - $extension = strtolower(trim($node->glob['ddpattern'][0], '*.')); - - // skip none glob extensions and check if string length between 1 and 10 - if (strpos($extension, '.') !== false || strlen($extension) < 1 || strlen($extension) > 9) { - continue; - } - - // check if string length lower than 10 - if (!isset($valid_mime_types[$mime_type])) { - // generate array for mimetype to extension resolver (only first match) - $valid_mime_types[$extension] = "'{$extension}' => '{$mime_type}'"; - } - } - } - - // full list of valid extensions only - $valid_mime_types = array_unique($valid_mime_types); - ksort($valid_mime_types); - - // combine mime types and extensions array - $output = "$preamble\$swift_mime_types = array(\n ".implode($valid_mime_types, ",\n ")."\n);"; - - // write mime_types.php config file - @file_put_contents('./mime_types.php', $output); -} - -generateUpToDateMimeArray(); diff --git a/lib/SwiftMailer/version.txt b/lib/SwiftMailer/version.txt deleted file mode 100644 index c0e6041..0000000 --- a/lib/SwiftMailer/version.txt +++ /dev/null @@ -1 +0,0 @@ -5.4.2 + fix для php 5.5, 5.6.x \ No newline at end of file diff --git a/lib/SymfonyMailer/composer.json b/lib/SymfonyMailer/composer.json new file mode 100644 index 0000000..0ac8212 --- /dev/null +++ b/lib/SymfonyMailer/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "symfony/mailer": "^7.3" + } +} diff --git a/lib/SymfonyMailer/composer.lock b/lib/SymfonyMailer/composer.lock new file mode 100644 index 0000000..5de47a9 --- /dev/null +++ b/lib/SymfonyMailer/composer.lock @@ -0,0 +1,1055 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "2d5a2f9fcd523772d2a79796574e1d9f", + "packages": [ + { + "name": "doctrine/lexer", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2024-02-05T11:56:58+00:00" + }, + { + "name": "egulias/email-validator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2025-03-06T22:45:56+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.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": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.3.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191", + "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-08-13T11:49:31+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "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": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/mailer", + "version": "v7.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "ab97ef2f7acf0216955f5845484235113047a31d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/ab97ef2f7acf0216955f5845484235113047a31d", + "reference": "ab97ef2f7acf0216955f5845484235113047a31d", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.2", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/mime": "^7.2", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/twig-bridge": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v7.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-09-17T05:51:54+00:00" + }, + { + "name": "symfony/mime", + "version": "v7.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/b1b828f69cbaf887fa835a091869e55df91d0e35", + "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<6.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v7.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-09-16T08:38:17+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-10T14:38:51+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "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" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "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": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-04-25T09:37:31+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" +} diff --git a/lib/SymfonyMailer/vendor/autoload.php b/lib/SymfonyMailer/vendor/autoload.php new file mode 100644 index 0000000..6919a54 --- /dev/null +++ b/lib/SymfonyMailer/vendor/autoload.php @@ -0,0 +1,22 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + + // PSR-4 + /** + * @var array> + */ + private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ + private $prefixDirsPsr4 = array(); + /** + * @var list + */ + private $fallbackDirsPsr4 = array(); + + // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ + private $prefixesPsr0 = array(); + /** + * @var list + */ + private $fallbackDirsPsr0 = array(); + + /** @var bool */ + private $useIncludePath = false; + + /** + * @var array + */ + private $classMap = array(); + + /** @var bool */ + private $classMapAuthoritative = false; + + /** + * @var array + */ + private $missingClasses = array(); + + /** @var string|null */ + private $apcuPrefix; + + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + /** + * @return array> + */ + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + /** + * @return list + */ + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + /** + * @return list + */ + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + /** + * @return array Array of classname => path + */ + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + * + * @return void + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void + */ + public function add($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + * + * @return void + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + * + * @return void + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + * + * @return void + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + * + * @return void + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return true|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + $includeFile = self::$includeFile; + $includeFile($file); + + return true; + } + + return null; + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } + + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } +} diff --git a/lib/SymfonyMailer/vendor/composer/InstalledVersions.php b/lib/SymfonyMailer/vendor/composer/InstalledVersions.php new file mode 100644 index 0000000..2052022 --- /dev/null +++ b/lib/SymfonyMailer/vendor/composer/InstalledVersions.php @@ -0,0 +1,396 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to + * @internal + */ + private static $selfDir = null; + + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool + */ + private static $installedIsLocalDir; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + + // when using reload, we disable the duplicate protection to ensure that self::$installed data is + // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not, + // so we have to assume it does not, and that may result in duplicate data being returned when listing + // all installed packages for example + self::$installedIsLocalDir = false; + } + + /** + * @return string + */ + private static function getSelfDir() + { + if (self::$selfDir === null) { + self::$selfDir = strtr(__DIR__, '\\', '/'); + } + + return self::$selfDir; + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + $copiedLocalDir = false; + + if (self::$canGetVendors) { + $selfDir = self::getSelfDir(); + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + $vendorDir = strtr($vendorDir, '\\', '/'); + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + self::$installedByVendor[$vendorDir] = $required; + $installed[] = $required; + if (self::$installed === null && $vendorDir.'/composer' === $selfDir) { + self::$installed = $required; + self::$installedIsLocalDir = true; + } + } + if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) { + $copiedLocalDir = true; + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array() && !$copiedLocalDir) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/lib/SymfonyMailer/vendor/composer/LICENSE b/lib/SymfonyMailer/vendor/composer/LICENSE new file mode 100644 index 0000000..f27399a --- /dev/null +++ b/lib/SymfonyMailer/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/lib/SymfonyMailer/vendor/composer/autoload_classmap.php b/lib/SymfonyMailer/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..9bb846c --- /dev/null +++ b/lib/SymfonyMailer/vendor/composer/autoload_classmap.php @@ -0,0 +1,11 @@ + $vendorDir . '/composer/InstalledVersions.php', + 'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', +); diff --git a/lib/SymfonyMailer/vendor/composer/autoload_files.php b/lib/SymfonyMailer/vendor/composer/autoload_files.php new file mode 100644 index 0000000..62eba4d --- /dev/null +++ b/lib/SymfonyMailer/vendor/composer/autoload_files.php @@ -0,0 +1,13 @@ + $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', + 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php', + '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', +); diff --git a/lib/SymfonyMailer/vendor/composer/autoload_namespaces.php b/lib/SymfonyMailer/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..15a2ff3 --- /dev/null +++ b/lib/SymfonyMailer/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + 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\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'), + 'Symfony\\Contracts\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher-contracts'), + 'Symfony\\Component\\Mime\\' => array($vendorDir . '/symfony/mime'), + 'Symfony\\Component\\Mailer\\' => array($vendorDir . '/symfony/mailer'), + 'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log/src'), + 'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'), + 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), + 'Egulias\\EmailValidator\\' => array($vendorDir . '/egulias/email-validator/src'), + 'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/src'), +); diff --git a/lib/SymfonyMailer/vendor/composer/autoload_real.php b/lib/SymfonyMailer/vendor/composer/autoload_real.php new file mode 100644 index 0000000..1c6a02f --- /dev/null +++ b/lib/SymfonyMailer/vendor/composer/autoload_real.php @@ -0,0 +1,50 @@ +register(true); + + $filesToLoad = \Composer\Autoload\ComposerStaticInit9386ebee37a2a4e9cdbcab7b77919bf5::$files; + $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; + } + }, null, null); + foreach ($filesToLoad as $fileIdentifier => $file) { + $requireFile($fileIdentifier, $file); + } + + return $loader; + } +} diff --git a/lib/SymfonyMailer/vendor/composer/autoload_static.php b/lib/SymfonyMailer/vendor/composer/autoload_static.php new file mode 100644 index 0000000..84ad3f0 --- /dev/null +++ b/lib/SymfonyMailer/vendor/composer/autoload_static.php @@ -0,0 +1,113 @@ + __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', + 'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php', + '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'S' => + array ( + 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33, + 'Symfony\\Polyfill\\Intl\\Idn\\' => 26, + 'Symfony\\Contracts\\Service\\' => 26, + 'Symfony\\Contracts\\EventDispatcher\\' => 34, + 'Symfony\\Component\\Mime\\' => 23, + 'Symfony\\Component\\Mailer\\' => 25, + 'Symfony\\Component\\EventDispatcher\\' => 34, + ), + 'P' => + array ( + 'Psr\\Log\\' => 8, + 'Psr\\EventDispatcher\\' => 20, + 'Psr\\Container\\' => 14, + ), + 'E' => + array ( + 'Egulias\\EmailValidator\\' => 23, + ), + 'D' => + array ( + 'Doctrine\\Common\\Lexer\\' => 22, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Symfony\\Polyfill\\Mbstring\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', + ), + 'Symfony\\Polyfill\\Intl\\Normalizer\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer', + ), + 'Symfony\\Polyfill\\Intl\\Idn\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-idn', + ), + 'Symfony\\Contracts\\Service\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/service-contracts', + ), + 'Symfony\\Contracts\\EventDispatcher\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/event-dispatcher-contracts', + ), + 'Symfony\\Component\\Mime\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/mime', + ), + 'Symfony\\Component\\Mailer\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/mailer', + ), + 'Symfony\\Component\\EventDispatcher\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/event-dispatcher', + ), + 'Psr\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/log/src', + ), + 'Psr\\EventDispatcher\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/event-dispatcher/src', + ), + 'Psr\\Container\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/container/src', + ), + 'Egulias\\EmailValidator\\' => + array ( + 0 => __DIR__ . '/..' . '/egulias/email-validator/src', + ), + 'Doctrine\\Common\\Lexer\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/lexer/src', + ), + ); + + 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 = ComposerStaticInit9386ebee37a2a4e9cdbcab7b77919bf5::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit9386ebee37a2a4e9cdbcab7b77919bf5::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit9386ebee37a2a4e9cdbcab7b77919bf5::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/lib/SymfonyMailer/vendor/composer/installed.json b/lib/SymfonyMailer/vendor/composer/installed.json new file mode 100644 index 0000000..0ada3f5 --- /dev/null +++ b/lib/SymfonyMailer/vendor/composer/installed.json @@ -0,0 +1,1084 @@ +{ + "packages": [ + { + "name": "doctrine/lexer", + "version": "3.0.1", + "version_normalized": "3.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" + }, + "time": "2024-02-05T11:56:58+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "install-path": "../doctrine/lexer" + }, + { + "name": "egulias/email-validator", + "version": "4.0.4", + "version_normalized": "4.0.4.0", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "time": "2025-03-06T22:45:56+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "install-path": "../egulias/email-validator" + }, + { + "name": "psr/container", + "version": "2.0.2", + "version_normalized": "2.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "time": "2021-11-05T16:47:00+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "install-path": "../psr/container" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "time": "2019-01-08T18:20:26+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "install-path": "../psr/event-dispatcher" + }, + { + "name": "psr/log", + "version": "3.0.2", + "version_normalized": "3.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "time": "2024-09-11T13:17:53+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "install-path": "../psr/log" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "version_normalized": "3.6.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "time": "2024-09-25T14:21:43+00:00", + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "function.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": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/deprecation-contracts" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.3.3", + "version_normalized": "7.3.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191", + "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" + }, + "time": "2025-08-13T11:49:31+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/event-dispatcher" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.6.0", + "version_normalized": "3.6.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "time": "2024-09-25T14:21:43+00:00", + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "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": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/event-dispatcher-contracts" + }, + { + "name": "symfony/mailer", + "version": "v7.3.4", + "version_normalized": "7.3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "ab97ef2f7acf0216955f5845484235113047a31d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/ab97ef2f7acf0216955f5845484235113047a31d", + "reference": "ab97ef2f7acf0216955f5845484235113047a31d", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.2", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/mime": "^7.2", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/twig-bridge": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0" + }, + "time": "2025-09-17T05:51:54+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v7.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/mailer" + }, + { + "name": "symfony/mime", + "version": "v7.3.4", + "version_normalized": "7.3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/b1b828f69cbaf887fa835a091869e55df91d0e35", + "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<6.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3" + }, + "time": "2025-09-16T08:38:17+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v7.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/mime" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.33.0", + "version_normalized": "1.33.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "time": "2024-09-10T14:38:51+00:00", + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-intl-idn" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.33.0", + "version_normalized": "1.33.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "time": "2024-09-09T11:45:10+00:00", + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-intl-normalizer" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.33.0", + "version_normalized": "1.33.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "time": "2024-12-23T08:48:59+00:00", + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "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" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-mbstring" + }, + { + "name": "symfony/service-contracts", + "version": "v3.6.0", + "version_normalized": "3.6.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "time": "2025-04-25T09:37:31+00:00", + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "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": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/service-contracts" + } + ], + "dev": true, + "dev-package-names": [] +} diff --git a/lib/SymfonyMailer/vendor/composer/installed.php b/lib/SymfonyMailer/vendor/composer/installed.php new file mode 100644 index 0000000..c208ea9 --- /dev/null +++ b/lib/SymfonyMailer/vendor/composer/installed.php @@ -0,0 +1,161 @@ + array( + 'name' => '__root__', + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'reference' => null, + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => true, + ), + 'versions' => array( + '__root__' => array( + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'reference' => null, + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'doctrine/lexer' => array( + 'pretty_version' => '3.0.1', + 'version' => '3.0.1.0', + 'reference' => '31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd', + 'type' => 'library', + 'install_path' => __DIR__ . '/../doctrine/lexer', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'egulias/email-validator' => array( + 'pretty_version' => '4.0.4', + 'version' => '4.0.4.0', + 'reference' => 'd42c8731f0624ad6bdc8d3e5e9a4524f68801cfa', + 'type' => 'library', + 'install_path' => __DIR__ . '/../egulias/email-validator', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/container' => array( + 'pretty_version' => '2.0.2', + 'version' => '2.0.2.0', + 'reference' => 'c71ecc56dfe541dbd90c5360474fbc405f8d5963', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/container', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/event-dispatcher' => array( + 'pretty_version' => '1.0.0', + 'version' => '1.0.0.0', + 'reference' => 'dbefd12671e8a14ec7f180cab83036ed26714bb0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/event-dispatcher', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/event-dispatcher-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'psr/log' => array( + 'pretty_version' => '3.0.2', + 'version' => '3.0.2.0', + 'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/log', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/deprecation-contracts' => array( + 'pretty_version' => 'v3.6.0', + 'version' => '3.6.0.0', + 'reference' => '63afe740e99a13ba87ec199bb07bbdee937a5b62', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/event-dispatcher' => array( + 'pretty_version' => 'v7.3.3', + 'version' => '7.3.3.0', + 'reference' => 'b7dc69e71de420ac04bc9ab830cf3ffebba48191', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/event-dispatcher', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/event-dispatcher-contracts' => array( + 'pretty_version' => 'v3.6.0', + 'version' => '3.6.0.0', + 'reference' => '59eb412e93815df44f05f342958efa9f46b1e586', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/event-dispatcher-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/event-dispatcher-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '2.0|3.0', + ), + ), + 'symfony/mailer' => array( + 'pretty_version' => 'v7.3.4', + 'version' => '7.3.4.0', + 'reference' => 'ab97ef2f7acf0216955f5845484235113047a31d', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/mailer', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/mime' => array( + 'pretty_version' => 'v7.3.4', + 'version' => '7.3.4.0', + 'reference' => 'b1b828f69cbaf887fa835a091869e55df91d0e35', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/mime', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-intl-idn' => array( + 'pretty_version' => 'v1.33.0', + 'version' => '1.33.0.0', + 'reference' => '9614ac4d8061dc257ecc64cba1b140873dce8ad3', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-intl-normalizer' => array( + 'pretty_version' => 'v1.33.0', + 'version' => '1.33.0.0', + 'reference' => '3833d7255cc303546435cb650316bff708a1c75c', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-mbstring' => array( + 'pretty_version' => 'v1.33.0', + 'version' => '1.33.0.0', + 'reference' => '6d857f4d76bd4b343eac26d6b539585d2bc56493', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/service-contracts' => array( + 'pretty_version' => 'v3.6.0', + 'version' => '3.6.0.0', + 'reference' => 'f021b05a130d35510bd6b25fe9053c2a8a15d5d4', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/service-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/lib/SymfonyMailer/vendor/composer/platform_check.php b/lib/SymfonyMailer/vendor/composer/platform_check.php new file mode 100644 index 0000000..d32d90c --- /dev/null +++ b/lib/SymfonyMailer/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 80200)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/lib/SymfonyMailer/vendor/doctrine/lexer/LICENSE b/lib/SymfonyMailer/vendor/doctrine/lexer/LICENSE new file mode 100644 index 0000000..e8fdec4 --- /dev/null +++ b/lib/SymfonyMailer/vendor/doctrine/lexer/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2006-2018 Doctrine Project + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/lib/SymfonyMailer/vendor/doctrine/lexer/README.md b/lib/SymfonyMailer/vendor/doctrine/lexer/README.md new file mode 100644 index 0000000..784f2a2 --- /dev/null +++ b/lib/SymfonyMailer/vendor/doctrine/lexer/README.md @@ -0,0 +1,9 @@ +# Doctrine Lexer + +[![Build Status](https://github.com/doctrine/lexer/workflows/Continuous%20Integration/badge.svg)](https://github.com/doctrine/lexer/actions) + +Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers. + +This lexer is used in Doctrine Annotations and in Doctrine ORM (DQL). + +https://www.doctrine-project.org/projects/lexer.html diff --git a/lib/SymfonyMailer/vendor/doctrine/lexer/UPGRADE.md b/lib/SymfonyMailer/vendor/doctrine/lexer/UPGRADE.md new file mode 100644 index 0000000..1933fcb --- /dev/null +++ b/lib/SymfonyMailer/vendor/doctrine/lexer/UPGRADE.md @@ -0,0 +1,22 @@ +Note about upgrading: Doctrine uses static and runtime mechanisms to raise +awareness about deprecated code. + +- Use of `@deprecated` docblock that is detected by IDEs (like PHPStorm) or + Static Analysis tools (like Psalm, phpstan) +- Use of our low-overhead runtime deprecation API, details: + https://github.com/doctrine/deprecations/ + +# Upgrade to 3.0.0 + +`Doctrine\Common\Lexer\Token` no longer implements `ArrayAccess`. +Parameter type declarations have been added to +`Doctrine\Common\Lexer\AbstractLexer` and `Doctrine\Common\Lexer\Token`. +You should add both parameter type declarations and return type declarations to +your lexers, based on the `@return` phpdoc. + +# Upgrade to 2.0.0 + +`AbstractLexer::glimpse()` and `AbstractLexer::peek()` now return +instances of `Doctrine\Common\Lexer\Token`, which is an array-like class +Using it as an array is deprecated in favor of using properties of that class. +Using `count()` on it is deprecated with no replacement. diff --git a/lib/SymfonyMailer/vendor/doctrine/lexer/composer.json b/lib/SymfonyMailer/vendor/doctrine/lexer/composer.json new file mode 100644 index 0000000..995dafa --- /dev/null +++ b/lib/SymfonyMailer/vendor/doctrine/lexer/composer.json @@ -0,0 +1,55 @@ +{ + "name": "doctrine/lexer", + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "license": "MIT", + "type": "library", + "keywords": [ + "php", + "parser", + "lexer", + "annotations", + "docblock" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Doctrine\\Tests\\Common\\Lexer\\": "tests" + } + }, + "config": { + "allow-plugins": { + "composer/package-versions-deprecated": true, + "dealerdirect/phpcodesniffer-composer-installer": true + }, + "sort-packages": true + } +} diff --git a/lib/SymfonyMailer/vendor/doctrine/lexer/src/AbstractLexer.php b/lib/SymfonyMailer/vendor/doctrine/lexer/src/AbstractLexer.php new file mode 100644 index 0000000..2436885 --- /dev/null +++ b/lib/SymfonyMailer/vendor/doctrine/lexer/src/AbstractLexer.php @@ -0,0 +1,328 @@ +> + */ + private array $tokens = []; + + /** + * Current lexer position in input string. + */ + private int $position = 0; + + /** + * Current peek of current lexer position. + */ + private int $peek = 0; + + /** + * The next token in the input. + * + * @var Token|null + */ + public Token|null $lookahead; + + /** + * The last matched/seen token. + * + * @var Token|null + */ + public Token|null $token; + + /** + * Composed regex for input parsing. + * + * @var non-empty-string|null + */ + private string|null $regex = null; + + /** + * Sets the input data to be tokenized. + * + * The Lexer is immediately reset and the new input tokenized. + * Any unprocessed tokens from any previous input are lost. + * + * @param string $input The input to be tokenized. + * + * @return void + */ + public function setInput(string $input) + { + $this->input = $input; + $this->tokens = []; + + $this->reset(); + $this->scan($input); + } + + /** + * Resets the lexer. + * + * @return void + */ + public function reset() + { + $this->lookahead = null; + $this->token = null; + $this->peek = 0; + $this->position = 0; + } + + /** + * Resets the peek pointer to 0. + * + * @return void + */ + public function resetPeek() + { + $this->peek = 0; + } + + /** + * Resets the lexer position on the input to the given position. + * + * @param int $position Position to place the lexical scanner. + * + * @return void + */ + public function resetPosition(int $position = 0) + { + $this->position = $position; + } + + /** + * Retrieve the original lexer's input until a given position. + * + * @return string + */ + public function getInputUntilPosition(int $position) + { + return substr($this->input, 0, $position); + } + + /** + * Checks whether a given token matches the current lookahead. + * + * @param T $type + * + * @return bool + * + * @psalm-assert-if-true !=null $this->lookahead + */ + public function isNextToken(int|string|UnitEnum $type) + { + return $this->lookahead !== null && $this->lookahead->isA($type); + } + + /** + * Checks whether any of the given tokens matches the current lookahead. + * + * @param list $types + * + * @return bool + * + * @psalm-assert-if-true !=null $this->lookahead + */ + public function isNextTokenAny(array $types) + { + return $this->lookahead !== null && $this->lookahead->isA(...$types); + } + + /** + * Moves to the next token in the input string. + * + * @return bool + * + * @psalm-assert-if-true !null $this->lookahead + */ + public function moveNext() + { + $this->peek = 0; + $this->token = $this->lookahead; + $this->lookahead = isset($this->tokens[$this->position]) + ? $this->tokens[$this->position++] : null; + + return $this->lookahead !== null; + } + + /** + * Tells the lexer to skip input tokens until it sees a token with the given value. + * + * @param T $type The token type to skip until. + * + * @return void + */ + public function skipUntil(int|string|UnitEnum $type) + { + while ($this->lookahead !== null && ! $this->lookahead->isA($type)) { + $this->moveNext(); + } + } + + /** + * Checks if given value is identical to the given token. + * + * @return bool + */ + public function isA(string $value, int|string|UnitEnum $token) + { + return $this->getType($value) === $token; + } + + /** + * Moves the lookahead token forward. + * + * @return Token|null The next token or NULL if there are no more tokens ahead. + */ + public function peek() + { + if (isset($this->tokens[$this->position + $this->peek])) { + return $this->tokens[$this->position + $this->peek++]; + } + + return null; + } + + /** + * Peeks at the next token, returns it and immediately resets the peek. + * + * @return Token|null The next token or NULL if there are no more tokens ahead. + */ + public function glimpse() + { + $peek = $this->peek(); + $this->peek = 0; + + return $peek; + } + + /** + * Scans the input string for tokens. + * + * @param string $input A query string. + * + * @return void + */ + protected function scan(string $input) + { + if (! isset($this->regex)) { + $this->regex = sprintf( + '/(%s)|%s/%s', + implode(')|(', $this->getCatchablePatterns()), + implode('|', $this->getNonCatchablePatterns()), + $this->getModifiers(), + ); + } + + $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE; + $matches = preg_split($this->regex, $input, -1, $flags); + + if ($matches === false) { + // Work around https://bugs.php.net/78122 + $matches = [[$input, 0]]; + } + + foreach ($matches as $match) { + // Must remain before 'value' assignment since it can change content + $firstMatch = $match[0]; + $type = $this->getType($firstMatch); + + $this->tokens[] = new Token( + $firstMatch, + $type, + $match[1], + ); + } + } + + /** + * Gets the literal for a given token. + * + * @param T $token + * + * @return int|string + */ + public function getLiteral(int|string|UnitEnum $token) + { + if ($token instanceof UnitEnum) { + return $token::class . '::' . $token->name; + } + + $className = static::class; + + $reflClass = new ReflectionClass($className); + $constants = $reflClass->getConstants(); + + foreach ($constants as $name => $value) { + if ($value === $token) { + return $className . '::' . $name; + } + } + + return $token; + } + + /** + * Regex modifiers + * + * @return string + */ + protected function getModifiers() + { + return 'iu'; + } + + /** + * Lexical catchable patterns. + * + * @return string[] + */ + abstract protected function getCatchablePatterns(); + + /** + * Lexical non-catchable patterns. + * + * @return string[] + */ + abstract protected function getNonCatchablePatterns(); + + /** + * Retrieve token type. Also processes the token value if necessary. + * + * @return T|null + * + * @param-out V $value + */ + abstract protected function getType(string &$value); +} diff --git a/lib/SymfonyMailer/vendor/doctrine/lexer/src/Token.php b/lib/SymfonyMailer/vendor/doctrine/lexer/src/Token.php new file mode 100644 index 0000000..b6df694 --- /dev/null +++ b/lib/SymfonyMailer/vendor/doctrine/lexer/src/Token.php @@ -0,0 +1,56 @@ +value = $value; + $this->type = $type; + $this->position = $position; + } + + /** @param T ...$types */ + public function isA(...$types): bool + { + return in_array($this->type, $types, true); + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/CONTRIBUTING.md b/lib/SymfonyMailer/vendor/egulias/email-validator/CONTRIBUTING.md new file mode 100644 index 0000000..907bc2c --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/CONTRIBUTING.md @@ -0,0 +1,153 @@ +# Contributing + +When contributing to this repository make sure to follow the Pull request process below. +Reduce to the minimum 3rd party dependencies. + +Please note we have a [code of conduct](#Code of Conduct), please follow it in all your interactions with the project. + +## Pull Request Process + +When doing a PR to v2 remember that you also have to do the PR port to v3, or tests confirming the bug is not reproducible. + +1. Supported version is v3. If you are fixing a bug in v2, please port to v3 +2. Use the title as a brief description of the changes +3. Describe the changes you are proposing + 1. If adding an extra validation state the benefits of adding it and the problem is solving + 2. Document in the readme, by adding it to the list +4. Provide appropriate tests for the code you are submitting: aim to keep the existing coverage percentage. +5. Add your Twitter handle (if you have) so we can thank you there. + +## License +By contributing, you agree that your contributions will be licensed under its MIT License. + +## Code of Conduct + +### Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +### Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +### Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +### Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +### Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at . +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +#### Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +#### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +#### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +#### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +#### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +### Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available +at [https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/LICENSE b/lib/SymfonyMailer/vendor/egulias/email-validator/LICENSE new file mode 100644 index 0000000..b1902a4 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013-2023 Eduardo Gulias Davis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/composer.json b/lib/SymfonyMailer/vendor/egulias/email-validator/composer.json new file mode 100644 index 0000000..bf1b3f4 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/composer.json @@ -0,0 +1,37 @@ +{ + "name": "egulias/email-validator", + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": ["email", "validation", "validator", "emailvalidation", "emailvalidator"], + "license": "MIT", + "authors": [ + {"name": "Eduardo Gulias Davis"} + ], + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "require": { + "php": ">=8.1", + "doctrine/lexer": "^2.0 || ^3.0", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Egulias\\EmailValidator\\Tests\\": "tests" + } + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/EmailLexer.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/EmailLexer.php new file mode 100644 index 0000000..a7fdc2d --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/EmailLexer.php @@ -0,0 +1,329 @@ + */ +class EmailLexer extends AbstractLexer +{ + //ASCII values + public const S_EMPTY = -1; + public const C_NUL = 0; + public const S_HTAB = 9; + public const S_LF = 10; + public const S_CR = 13; + public const S_SP = 32; + public const EXCLAMATION = 33; + public const S_DQUOTE = 34; + public const NUMBER_SIGN = 35; + public const DOLLAR = 36; + public const PERCENTAGE = 37; + public const AMPERSAND = 38; + public const S_SQUOTE = 39; + public const S_OPENPARENTHESIS = 40; + public const S_CLOSEPARENTHESIS = 41; + public const ASTERISK = 42; + public const S_PLUS = 43; + public const S_COMMA = 44; + public const S_HYPHEN = 45; + public const S_DOT = 46; + public const S_SLASH = 47; + public const S_COLON = 58; + public const S_SEMICOLON = 59; + public const S_LOWERTHAN = 60; + public const S_EQUAL = 61; + public const S_GREATERTHAN = 62; + public const QUESTIONMARK = 63; + public const S_AT = 64; + public const S_OPENBRACKET = 91; + public const S_BACKSLASH = 92; + public const S_CLOSEBRACKET = 93; + public const CARET = 94; + public const S_UNDERSCORE = 95; + public const S_BACKTICK = 96; + public const S_OPENCURLYBRACES = 123; + public const S_PIPE = 124; + public const S_CLOSECURLYBRACES = 125; + public const S_TILDE = 126; + public const C_DEL = 127; + public const INVERT_QUESTIONMARK = 168; + public const INVERT_EXCLAMATION = 173; + public const GENERIC = 300; + public const S_IPV6TAG = 301; + public const INVALID = 302; + public const CRLF = 1310; + public const S_DOUBLECOLON = 5858; + public const ASCII_INVALID_FROM = 127; + public const ASCII_INVALID_TO = 199; + + /** + * US-ASCII visible characters not valid for atext (@link http://tools.ietf.org/html/rfc5322#section-3.2.3) + * + * @var array + */ + protected $charValue = [ + '{' => self::S_OPENCURLYBRACES, + '}' => self::S_CLOSECURLYBRACES, + '(' => self::S_OPENPARENTHESIS, + ')' => self::S_CLOSEPARENTHESIS, + '<' => self::S_LOWERTHAN, + '>' => self::S_GREATERTHAN, + '[' => self::S_OPENBRACKET, + ']' => self::S_CLOSEBRACKET, + ':' => self::S_COLON, + ';' => self::S_SEMICOLON, + '@' => self::S_AT, + '\\' => self::S_BACKSLASH, + '/' => self::S_SLASH, + ',' => self::S_COMMA, + '.' => self::S_DOT, + "'" => self::S_SQUOTE, + "`" => self::S_BACKTICK, + '"' => self::S_DQUOTE, + '-' => self::S_HYPHEN, + '::' => self::S_DOUBLECOLON, + ' ' => self::S_SP, + "\t" => self::S_HTAB, + "\r" => self::S_CR, + "\n" => self::S_LF, + "\r\n" => self::CRLF, + 'IPv6' => self::S_IPV6TAG, + '' => self::S_EMPTY, + '\0' => self::C_NUL, + '*' => self::ASTERISK, + '!' => self::EXCLAMATION, + '&' => self::AMPERSAND, + '^' => self::CARET, + '$' => self::DOLLAR, + '%' => self::PERCENTAGE, + '~' => self::S_TILDE, + '|' => self::S_PIPE, + '_' => self::S_UNDERSCORE, + '=' => self::S_EQUAL, + '+' => self::S_PLUS, + '¿' => self::INVERT_QUESTIONMARK, + '?' => self::QUESTIONMARK, + '#' => self::NUMBER_SIGN, + '¡' => self::INVERT_EXCLAMATION, + ]; + + public const INVALID_CHARS_REGEX = "/[^\p{S}\p{C}\p{Cc}]+/iu"; + + public const VALID_UTF8_REGEX = '/\p{Cc}+/u'; + + public const CATCHABLE_PATTERNS = [ + '[a-zA-Z]+[46]?', //ASCII and domain literal + '[^\x00-\x7F]', //UTF-8 + '[0-9]+', + '\r\n', + '::', + '\s+?', + '.', + ]; + + public const NON_CATCHABLE_PATTERNS = [ + '[\xA0-\xff]+', + ]; + + public const MODIFIERS = 'iu'; + + /** @var bool */ + protected $hasInvalidTokens = false; + + /** + * @var Token + */ + protected Token $previous; + + /** + * The last matched/seen token. + * + * @var Token + */ + public Token $current; + + /** + * @var Token + */ + private Token $nullToken; + + /** @var string */ + private $accumulator = ''; + + /** @var bool */ + private $hasToRecord = false; + + public function __construct() + { + /** @var Token $nullToken */ + $nullToken = new Token('', self::S_EMPTY, 0); + $this->nullToken = $nullToken; + + $this->current = $this->previous = $this->nullToken; + $this->lookahead = null; + } + + public function reset(): void + { + $this->hasInvalidTokens = false; + parent::reset(); + $this->current = $this->previous = $this->nullToken; + } + + /** + * @param int $type + * @throws \UnexpectedValueException + * @return boolean + * + */ + public function find($type): bool + { + $search = clone $this; + $search->skipUntil($type); + + if (!$search->lookahead) { + throw new \UnexpectedValueException($type . ' not found'); + } + return true; + } + + /** + * moveNext + * + * @return boolean + */ + public function moveNext(): bool + { + if ($this->hasToRecord && $this->previous === $this->nullToken) { + $this->accumulator .= $this->current->value; + } + + $this->previous = $this->current; + + if ($this->lookahead === null) { + $this->lookahead = $this->nullToken; + } + + $hasNext = parent::moveNext(); + $this->current = $this->token ?? $this->nullToken; + + if ($this->hasToRecord) { + $this->accumulator .= $this->current->value; + } + + return $hasNext; + } + + /** + * Retrieve token type. Also processes the token value if necessary. + * + * @param string $value + * @throws \InvalidArgumentException + * @return integer + */ + protected function getType(&$value): int + { + $encoded = $value; + + if (mb_detect_encoding($value, 'auto', true) !== 'UTF-8') { + $encoded = mb_convert_encoding($value, 'UTF-8', 'Windows-1252'); + } + + if ($this->isValid($encoded)) { + return $this->charValue[$encoded]; + } + + if ($this->isNullType($encoded)) { + return self::C_NUL; + } + + if ($this->isInvalidChar($encoded)) { + $this->hasInvalidTokens = true; + return self::INVALID; + } + + return self::GENERIC; + } + + protected function isValid(string $value): bool + { + return isset($this->charValue[$value]); + } + + protected function isNullType(string $value): bool + { + return $value === "\0"; + } + + protected function isInvalidChar(string $value): bool + { + return !preg_match(self::INVALID_CHARS_REGEX, $value); + } + + protected function isUTF8Invalid(string $value): bool + { + return preg_match(self::VALID_UTF8_REGEX, $value) !== false; + } + + public function hasInvalidTokens(): bool + { + return $this->hasInvalidTokens; + } + + /** + * getPrevious + * + * @return Token + */ + public function getPrevious(): Token + { + return $this->previous; + } + + /** + * Lexical catchable patterns. + * + * @return string[] + */ + protected function getCatchablePatterns(): array + { + return self::CATCHABLE_PATTERNS; + } + + /** + * Lexical non-catchable patterns. + * + * @return string[] + */ + protected function getNonCatchablePatterns(): array + { + return self::NON_CATCHABLE_PATTERNS; + } + + protected function getModifiers(): string + { + return self::MODIFIERS; + } + + public function getAccumulatedValues(): string + { + return $this->accumulator; + } + + public function startRecording(): void + { + $this->hasToRecord = true; + } + + public function stopRecording(): void + { + $this->hasToRecord = false; + } + + public function clearRecorded(): void + { + $this->accumulator = ''; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/EmailParser.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/EmailParser.php new file mode 100644 index 0000000..fc449c7 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/EmailParser.php @@ -0,0 +1,90 @@ +addLongEmailWarning($this->localPart, $this->domainPart); + + return $result; + } + + protected function preLeftParsing(): Result + { + if (!$this->hasAtToken()) { + return new InvalidEmail(new NoLocalPart(), $this->lexer->current->value); + } + return new ValidEmail(); + } + + protected function parseLeftFromAt(): Result + { + return $this->processLocalPart(); + } + + protected function parseRightFromAt(): Result + { + return $this->processDomainPart(); + } + + private function processLocalPart(): Result + { + $localPartParser = new LocalPart($this->lexer); + $localPartResult = $localPartParser->parse(); + $this->localPart = $localPartParser->localPart(); + $this->warnings = [...$localPartParser->getWarnings(), ...$this->warnings]; + + return $localPartResult; + } + + private function processDomainPart(): Result + { + $domainPartParser = new DomainPart($this->lexer); + $domainPartResult = $domainPartParser->parse(); + $this->domainPart = $domainPartParser->domainPart(); + $this->warnings = [...$domainPartParser->getWarnings(), ...$this->warnings]; + + return $domainPartResult; + } + + public function getDomainPart(): string + { + return $this->domainPart; + } + + public function getLocalPart(): string + { + return $this->localPart; + } + + private function addLongEmailWarning(string $localPart, string $parsedDomainPart): void + { + if (strlen($localPart . '@' . $parsedDomainPart) > self::EMAIL_MAX_LENGTH) { + $this->warnings[EmailTooLong::CODE] = new EmailTooLong(); + } + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/EmailValidator.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/EmailValidator.php new file mode 100644 index 0000000..5a2e5c8 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/EmailValidator.php @@ -0,0 +1,67 @@ +lexer = new EmailLexer(); + } + + /** + * @param string $email + * @param EmailValidation $emailValidation + * @return bool + */ + public function isValid(string $email, EmailValidation $emailValidation) + { + $isValid = $emailValidation->isValid($email, $this->lexer); + $this->warnings = $emailValidation->getWarnings(); + $this->error = $emailValidation->getError(); + + return $isValid; + } + + /** + * @return boolean + */ + public function hasWarnings() + { + return !empty($this->warnings); + } + + /** + * @return array + */ + public function getWarnings() + { + return $this->warnings; + } + + /** + * @return InvalidEmail|null + */ + public function getError() + { + return $this->error; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/MessageIDParser.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/MessageIDParser.php new file mode 100644 index 0000000..35bd0a7 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/MessageIDParser.php @@ -0,0 +1,91 @@ +addLongEmailWarning($this->idLeft, $this->idRight); + + return $result; + } + + protected function preLeftParsing(): Result + { + if (!$this->hasAtToken()) { + return new InvalidEmail(new NoLocalPart(), $this->lexer->current->value); + } + return new ValidEmail(); + } + + protected function parseLeftFromAt(): Result + { + return $this->processIDLeft(); + } + + protected function parseRightFromAt(): Result + { + return $this->processIDRight(); + } + + private function processIDLeft(): Result + { + $localPartParser = new IDLeftPart($this->lexer); + $localPartResult = $localPartParser->parse(); + $this->idLeft = $localPartParser->localPart(); + $this->warnings = [...$localPartParser->getWarnings(), ...$this->warnings]; + + return $localPartResult; + } + + private function processIDRight(): Result + { + $domainPartParser = new IDRightPart($this->lexer); + $domainPartResult = $domainPartParser->parse(); + $this->idRight = $domainPartParser->domainPart(); + $this->warnings = [...$domainPartParser->getWarnings(), ...$this->warnings]; + + return $domainPartResult; + } + + public function getLeftPart(): string + { + return $this->idLeft; + } + + public function getRightPart(): string + { + return $this->idRight; + } + + private function addLongEmailWarning(string $localPart, string $parsedDomainPart): void + { + if (strlen($localPart . '@' . $parsedDomainPart) > self::EMAILID_MAX_LENGTH) { + $this->warnings[EmailTooLong::CODE] = new EmailTooLong(); + } + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser.php new file mode 100644 index 0000000..d577e3e --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser.php @@ -0,0 +1,78 @@ +lexer = $lexer; + } + + public function parse(string $str): Result + { + $this->lexer->setInput($str); + + if ($this->lexer->hasInvalidTokens()) { + return new InvalidEmail(new ExpectingATEXT("Invalid tokens found"), $this->lexer->current->value); + } + + $preParsingResult = $this->preLeftParsing(); + if ($preParsingResult->isInvalid()) { + return $preParsingResult; + } + + $localPartResult = $this->parseLeftFromAt(); + + if ($localPartResult->isInvalid()) { + return $localPartResult; + } + + $domainPartResult = $this->parseRightFromAt(); + + if ($domainPartResult->isInvalid()) { + return $domainPartResult; + } + + return new ValidEmail(); + } + + /** + * @return Warning\Warning[] + */ + public function getWarnings(): array + { + return $this->warnings; + } + + protected function hasAtToken(): bool + { + $this->lexer->moveNext(); + $this->lexer->moveNext(); + + return !$this->lexer->current->isA(EmailLexer::S_AT); + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/Comment.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/Comment.php new file mode 100644 index 0000000..7b5b47e --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/Comment.php @@ -0,0 +1,102 @@ +lexer = $lexer; + $this->commentStrategy = $commentStrategy; + } + + public function parse(): Result + { + if ($this->lexer->current->isA(EmailLexer::S_OPENPARENTHESIS)) { + $this->openedParenthesis++; + if ($this->noClosingParenthesis()) { + return new InvalidEmail(new UnclosedComment(), $this->lexer->current->value); + } + } + + if ($this->lexer->current->isA(EmailLexer::S_CLOSEPARENTHESIS)) { + return new InvalidEmail(new UnOpenedComment(), $this->lexer->current->value); + } + + $this->warnings[WarningComment::CODE] = new WarningComment(); + + $moreTokens = true; + while ($this->commentStrategy->exitCondition($this->lexer, $this->openedParenthesis) && $moreTokens) { + + if ($this->lexer->isNextToken(EmailLexer::S_OPENPARENTHESIS)) { + $this->openedParenthesis++; + } + $this->warnEscaping(); + if ($this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) { + $this->openedParenthesis--; + } + $moreTokens = $this->lexer->moveNext(); + } + + if ($this->openedParenthesis >= 1) { + return new InvalidEmail(new UnclosedComment(), $this->lexer->current->value); + } + if ($this->openedParenthesis < 0) { + return new InvalidEmail(new UnOpenedComment(), $this->lexer->current->value); + } + + $finalValidations = $this->commentStrategy->endOfLoopValidations($this->lexer); + + $this->warnings = [...$this->warnings, ...$this->commentStrategy->getWarnings()]; + + return $finalValidations; + } + + + /** + * @return void + */ + private function warnEscaping(): void + { + //Backslash found + if (!$this->lexer->current->isA(EmailLexer::S_BACKSLASH)) { + return; + } + + if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB, EmailLexer::C_DEL))) { + return; + } + + $this->warnings[QuotedPart::CODE] = + new QuotedPart($this->lexer->getPrevious()->type, $this->lexer->current->type); + } + + private function noClosingParenthesis(): bool + { + try { + $this->lexer->find(EmailLexer::S_CLOSEPARENTHESIS); + return false; + } catch (\RuntimeException $e) { + return true; + } + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/CommentStrategy/CommentStrategy.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/CommentStrategy/CommentStrategy.php new file mode 100644 index 0000000..8834db0 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/CommentStrategy/CommentStrategy.php @@ -0,0 +1,22 @@ +isNextToken(EmailLexer::S_DOT)); + } + + public function endOfLoopValidations(EmailLexer $lexer): Result + { + //test for end of string + if (!$lexer->isNextToken(EmailLexer::S_DOT)) { + return new InvalidEmail(new ExpectingATEXT('DOT not found near CLOSEPARENTHESIS'), $lexer->current->value); + } + //add warning + //Address is valid within the message but cannot be used unmodified for the envelope + return new ValidEmail(); + } + + public function getWarnings(): array + { + return []; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/CommentStrategy/LocalComment.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/CommentStrategy/LocalComment.php new file mode 100644 index 0000000..5f30a90 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/CommentStrategy/LocalComment.php @@ -0,0 +1,38 @@ + + */ + private $warnings = []; + + public function exitCondition(EmailLexer $lexer, int $openedParenthesis): bool + { + return !$lexer->isNextToken(EmailLexer::S_AT); + } + + public function endOfLoopValidations(EmailLexer $lexer): Result + { + if (!$lexer->isNextToken(EmailLexer::S_AT)) { + return new InvalidEmail(new ExpectingATEXT('ATEX is not expected after closing comments'), $lexer->current->value); + } + $this->warnings[CFWSNearAt::CODE] = new CFWSNearAt(); + return new ValidEmail(); + } + + public function getWarnings(): array + { + return $this->warnings; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/DomainLiteral.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/DomainLiteral.php new file mode 100644 index 0000000..5093e50 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/DomainLiteral.php @@ -0,0 +1,210 @@ +addTagWarnings(); + + $IPv6TAG = false; + $addressLiteral = ''; + + do { + if ($this->lexer->current->isA(EmailLexer::C_NUL)) { + return new InvalidEmail(new ExpectingDTEXT(), $this->lexer->current->value); + } + + $this->addObsoleteWarnings(); + + if ($this->lexer->isNextTokenAny(array(EmailLexer::S_OPENBRACKET, EmailLexer::S_OPENBRACKET))) { + return new InvalidEmail(new ExpectingDTEXT(), $this->lexer->current->value); + } + + if ($this->lexer->isNextTokenAny( + array(EmailLexer::S_HTAB, EmailLexer::S_SP, EmailLexer::CRLF) + )) { + $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS(); + $this->parseFWS(); + } + + if ($this->lexer->isNextToken(EmailLexer::S_CR)) { + return new InvalidEmail(new CRNoLF(), $this->lexer->current->value); + } + + if ($this->lexer->current->isA(EmailLexer::S_BACKSLASH)) { + return new InvalidEmail(new UnusualElements($this->lexer->current->value), $this->lexer->current->value); + } + if ($this->lexer->current->isA(EmailLexer::S_IPV6TAG)) { + $IPv6TAG = true; + } + + if ($this->lexer->current->isA(EmailLexer::S_CLOSEBRACKET)) { + break; + } + + $addressLiteral .= $this->lexer->current->value; + } while ($this->lexer->moveNext()); + + + //Encapsulate + $addressLiteral = str_replace('[', '', $addressLiteral); + $isAddressLiteralIPv4 = $this->checkIPV4Tag($addressLiteral); + + if (!$isAddressLiteralIPv4) { + return new ValidEmail(); + } + + $addressLiteral = $this->convertIPv4ToIPv6($addressLiteral); + + if (!$IPv6TAG) { + $this->warnings[WarningDomainLiteral::CODE] = new WarningDomainLiteral(); + return new ValidEmail(); + } + + $this->warnings[AddressLiteral::CODE] = new AddressLiteral(); + + $this->checkIPV6Tag($addressLiteral); + + return new ValidEmail(); + } + + /** + * @param string $addressLiteral + * @param int $maxGroups + */ + public function checkIPV6Tag($addressLiteral, $maxGroups = 8): void + { + $prev = $this->lexer->getPrevious(); + if ($prev->isA(EmailLexer::S_COLON)) { + $this->warnings[IPV6ColonEnd::CODE] = new IPV6ColonEnd(); + } + + $IPv6 = substr($addressLiteral, 5); + //Daniel Marschall's new IPv6 testing strategy + $matchesIP = explode(':', $IPv6); + $groupCount = count($matchesIP); + $colons = strpos($IPv6, '::'); + + if (count(preg_grep('/^[0-9A-Fa-f]{0,4}$/', $matchesIP, PREG_GREP_INVERT)) !== 0) { + $this->warnings[IPV6BadChar::CODE] = new IPV6BadChar(); + } + + if ($colons === false) { + // We need exactly the right number of groups + if ($groupCount !== $maxGroups) { + $this->warnings[IPV6GroupCount::CODE] = new IPV6GroupCount(); + } + return; + } + + if ($colons !== strrpos($IPv6, '::')) { + $this->warnings[IPV6DoubleColon::CODE] = new IPV6DoubleColon(); + return; + } + + if ($colons === 0 || $colons === (strlen($IPv6) - 2)) { + // RFC 4291 allows :: at the start or end of an address + //with 7 other groups in addition + ++$maxGroups; + } + + if ($groupCount > $maxGroups) { + $this->warnings[IPV6MaxGroups::CODE] = new IPV6MaxGroups(); + } elseif ($groupCount === $maxGroups) { + $this->warnings[IPV6Deprecated::CODE] = new IPV6Deprecated(); + } + } + + public function convertIPv4ToIPv6(string $addressLiteralIPv4): string + { + $matchesIP = []; + $IPv4Match = preg_match(self::IPV4_REGEX, $addressLiteralIPv4, $matchesIP); + + // Extract IPv4 part from the end of the address-literal (if there is one) + if ($IPv4Match > 0) { + $index = (int) strrpos($addressLiteralIPv4, $matchesIP[0]); + //There's a match but it is at the start + if ($index > 0) { + // Convert IPv4 part to IPv6 format for further testing + return substr($addressLiteralIPv4, 0, $index) . '0:0'; + } + } + + return $addressLiteralIPv4; + } + + /** + * @param string $addressLiteral + * + * @return bool + */ + protected function checkIPV4Tag($addressLiteral): bool + { + $matchesIP = []; + $IPv4Match = preg_match(self::IPV4_REGEX, $addressLiteral, $matchesIP); + + // Extract IPv4 part from the end of the address-literal (if there is one) + + if ($IPv4Match > 0) { + $index = strrpos($addressLiteral, $matchesIP[0]); + //There's a match but it is at the start + if ($index === 0) { + $this->warnings[AddressLiteral::CODE] = new AddressLiteral(); + return false; + } + } + + return true; + } + + private function addObsoleteWarnings(): void + { + if (in_array($this->lexer->current->type, self::OBSOLETE_WARNINGS)) { + $this->warnings[ObsoleteDTEXT::CODE] = new ObsoleteDTEXT(); + } + } + + private function addTagWarnings(): void + { + if ($this->lexer->isNextToken(EmailLexer::S_COLON)) { + $this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart(); + } + if ($this->lexer->isNextToken(EmailLexer::S_IPV6TAG)) { + $lexer = clone $this->lexer; + $lexer->moveNext(); + if ($lexer->isNextToken(EmailLexer::S_DOUBLECOLON)) { + $this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart(); + } + } + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/DomainPart.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/DomainPart.php new file mode 100644 index 0000000..3b6284b --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/DomainPart.php @@ -0,0 +1,327 @@ +lexer->clearRecorded(); + $this->lexer->startRecording(); + + $this->lexer->moveNext(); + + $domainChecks = $this->performDomainStartChecks(); + if ($domainChecks->isInvalid()) { + return $domainChecks; + } + + if ($this->lexer->current->isA(EmailLexer::S_AT)) { + return new InvalidEmail(new ConsecutiveAt(), $this->lexer->current->value); + } + + $result = $this->doParseDomainPart(); + if ($result->isInvalid()) { + return $result; + } + + $end = $this->checkEndOfDomain(); + if ($end->isInvalid()) { + return $end; + } + + $this->lexer->stopRecording(); + $this->domainPart = $this->lexer->getAccumulatedValues(); + + $length = strlen($this->domainPart); + if ($length > self::DOMAIN_MAX_LENGTH) { + return new InvalidEmail(new DomainTooLong(), $this->lexer->current->value); + } + + return new ValidEmail(); + } + + private function checkEndOfDomain(): Result + { + $prev = $this->lexer->getPrevious(); + if ($prev->isA(EmailLexer::S_DOT)) { + return new InvalidEmail(new DotAtEnd(), $this->lexer->current->value); + } + if ($prev->isA(EmailLexer::S_HYPHEN)) { + return new InvalidEmail(new DomainHyphened('Hypen found at the end of the domain'), $prev->value); + } + + if ($this->lexer->current->isA(EmailLexer::S_SP)) { + return new InvalidEmail(new CRLFAtTheEnd(), $prev->value); + } + return new ValidEmail(); + } + + private function performDomainStartChecks(): Result + { + $invalidTokens = $this->checkInvalidTokensAfterAT(); + if ($invalidTokens->isInvalid()) { + return $invalidTokens; + } + + $missingDomain = $this->checkEmptyDomain(); + if ($missingDomain->isInvalid()) { + return $missingDomain; + } + + if ($this->lexer->current->isA(EmailLexer::S_OPENPARENTHESIS)) { + $this->warnings[DeprecatedComment::CODE] = new DeprecatedComment(); + } + return new ValidEmail(); + } + + private function checkEmptyDomain(): Result + { + $thereIsNoDomain = $this->lexer->current->isA(EmailLexer::S_EMPTY) || + ($this->lexer->current->isA(EmailLexer::S_SP) && + !$this->lexer->isNextToken(EmailLexer::GENERIC)); + + if ($thereIsNoDomain) { + return new InvalidEmail(new NoDomainPart(), $this->lexer->current->value); + } + + return new ValidEmail(); + } + + private function checkInvalidTokensAfterAT(): Result + { + if ($this->lexer->current->isA(EmailLexer::S_DOT)) { + return new InvalidEmail(new DotAtStart(), $this->lexer->current->value); + } + if ($this->lexer->current->isA(EmailLexer::S_HYPHEN)) { + return new InvalidEmail(new DomainHyphened('After AT'), $this->lexer->current->value); + } + return new ValidEmail(); + } + + protected function parseComments(): Result + { + $commentParser = new Comment($this->lexer, new DomainComment()); + $result = $commentParser->parse(); + $this->warnings = [...$this->warnings, ...$commentParser->getWarnings()]; + + return $result; + } + + protected function doParseDomainPart(): Result + { + $tldMissing = true; + $hasComments = false; + $domain = ''; + do { + $prev = $this->lexer->getPrevious(); + + $notAllowedChars = $this->checkNotAllowedChars($this->lexer->current); + if ($notAllowedChars->isInvalid()) { + return $notAllowedChars; + } + + if ( + $this->lexer->current->isA(EmailLexer::S_OPENPARENTHESIS) || + $this->lexer->current->isA(EmailLexer::S_CLOSEPARENTHESIS) + ) { + $hasComments = true; + $commentsResult = $this->parseComments(); + + //Invalid comment parsing + if ($commentsResult->isInvalid()) { + return $commentsResult; + } + } + + $dotsResult = $this->checkConsecutiveDots(); + if ($dotsResult->isInvalid()) { + return $dotsResult; + } + + if ($this->lexer->current->isA(EmailLexer::S_OPENBRACKET)) { + $literalResult = $this->parseDomainLiteral(); + + $this->addTLDWarnings($tldMissing); + return $literalResult; + } + + $labelCheck = $this->checkLabelLength(); + if ($labelCheck->isInvalid()) { + return $labelCheck; + } + + $FwsResult = $this->parseFWS(); + if ($FwsResult->isInvalid()) { + return $FwsResult; + } + + $domain .= $this->lexer->current->value; + + if ($this->lexer->current->isA(EmailLexer::S_DOT) && $this->lexer->isNextToken(EmailLexer::GENERIC)) { + $tldMissing = false; + } + + $exceptionsResult = $this->checkDomainPartExceptions($prev, $hasComments); + if ($exceptionsResult->isInvalid()) { + return $exceptionsResult; + } + $this->lexer->moveNext(); + } while (!$this->lexer->current->isA(EmailLexer::S_EMPTY)); + + $labelCheck = $this->checkLabelLength(true); + if ($labelCheck->isInvalid()) { + return $labelCheck; + } + $this->addTLDWarnings($tldMissing); + + $this->domainPart = $domain; + return new ValidEmail(); + } + + /** + * @param Token $token + * + * @return Result + */ + private function checkNotAllowedChars(Token $token): Result + { + $notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH => true]; + if (isset($notAllowed[$token->type])) { + return new InvalidEmail(new CharNotAllowed(), $token->value); + } + return new ValidEmail(); + } + + /** + * @return Result + */ + protected function parseDomainLiteral(): Result + { + try { + $this->lexer->find(EmailLexer::S_CLOSEBRACKET); + } catch (\RuntimeException $e) { + return new InvalidEmail(new ExpectingDomainLiteralClose(), $this->lexer->current->value); + } + + $domainLiteralParser = new DomainLiteralParser($this->lexer); + $result = $domainLiteralParser->parse(); + $this->warnings = [...$this->warnings, ...$domainLiteralParser->getWarnings()]; + return $result; + } + + /** + * @param Token $prev + * @param bool $hasComments + * + * @return Result + */ + protected function checkDomainPartExceptions(Token $prev, bool $hasComments): Result + { + if ($this->lexer->current->isA(EmailLexer::S_OPENBRACKET) && $prev->type !== EmailLexer::S_AT) { + return new InvalidEmail(new ExpectingATEXT('OPENBRACKET not after AT'), $this->lexer->current->value); + } + + if ($this->lexer->current->isA(EmailLexer::S_HYPHEN) && $this->lexer->isNextToken(EmailLexer::S_DOT)) { + return new InvalidEmail(new DomainHyphened('Hypen found near DOT'), $this->lexer->current->value); + } + + if ( + $this->lexer->current->isA(EmailLexer::S_BACKSLASH) + && $this->lexer->isNextToken(EmailLexer::GENERIC) + ) { + return new InvalidEmail(new ExpectingATEXT('Escaping following "ATOM"'), $this->lexer->current->value); + } + + return $this->validateTokens($hasComments); + } + + protected function validateTokens(bool $hasComments): Result + { + $validDomainTokens = array( + EmailLexer::GENERIC => true, + EmailLexer::S_HYPHEN => true, + EmailLexer::S_DOT => true, + ); + + if ($hasComments) { + $validDomainTokens[EmailLexer::S_OPENPARENTHESIS] = true; + $validDomainTokens[EmailLexer::S_CLOSEPARENTHESIS] = true; + } + + if (!isset($validDomainTokens[$this->lexer->current->type])) { + return new InvalidEmail(new ExpectingATEXT('Invalid token in domain: ' . $this->lexer->current->value), $this->lexer->current->value); + } + + return new ValidEmail(); + } + + private function checkLabelLength(bool $isEndOfDomain = false): Result + { + if ($this->lexer->current->isA(EmailLexer::S_DOT) || $isEndOfDomain) { + if ($this->isLabelTooLong($this->label)) { + return new InvalidEmail(new LabelTooLong(), $this->lexer->current->value); + } + $this->label = ''; + } + $this->label .= $this->lexer->current->value; + return new ValidEmail(); + } + + + private function isLabelTooLong(string $label): bool + { + if (preg_match('/[^\x00-\x7F]/', $label)) { + idn_to_ascii($label, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $idnaInfo); + /** @psalm-var array{errors: int, ...} $idnaInfo */ + return (bool) ($idnaInfo['errors'] & IDNA_ERROR_LABEL_TOO_LONG); + } + return strlen($label) > self::LABEL_MAX_LENGTH; + } + + private function addTLDWarnings(bool $isTLDMissing): void + { + if ($isTLDMissing) { + $this->warnings[TLD::CODE] = new TLD(); + } + } + + public function domainPart(): string + { + return $this->domainPart; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/DoubleQuote.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/DoubleQuote.php new file mode 100644 index 0000000..b5335d3 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/DoubleQuote.php @@ -0,0 +1,91 @@ +checkDQUOTE(); + if ($validQuotedString->isInvalid()) { + return $validQuotedString; + } + + $special = [ + EmailLexer::S_CR => true, + EmailLexer::S_HTAB => true, + EmailLexer::S_LF => true + ]; + + $invalid = [ + EmailLexer::C_NUL => true, + EmailLexer::S_HTAB => true, + EmailLexer::S_CR => true, + EmailLexer::S_LF => true + ]; + + $setSpecialsWarning = true; + + $this->lexer->moveNext(); + + while (!$this->lexer->current->isA(EmailLexer::S_DQUOTE) && !$this->lexer->current->isA(EmailLexer::S_EMPTY)) { + if (isset($special[$this->lexer->current->type]) && $setSpecialsWarning) { + $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS(); + $setSpecialsWarning = false; + } + if ($this->lexer->current->isA(EmailLexer::S_BACKSLASH) && $this->lexer->isNextToken(EmailLexer::S_DQUOTE)) { + $this->lexer->moveNext(); + } + + $this->lexer->moveNext(); + + if (!$this->escaped() && isset($invalid[$this->lexer->current->type])) { + return new InvalidEmail(new ExpectingATEXT("Expecting ATEXT between DQUOTE"), $this->lexer->current->value); + } + } + + $prev = $this->lexer->getPrevious(); + + if ($prev->isA(EmailLexer::S_BACKSLASH)) { + $validQuotedString = $this->checkDQUOTE(); + if ($validQuotedString->isInvalid()) { + return $validQuotedString; + } + } + + if (!$this->lexer->isNextToken(EmailLexer::S_AT) && !$prev->isA(EmailLexer::S_BACKSLASH)) { + return new InvalidEmail(new ExpectingATEXT("Expecting ATEXT between DQUOTE"), $this->lexer->current->value); + } + + return new ValidEmail(); + } + + protected function checkDQUOTE(): Result + { + $previous = $this->lexer->getPrevious(); + + if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous->isA(EmailLexer::GENERIC)) { + $description = 'https://tools.ietf.org/html/rfc5322#section-3.2.4 - quoted string should be a unit'; + return new InvalidEmail(new ExpectingATEXT($description), $this->lexer->current->value); + } + + try { + $this->lexer->find(EmailLexer::S_DQUOTE); + } catch (\Exception $e) { + return new InvalidEmail(new UnclosedQuotedString(), $this->lexer->current->value); + } + $this->warnings[QuotedString::CODE] = new QuotedString($previous->value, $this->lexer->current->value); + + return new ValidEmail(); + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/FoldingWhiteSpace.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/FoldingWhiteSpace.php new file mode 100644 index 0000000..348a7af --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/FoldingWhiteSpace.php @@ -0,0 +1,87 @@ +isFWS()) { + return new ValidEmail(); + } + + $previous = $this->lexer->getPrevious(); + + $resultCRLF = $this->checkCRLFInFWS(); + if ($resultCRLF->isInvalid()) { + return $resultCRLF; + } + + if ($this->lexer->current->isA(EmailLexer::S_CR)) { + return new InvalidEmail(new CRNoLF(), $this->lexer->current->value); + } + + if ($this->lexer->isNextToken(EmailLexer::GENERIC) && !$previous->isA(EmailLexer::S_AT)) { + return new InvalidEmail(new AtextAfterCFWS(), $this->lexer->current->value); + } + + if ($this->lexer->current->isA(EmailLexer::S_LF) || $this->lexer->current->isA(EmailLexer::C_NUL)) { + return new InvalidEmail(new ExpectingCTEXT(), $this->lexer->current->value); + } + + if ($this->lexer->isNextToken(EmailLexer::S_AT) || $previous->isA(EmailLexer::S_AT)) { + $this->warnings[CFWSNearAt::CODE] = new CFWSNearAt(); + } else { + $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS(); + } + + return new ValidEmail(); + } + + protected function checkCRLFInFWS(): Result + { + if (!$this->lexer->current->isA(EmailLexer::CRLF)) { + return new ValidEmail(); + } + + if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) { + return new InvalidEmail(new CRLFX2(), $this->lexer->current->value); + } + + //this has no coverage. Condition is repeated from above one + if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) { + return new InvalidEmail(new CRLFAtTheEnd(), $this->lexer->current->value); + } + + return new ValidEmail(); + } + + protected function isFWS(): bool + { + if ($this->escaped()) { + return false; + } + + return in_array($this->lexer->current->type, self::FWS_TYPES); + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/IDLeftPart.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/IDLeftPart.php new file mode 100644 index 0000000..bedcf7b --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/IDLeftPart.php @@ -0,0 +1,15 @@ +lexer->current->value); + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/IDRightPart.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/IDRightPart.php new file mode 100644 index 0000000..d2fc1d7 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/IDRightPart.php @@ -0,0 +1,29 @@ + true, + EmailLexer::S_SQUOTE => true, + EmailLexer::S_BACKTICK => true, + EmailLexer::S_SEMICOLON => true, + EmailLexer::S_GREATERTHAN => true, + EmailLexer::S_LOWERTHAN => true, + ]; + + if (isset($invalidDomainTokens[$this->lexer->current->type])) { + return new InvalidEmail(new ExpectingATEXT('Invalid token in domain: ' . $this->lexer->current->value), $this->lexer->current->value); + } + return new ValidEmail(); + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/LocalPart.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/LocalPart.php new file mode 100644 index 0000000..10f9565 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/LocalPart.php @@ -0,0 +1,163 @@ + EmailLexer::S_COMMA, + EmailLexer::S_CLOSEBRACKET => EmailLexer::S_CLOSEBRACKET, + EmailLexer::S_OPENBRACKET => EmailLexer::S_OPENBRACKET, + EmailLexer::S_GREATERTHAN => EmailLexer::S_GREATERTHAN, + EmailLexer::S_LOWERTHAN => EmailLexer::S_LOWERTHAN, + EmailLexer::S_COLON => EmailLexer::S_COLON, + EmailLexer::S_SEMICOLON => EmailLexer::S_SEMICOLON, + EmailLexer::INVALID => EmailLexer::INVALID + ]; + + /** + * @var string + */ + private $localPart = ''; + + + public function parse(): Result + { + $this->lexer->clearRecorded(); + $this->lexer->startRecording(); + + while (!$this->lexer->current->isA(EmailLexer::S_AT) && !$this->lexer->current->isA(EmailLexer::S_EMPTY)) { + if ($this->hasDotAtStart()) { + return new InvalidEmail(new DotAtStart(), $this->lexer->current->value); + } + + if ($this->lexer->current->isA(EmailLexer::S_DQUOTE)) { + $dquoteParsingResult = $this->parseDoubleQuote(); + + //Invalid double quote parsing + if ($dquoteParsingResult->isInvalid()) { + return $dquoteParsingResult; + } + } + + if ( + $this->lexer->current->isA(EmailLexer::S_OPENPARENTHESIS) || + $this->lexer->current->isA(EmailLexer::S_CLOSEPARENTHESIS) + ) { + $commentsResult = $this->parseComments(); + + //Invalid comment parsing + if ($commentsResult->isInvalid()) { + return $commentsResult; + } + } + + if ($this->lexer->current->isA(EmailLexer::S_DOT) && $this->lexer->isNextToken(EmailLexer::S_DOT)) { + return new InvalidEmail(new ConsecutiveDot(), $this->lexer->current->value); + } + + if ( + $this->lexer->current->isA(EmailLexer::S_DOT) && + $this->lexer->isNextToken(EmailLexer::S_AT) + ) { + return new InvalidEmail(new DotAtEnd(), $this->lexer->current->value); + } + + $resultEscaping = $this->validateEscaping(); + if ($resultEscaping->isInvalid()) { + return $resultEscaping; + } + + $resultToken = $this->validateTokens(false); + if ($resultToken->isInvalid()) { + return $resultToken; + } + + $resultFWS = $this->parseLocalFWS(); + if ($resultFWS->isInvalid()) { + return $resultFWS; + } + + $this->lexer->moveNext(); + } + + $this->lexer->stopRecording(); + $this->localPart = rtrim($this->lexer->getAccumulatedValues(), '@'); + if (strlen($this->localPart) > LocalTooLong::LOCAL_PART_LENGTH) { + $this->warnings[LocalTooLong::CODE] = new LocalTooLong(); + } + + return new ValidEmail(); + } + + protected function validateTokens(bool $hasComments): Result + { + if (isset(self::INVALID_TOKENS[$this->lexer->current->type])) { + return new InvalidEmail(new ExpectingATEXT('Invalid token found'), $this->lexer->current->value); + } + return new ValidEmail(); + } + + public function localPart(): string + { + return $this->localPart; + } + + private function parseLocalFWS(): Result + { + $foldingWS = new FoldingWhiteSpace($this->lexer); + $resultFWS = $foldingWS->parse(); + if ($resultFWS->isValid()) { + $this->warnings = [...$this->warnings, ...$foldingWS->getWarnings()]; + } + return $resultFWS; + } + + private function hasDotAtStart(): bool + { + return $this->lexer->current->isA(EmailLexer::S_DOT) && $this->lexer->getPrevious()->isA(EmailLexer::S_EMPTY); + } + + private function parseDoubleQuote(): Result + { + $dquoteParser = new DoubleQuote($this->lexer); + $parseAgain = $dquoteParser->parse(); + $this->warnings = [...$this->warnings, ...$dquoteParser->getWarnings()]; + + return $parseAgain; + } + + protected function parseComments(): Result + { + $commentParser = new Comment($this->lexer, new LocalComment()); + $result = $commentParser->parse(); + $this->warnings = [...$this->warnings, ...$commentParser->getWarnings()]; + + return $result; + } + + private function validateEscaping(): Result + { + //Backslash found + if (!$this->lexer->current->isA(EmailLexer::S_BACKSLASH)) { + return new ValidEmail(); + } + + if ($this->lexer->isNextToken(EmailLexer::GENERIC)) { + return new InvalidEmail(new ExpectingATEXT('Found ATOM after escaping'), $this->lexer->current->value); + } + + return new ValidEmail(); + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/PartParser.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/PartParser.php new file mode 100644 index 0000000..53afb25 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Parser/PartParser.php @@ -0,0 +1,63 @@ +lexer = $lexer; + } + + abstract public function parse(): Result; + + /** + * @return Warning[] + */ + public function getWarnings() + { + return $this->warnings; + } + + protected function parseFWS(): Result + { + $foldingWS = new FoldingWhiteSpace($this->lexer); + $resultFWS = $foldingWS->parse(); + $this->warnings = [...$this->warnings, ...$foldingWS->getWarnings()]; + return $resultFWS; + } + + protected function checkConsecutiveDots(): Result + { + if ($this->lexer->current->isA(EmailLexer::S_DOT) && $this->lexer->isNextToken(EmailLexer::S_DOT)) { + return new InvalidEmail(new ConsecutiveDot(), $this->lexer->current->value); + } + + return new ValidEmail(); + } + + protected function escaped(): bool + { + $previous = $this->lexer->getPrevious(); + + return $previous->isA(EmailLexer::S_BACKSLASH) + && !$this->lexer->current->isA(EmailLexer::GENERIC); + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/InvalidEmail.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/InvalidEmail.php new file mode 100644 index 0000000..82699ac --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/InvalidEmail.php @@ -0,0 +1,49 @@ +token = $token; + $this->reason = $reason; + } + + public function isValid(): bool + { + return false; + } + + public function isInvalid(): bool + { + return true; + } + + public function description(): string + { + return $this->reason->description() . " in char " . $this->token; + } + + public function code(): int + { + return $this->reason->code(); + } + + public function reason(): Reason + { + return $this->reason; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/MultipleErrors.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/MultipleErrors.php new file mode 100644 index 0000000..5fa85af --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/MultipleErrors.php @@ -0,0 +1,56 @@ +reasons[$reason->code()] = $reason; + } + + /** + * @return Reason[] + */ + public function getReasons() : array + { + return $this->reasons; + } + + public function reason() : Reason + { + return 0 !== count($this->reasons) + ? current($this->reasons) + : new EmptyReason(); + } + + public function description() : string + { + $description = ''; + foreach($this->reasons as $reason) { + $description .= $reason->description() . PHP_EOL; + } + + return $description; + } + + public function code() : int + { + return 0; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/AtextAfterCFWS.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/AtextAfterCFWS.php new file mode 100644 index 0000000..96e2284 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/AtextAfterCFWS.php @@ -0,0 +1,16 @@ +detailedDescription = $details; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/DomainAcceptsNoMail.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/DomainAcceptsNoMail.php new file mode 100644 index 0000000..bcaefb6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/DomainAcceptsNoMail.php @@ -0,0 +1,16 @@ +exception = $exception; + + } + public function code() : int + { + return 999; + } + + public function description() : string + { + return $this->exception->getMessage(); + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/ExpectingATEXT.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/ExpectingATEXT.php new file mode 100644 index 0000000..07ea8d2 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/ExpectingATEXT.php @@ -0,0 +1,16 @@ +detailedDescription; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/ExpectingCTEXT.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/ExpectingCTEXT.php new file mode 100644 index 0000000..64f5f7c --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Reason/ExpectingCTEXT.php @@ -0,0 +1,16 @@ +element = $element; + } + + public function code() : int + { + return 201; + } + + public function description() : string + { + return 'Unusual element found, wourld render invalid in majority of cases. Element found: ' . $this->element; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Result.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Result.php new file mode 100644 index 0000000..0e50fc5 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/Result.php @@ -0,0 +1,31 @@ +reason = new ReasonSpoofEmail(); + parent::__construct($this->reason, ''); + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/ValidEmail.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/ValidEmail.php new file mode 100644 index 0000000..fdc882f --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Result/ValidEmail.php @@ -0,0 +1,27 @@ +dnsGetRecord = $dnsGetRecord; + } + + public function isValid(string $email, EmailLexer $emailLexer): bool + { + // use the input to check DNS if we cannot extract something similar to a domain + $host = $email; + + // Arguable pattern to extract the domain. Not aiming to validate the domain nor the email + if (false !== $lastAtPos = strrpos($email, '@')) { + $host = substr($email, $lastAtPos + 1); + } + + // Get the domain parts + $hostParts = explode('.', $host); + + $isLocalDomain = count($hostParts) <= 1; + $isReservedTopLevel = in_array($hostParts[(count($hostParts) - 1)], self::RESERVED_DNS_TOP_LEVEL_NAMES, true); + + // Exclude reserved top level DNS names + if ($isLocalDomain || $isReservedTopLevel) { + $this->error = new InvalidEmail(new LocalOrReservedDomain(), $host); + return false; + } + + return $this->checkDns($host); + } + + public function getError(): ?InvalidEmail + { + return $this->error; + } + + /** + * @return Warning[] + */ + public function getWarnings(): array + { + return $this->warnings; + } + + /** + * @param string $host + * + * @return bool + */ + protected function checkDns($host) + { + $variant = INTL_IDNA_VARIANT_UTS46; + + $host = rtrim(idn_to_ascii($host, IDNA_DEFAULT, $variant), '.'); + + $hostParts = explode('.', $host); + $host = array_pop($hostParts); + + while (count($hostParts) > 0) { + $host = array_pop($hostParts) . '.' . $host; + + if ($this->validateDnsRecords($host)) { + return true; + } + } + + return false; + } + + + /** + * Validate the DNS records for given host. + * + * @param string $host A set of DNS records in the format returned by dns_get_record. + * + * @return bool True on success. + */ + private function validateDnsRecords($host): bool + { + $dnsRecordsResult = $this->dnsGetRecord->getRecords($host, DNS_A + DNS_MX); + + if ($dnsRecordsResult->withError()) { + $this->error = new InvalidEmail(new UnableToGetDNSRecord(), ''); + return false; + } + + $dnsRecords = $dnsRecordsResult->getRecords(); + + // Combined check for A+MX+AAAA can fail with SERVFAIL, even in the presence of valid A/MX records + $aaaaRecordsResult = $this->dnsGetRecord->getRecords($host, DNS_AAAA); + + if (! $aaaaRecordsResult->withError()) { + $dnsRecords = array_merge($dnsRecords, $aaaaRecordsResult->getRecords()); + } + + // No MX, A or AAAA DNS records + if ($dnsRecords === []) { + $this->error = new InvalidEmail(new ReasonNoDNSRecord(), ''); + return false; + } + + // For each DNS record + foreach ($dnsRecords as $dnsRecord) { + if (!$this->validateMXRecord($dnsRecord)) { + // No MX records (fallback to A or AAAA records) + if (empty($this->mxRecords)) { + $this->warnings[NoDNSMXRecord::CODE] = new NoDNSMXRecord(); + } + return false; + } + } + return true; + } + + /** + * Validate an MX record + * + * @param array $dnsRecord Given DNS record. + * + * @return bool True if valid. + */ + private function validateMxRecord($dnsRecord): bool + { + if (!isset($dnsRecord['type'])) { + $this->error = new InvalidEmail(new ReasonNoDNSRecord(), ''); + return false; + } + + if ($dnsRecord['type'] !== 'MX') { + return true; + } + + // "Null MX" record indicates the domain accepts no mail (https://tools.ietf.org/html/rfc7505) + if (empty($dnsRecord['target']) || $dnsRecord['target'] === '.') { + $this->error = new InvalidEmail(new DomainAcceptsNoMail(), ""); + return false; + } + + $this->mxRecords[] = $dnsRecord; + + return true; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/DNSGetRecordWrapper.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/DNSGetRecordWrapper.php new file mode 100644 index 0000000..5d04c01 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/DNSGetRecordWrapper.php @@ -0,0 +1,30 @@ +> $records + * @param bool $error + */ + public function __construct(private readonly array $records, private readonly bool $error = false) + { + } + + /** + * @return list> + */ + public function getRecords(): array + { + return $this->records; + } + + public function withError(): bool + { + return $this->error; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/EmailValidation.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/EmailValidation.php new file mode 100644 index 0000000..1bcc0a7 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/EmailValidation.php @@ -0,0 +1,34 @@ +setChecks(Spoofchecker::SINGLE_SCRIPT); + + if ($checker->isSuspicious($email)) { + $this->error = new SpoofEmail(); + } + + return $this->error === null; + } + + public function getError() : ?InvalidEmail + { + return $this->error; + } + + public function getWarnings() : array + { + return []; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/MessageIDValidation.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/MessageIDValidation.php new file mode 100644 index 0000000..97d1ea7 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/MessageIDValidation.php @@ -0,0 +1,55 @@ +parse($email); + $this->warnings = $parser->getWarnings(); + if ($result->isInvalid()) { + /** @psalm-suppress PropertyTypeCoercion */ + $this->error = $result; + return false; + } + } catch (\Exception $invalid) { + $this->error = new InvalidEmail(new ExceptionFound($invalid), ''); + return false; + } + + return true; + } + + /** + * @return Warning[] + */ + public function getWarnings(): array + { + return $this->warnings; + } + + public function getError(): ?InvalidEmail + { + return $this->error; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php new file mode 100644 index 0000000..c908053 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php @@ -0,0 +1,105 @@ +validations as $validation) { + $emailLexer->reset(); + $validationResult = $validation->isValid($email, $emailLexer); + $result = $result && $validationResult; + $this->warnings = [...$this->warnings, ...$validation->getWarnings()]; + if (!$validationResult) { + $this->processError($validation); + } + + if ($this->shouldStop($result)) { + break; + } + } + + return $result; + } + + private function initErrorStorage(): void + { + if (null === $this->error) { + $this->error = new MultipleErrors(); + } + } + + private function processError(EmailValidation $validation): void + { + if (null !== $validation->getError()) { + $this->initErrorStorage(); + /** @psalm-suppress PossiblyNullReference */ + $this->error->addReason($validation->getError()->reason()); + } + } + + private function shouldStop(bool $result): bool + { + return !$result && $this->mode === self::STOP_ON_ERROR; + } + + /** + * Returns the validation errors. + */ + public function getError(): ?InvalidEmail + { + return $this->error; + } + + /** + * @return Warning[] + */ + public function getWarnings(): array + { + return $this->warnings; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php new file mode 100644 index 0000000..06885ed --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php @@ -0,0 +1,41 @@ +getWarnings())) { + return true; + } + + $this->error = new InvalidEmail(new RFCWarnings(), ''); + + return false; + } + + /** + * {@inheritdoc} + */ + public function getError() : ?InvalidEmail + { + return $this->error ?: parent::getError(); + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/RFCValidation.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/RFCValidation.php new file mode 100644 index 0000000..f59cbfc --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Validation/RFCValidation.php @@ -0,0 +1,54 @@ +parse($email); + $this->warnings = $parser->getWarnings(); + if ($result->isInvalid()) { + /** @psalm-suppress PropertyTypeCoercion */ + $this->error = $result; + return false; + } + } catch (\Exception $invalid) { + $this->error = new InvalidEmail(new ExceptionFound($invalid), ''); + return false; + } + + return true; + } + + public function getError(): ?InvalidEmail + { + return $this->error; + } + + /** + * @return Warning[] + */ + public function getWarnings(): array + { + return $this->warnings; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/AddressLiteral.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/AddressLiteral.php new file mode 100644 index 0000000..474ff0e --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/AddressLiteral.php @@ -0,0 +1,14 @@ +message = 'Address literal in domain part'; + $this->rfcNumber = 5321; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/CFWSNearAt.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/CFWSNearAt.php new file mode 100644 index 0000000..8bac12b --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/CFWSNearAt.php @@ -0,0 +1,13 @@ +message = "Deprecated folding white space near @"; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/CFWSWithFWS.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/CFWSWithFWS.php new file mode 100644 index 0000000..ba57601 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/CFWSWithFWS.php @@ -0,0 +1,13 @@ +message = 'Folding whites space followed by folding white space'; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/Comment.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/Comment.php new file mode 100644 index 0000000..6508295 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/Comment.php @@ -0,0 +1,13 @@ +message = "Comments found in this email"; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/DeprecatedComment.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/DeprecatedComment.php new file mode 100644 index 0000000..a257807 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/DeprecatedComment.php @@ -0,0 +1,13 @@ +message = 'Deprecated comments'; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/DomainLiteral.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/DomainLiteral.php new file mode 100644 index 0000000..034388c --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/DomainLiteral.php @@ -0,0 +1,14 @@ +message = 'Domain Literal'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/EmailTooLong.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/EmailTooLong.php new file mode 100644 index 0000000..d25ad12 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/EmailTooLong.php @@ -0,0 +1,15 @@ +message = 'Email is too long, exceeds ' . EmailParser::EMAIL_MAX_LENGTH; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6BadChar.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6BadChar.php new file mode 100644 index 0000000..3ecd5bc --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6BadChar.php @@ -0,0 +1,14 @@ +message = 'Bad char in IPV6 domain literal'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6ColonEnd.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6ColonEnd.php new file mode 100644 index 0000000..3f0c2f2 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6ColonEnd.php @@ -0,0 +1,14 @@ +message = ':: found at the end of the domain literal'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6ColonStart.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6ColonStart.php new file mode 100644 index 0000000..742fb3b --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6ColonStart.php @@ -0,0 +1,14 @@ +message = ':: found at the start of the domain literal'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6Deprecated.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6Deprecated.php new file mode 100644 index 0000000..59c3037 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6Deprecated.php @@ -0,0 +1,14 @@ +message = 'Deprecated form of IPV6'; + $this->rfcNumber = 5321; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6DoubleColon.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6DoubleColon.php new file mode 100644 index 0000000..d406602 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6DoubleColon.php @@ -0,0 +1,14 @@ +message = 'Double colon found after IPV6 tag'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6GroupCount.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6GroupCount.php new file mode 100644 index 0000000..551bc3a --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6GroupCount.php @@ -0,0 +1,14 @@ +message = 'Group count is not IPV6 valid'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6MaxGroups.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6MaxGroups.php new file mode 100644 index 0000000..7f8a410 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/IPV6MaxGroups.php @@ -0,0 +1,14 @@ +message = 'Reached the maximum number of IPV6 groups allowed'; + $this->rfcNumber = 5321; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/LocalTooLong.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/LocalTooLong.php new file mode 100644 index 0000000..b46b874 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/LocalTooLong.php @@ -0,0 +1,15 @@ +message = 'Local part is too long, exceeds 64 chars (octets)'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/NoDNSMXRecord.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/NoDNSMXRecord.php new file mode 100644 index 0000000..bddb96b --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/NoDNSMXRecord.php @@ -0,0 +1,14 @@ +message = 'No MX DSN record was found for this email'; + $this->rfcNumber = 5321; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/ObsoleteDTEXT.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/ObsoleteDTEXT.php new file mode 100644 index 0000000..412fd49 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/ObsoleteDTEXT.php @@ -0,0 +1,14 @@ +rfcNumber = 5322; + $this->message = 'Obsolete DTEXT in domain literal'; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/QuotedPart.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/QuotedPart.php new file mode 100644 index 0000000..db0850c --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/QuotedPart.php @@ -0,0 +1,27 @@ +name; + } + + if ($postToken instanceof UnitEnum) { + $postToken = $postToken->name; + } + + $this->message = "Deprecated Quoted String found between $prevToken and $postToken"; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/QuotedString.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/QuotedString.php new file mode 100644 index 0000000..388da0b --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/QuotedString.php @@ -0,0 +1,17 @@ +message = "Quoted String found between $prevToken and $postToken"; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/TLD.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/TLD.php new file mode 100644 index 0000000..10cec28 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/TLD.php @@ -0,0 +1,13 @@ +message = "RFC5321, TLD"; + } +} diff --git a/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/Warning.php b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/Warning.php new file mode 100644 index 0000000..7adb3b8 --- /dev/null +++ b/lib/SymfonyMailer/vendor/egulias/email-validator/src/Warning/Warning.php @@ -0,0 +1,53 @@ +message; + } + + /** + * @return int + */ + public function code() + { + return self::CODE; + } + + /** + * @return int + */ + public function RFCNumber() + { + return $this->rfcNumber; + } + + /** + * @return string + */ + public function __toString(): string + { + return $this->message() . " rfc: " . $this->rfcNumber . "internal code: " . static::CODE; + } +} diff --git a/lib/SymfonyMailer/vendor/psr/container/.gitignore b/lib/SymfonyMailer/vendor/psr/container/.gitignore new file mode 100644 index 0000000..b2395aa --- /dev/null +++ b/lib/SymfonyMailer/vendor/psr/container/.gitignore @@ -0,0 +1,3 @@ +composer.lock +composer.phar +/vendor/ diff --git a/lib/SymfonyMailer/vendor/psr/container/LICENSE b/lib/SymfonyMailer/vendor/psr/container/LICENSE new file mode 100644 index 0000000..2877a48 --- /dev/null +++ b/lib/SymfonyMailer/vendor/psr/container/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013-2016 container-interop +Copyright (c) 2016 PHP Framework Interoperability Group + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/SymfonyMailer/vendor/psr/container/README.md b/lib/SymfonyMailer/vendor/psr/container/README.md new file mode 100644 index 0000000..1b9d9e5 --- /dev/null +++ b/lib/SymfonyMailer/vendor/psr/container/README.md @@ -0,0 +1,13 @@ +Container interface +============== + +This repository holds all interfaces related to [PSR-11 (Container Interface)][psr-url]. + +Note that this is not a Container implementation of its own. It is merely abstractions that describe the components of a Dependency Injection Container. + +The installable [package][package-url] and [implementations][implementation-url] are listed on Packagist. + +[psr-url]: https://www.php-fig.org/psr/psr-11/ +[package-url]: https://packagist.org/packages/psr/container +[implementation-url]: https://packagist.org/providers/psr/container-implementation + diff --git a/lib/SymfonyMailer/vendor/psr/container/composer.json b/lib/SymfonyMailer/vendor/psr/container/composer.json new file mode 100644 index 0000000..baf6cd1 --- /dev/null +++ b/lib/SymfonyMailer/vendor/psr/container/composer.json @@ -0,0 +1,27 @@ +{ + "name": "psr/container", + "type": "library", + "description": "Common Container Interface (PHP FIG PSR-11)", + "keywords": ["psr", "psr-11", "container", "container-interop", "container-interface"], + "homepage": "https://github.com/php-fig/container", + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "require": { + "php": ">=7.4.0" + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + } +} diff --git a/lib/SymfonyMailer/vendor/psr/container/src/ContainerExceptionInterface.php b/lib/SymfonyMailer/vendor/psr/container/src/ContainerExceptionInterface.php new file mode 100644 index 0000000..0f213f2 --- /dev/null +++ b/lib/SymfonyMailer/vendor/psr/container/src/ContainerExceptionInterface.php @@ -0,0 +1,12 @@ +=7.2.0" + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/lib/SymfonyMailer/vendor/psr/event-dispatcher/src/EventDispatcherInterface.php b/lib/SymfonyMailer/vendor/psr/event-dispatcher/src/EventDispatcherInterface.php new file mode 100644 index 0000000..4306fa9 --- /dev/null +++ b/lib/SymfonyMailer/vendor/psr/event-dispatcher/src/EventDispatcherInterface.php @@ -0,0 +1,21 @@ +logger = $logger; + } + + public function doSomething() + { + if ($this->logger) { + $this->logger->info('Doing work'); + } + + try { + $this->doSomethingElse(); + } catch (Exception $exception) { + $this->logger->error('Oh no!', array('exception' => $exception)); + } + + // do something useful + } +} +``` + +You can then pick one of the implementations of the interface to get a logger. + +If you want to implement the interface, you can require this package and +implement `Psr\Log\LoggerInterface` in your code. Please read the +[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) +for details. diff --git a/lib/SymfonyMailer/vendor/psr/log/composer.json b/lib/SymfonyMailer/vendor/psr/log/composer.json new file mode 100644 index 0000000..879fc6f --- /dev/null +++ b/lib/SymfonyMailer/vendor/psr/log/composer.json @@ -0,0 +1,26 @@ +{ + "name": "psr/log", + "description": "Common interface for logging libraries", + "keywords": ["psr", "psr-3", "log"], + "homepage": "https://github.com/php-fig/log", + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "require": { + "php": ">=8.0.0" + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + } +} diff --git a/lib/SymfonyMailer/vendor/psr/log/src/AbstractLogger.php b/lib/SymfonyMailer/vendor/psr/log/src/AbstractLogger.php new file mode 100644 index 0000000..d60a091 --- /dev/null +++ b/lib/SymfonyMailer/vendor/psr/log/src/AbstractLogger.php @@ -0,0 +1,15 @@ +logger = $logger; + } +} diff --git a/lib/SymfonyMailer/vendor/psr/log/src/LoggerInterface.php b/lib/SymfonyMailer/vendor/psr/log/src/LoggerInterface.php new file mode 100644 index 0000000..cb4cf64 --- /dev/null +++ b/lib/SymfonyMailer/vendor/psr/log/src/LoggerInterface.php @@ -0,0 +1,98 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + */ + public function alert(string|\Stringable $message, array $context = []): void + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + */ + public function critical(string|\Stringable $message, array $context = []): void + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + */ + public function error(string|\Stringable $message, array $context = []): void + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + */ + public function warning(string|\Stringable $message, array $context = []): void + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + */ + public function notice(string|\Stringable $message, array $context = []): void + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + */ + public function info(string|\Stringable $message, array $context = []): void + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + */ + public function debug(string|\Stringable $message, array $context = []): void + { + $this->log(LogLevel::DEBUG, $message, $context); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * + * @throws \Psr\Log\InvalidArgumentException + */ + abstract public function log($level, string|\Stringable $message, array $context = []): void; +} diff --git a/lib/SymfonyMailer/vendor/psr/log/src/NullLogger.php b/lib/SymfonyMailer/vendor/psr/log/src/NullLogger.php new file mode 100644 index 0000000..de0561e --- /dev/null +++ b/lib/SymfonyMailer/vendor/psr/log/src/NullLogger.php @@ -0,0 +1,26 @@ +logger) { }` + * blocks. + */ +class NullLogger extends AbstractLogger +{ + /** + * Logs with an arbitrary level. + * + * @param mixed[] $context + * + * @throws \Psr\Log\InvalidArgumentException + */ + public function log($level, string|\Stringable $message, array $context = []): void + { + // noop + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/CHANGELOG.md b/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/CHANGELOG.md new file mode 100644 index 0000000..7932e26 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/CHANGELOG.md @@ -0,0 +1,5 @@ +CHANGELOG +========= + +The changelog is maintained for all Symfony contracts at the following URL: +https://github.com/symfony/contracts/blob/main/CHANGELOG.md diff --git a/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/LICENSE b/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/LICENSE new file mode 100644 index 0000000..0ed3a24 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2020-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/README.md b/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/README.md new file mode 100644 index 0000000..9814864 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/README.md @@ -0,0 +1,26 @@ +Symfony Deprecation Contracts +============================= + +A generic function and convention to trigger deprecation notices. + +This package provides a single global function named `trigger_deprecation()` that triggers silenced deprecation notices. + +By using a custom PHP error handler such as the one provided by the Symfony ErrorHandler component, +the triggered deprecations can be caught and logged for later discovery, both on dev and prod environments. + +The function requires at least 3 arguments: + - the name of the Composer package that is triggering the deprecation + - the version of the package that introduced the deprecation + - the message of the deprecation + - more arguments can be provided: they will be inserted in the message using `printf()` formatting + +Example: +```php +trigger_deprecation('symfony/blockchain', '8.9', 'Using "%s" is deprecated, use "%s" instead.', 'bitcoin', 'fabcoin'); +``` + +This will generate the following message: +`Since symfony/blockchain 8.9: Using "bitcoin" is deprecated, use "fabcoin" instead.` + +While not recommended, the deprecation notices can be completely ignored by declaring an empty +`function trigger_deprecation() {}` in your application. diff --git a/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/composer.json b/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/composer.json new file mode 100644 index 0000000..5533b5c --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/composer.json @@ -0,0 +1,35 @@ +{ + "name": "symfony/deprecation-contracts", + "type": "library", + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=8.1" + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "3.6-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/function.php b/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/function.php new file mode 100644 index 0000000..2d56512 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/deprecation-contracts/function.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (!function_exists('trigger_deprecation')) { + /** + * Triggers a silenced deprecation notice. + * + * @param string $package The name of the Composer package that is triggering the deprecation + * @param string $version The version of the package that introduced the deprecation + * @param string $message The message of the deprecation + * @param mixed ...$args Values to insert in the message using printf() formatting + * + * @author Nicolas Grekas + */ + function trigger_deprecation(string $package, string $version, string $message, mixed ...$args): void + { + @trigger_error(($package || $version ? "Since $package $version: " : '').($args ? vsprintf($message, $args) : $message), \E_USER_DEPRECATED); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/CHANGELOG.md b/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/CHANGELOG.md new file mode 100644 index 0000000..7932e26 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/CHANGELOG.md @@ -0,0 +1,5 @@ +CHANGELOG +========= + +The changelog is maintained for all Symfony contracts at the following URL: +https://github.com/symfony/contracts/blob/main/CHANGELOG.md diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/Event.php b/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/Event.php new file mode 100644 index 0000000..2e7f998 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/Event.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\EventDispatcher; + +use Psr\EventDispatcher\StoppableEventInterface; + +/** + * Event is the base class for classes containing event data. + * + * This class contains no event data. It is used by events that do not pass + * state information to an event handler when an event is raised. + * + * You can call the method stopPropagation() to abort the execution of + * further listeners in your event listener. + * + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Bernhard Schussek + * @author Nicolas Grekas + */ +class Event implements StoppableEventInterface +{ + private bool $propagationStopped = false; + + public function isPropagationStopped(): bool + { + return $this->propagationStopped; + } + + /** + * Stops the propagation of the event to further event listeners. + * + * If multiple event listeners are connected to the same event, no + * further event listener will be triggered once any trigger calls + * stopPropagation(). + */ + public function stopPropagation(): void + { + $this->propagationStopped = true; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/EventDispatcherInterface.php b/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/EventDispatcherInterface.php new file mode 100644 index 0000000..2d7840d --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/EventDispatcherInterface.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\EventDispatcher; + +use Psr\EventDispatcher\EventDispatcherInterface as PsrEventDispatcherInterface; + +/** + * Allows providing hooks on domain-specific lifecycles by dispatching events. + */ +interface EventDispatcherInterface extends PsrEventDispatcherInterface +{ + /** + * Dispatches an event to all registered listeners. + * + * @template T of object + * + * @param T $event The event to pass to the event handlers/listeners + * @param string|null $eventName The name of the event to dispatch. If not supplied, + * the class of $event should be used instead. + * + * @return T The passed $event MUST be returned + */ + public function dispatch(object $event, ?string $eventName = null): object; +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/LICENSE b/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/LICENSE new file mode 100644 index 0000000..7536cae --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/README.md b/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/README.md new file mode 100644 index 0000000..332b961 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/README.md @@ -0,0 +1,9 @@ +Symfony EventDispatcher Contracts +================================= + +A set of abstractions extracted out of the Symfony components. + +Can be used to build on semantics that the Symfony components proved useful and +that already have battle tested implementations. + +See https://github.com/symfony/contracts/blob/main/README.md for more information. diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/composer.json b/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/composer.json new file mode 100644 index 0000000..d156b44 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher-contracts/composer.json @@ -0,0 +1,35 @@ +{ + "name": "symfony/event-dispatcher-contracts", + "type": "library", + "description": "Generic abstractions related to dispatching event", + "keywords": ["abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "autoload": { + "psr-4": { "Symfony\\Contracts\\EventDispatcher\\": "" } + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "3.6-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/Attribute/AsEventListener.php b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/Attribute/AsEventListener.php new file mode 100644 index 0000000..590ada9 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/Attribute/AsEventListener.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Attribute; + +/** + * Service tag to autoconfigure event listeners. + * + * @author Alexander M. Turek + */ +#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class AsEventListener +{ + /** + * @param string|null $event The event name to listen to + * @param string|null $method The method to run when the listened event is triggered + * @param int $priority The priority of this listener if several are declared for the same event + * @param string|null $dispatcher The service id of the event dispatcher to listen to + */ + public function __construct( + public ?string $event = null, + public ?string $method = null, + public int $priority = 0, + public ?string $dispatcher = null, + ) { + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/CHANGELOG.md b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/CHANGELOG.md new file mode 100644 index 0000000..76b2eab --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/CHANGELOG.md @@ -0,0 +1,96 @@ +CHANGELOG +========= + +6.0 +--- + + * Remove `LegacyEventDispatcherProxy` + +5.4 +--- + + * Allow `#[AsEventListener]` attribute on methods + +5.3 +--- + + * Add `#[AsEventListener]` attribute for declaring listeners on PHP 8 + +5.1.0 +----- + + * The `LegacyEventDispatcherProxy` class has been deprecated. + * Added an optional `dispatcher` attribute to the listener and subscriber tags in `RegisterListenerPass`. + +5.0.0 +----- + + * The signature of the `EventDispatcherInterface::dispatch()` method has been changed to `dispatch($event, string $eventName = null): object`. + * The `Event` class has been removed in favor of `Symfony\Contracts\EventDispatcher\Event`. + * The `TraceableEventDispatcherInterface` has been removed. + * The `WrappedListener` class is now final. + +4.4.0 +----- + + * `AddEventAliasesPass` has been added, allowing applications and bundles to extend the event alias mapping used by `RegisterListenersPass`. + * Made the `event` attribute of the `kernel.event_listener` tag optional for FQCN events. + +4.3.0 +----- + + * The signature of the `EventDispatcherInterface::dispatch()` method should be updated to `dispatch($event, string $eventName = null)`, not doing so is deprecated + * deprecated the `Event` class, use `Symfony\Contracts\EventDispatcher\Event` instead + +4.1.0 +----- + + * added support for invokable event listeners tagged with `kernel.event_listener` by default + * The `TraceableEventDispatcher::getOrphanedEvents()` method has been added. + * The `TraceableEventDispatcherInterface` has been deprecated. + +4.0.0 +----- + + * removed the `ContainerAwareEventDispatcher` class + * added the `reset()` method to the `TraceableEventDispatcherInterface` + +3.4.0 +----- + + * Implementing `TraceableEventDispatcherInterface` without the `reset()` method has been deprecated. + +3.3.0 +----- + + * The ContainerAwareEventDispatcher class has been deprecated. Use EventDispatcher with closure factories instead. + +3.0.0 +----- + + * The method `getListenerPriority($eventName, $listener)` has been added to the + `EventDispatcherInterface`. + * The methods `Event::setDispatcher()`, `Event::getDispatcher()`, `Event::setName()` + and `Event::getName()` have been removed. + The event dispatcher and the event name are passed to the listener call. + +2.5.0 +----- + + * added Debug\TraceableEventDispatcher (originally in HttpKernel) + * changed Debug\TraceableEventDispatcherInterface to extend EventDispatcherInterface + * added RegisterListenersPass (originally in HttpKernel) + +2.1.0 +----- + + * added TraceableEventDispatcherInterface + * added ContainerAwareEventDispatcher + * added a reference to the EventDispatcher on the Event + * added a reference to the Event name on the event + * added fluid interface to the dispatch() method which now returns the Event + object + * added GenericEvent event class + * added the possibility for subscribers to subscribe several times for the + same event + * added ImmutableEventDispatcher diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php new file mode 100644 index 0000000..48c2531 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php @@ -0,0 +1,355 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Debug; + +use Psr\EventDispatcher\StoppableEventInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Collects some data about event listeners. + * + * This event dispatcher delegates the dispatching to another one. + * + * @author Fabien Potencier + */ +class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterface +{ + /** + * @var \SplObjectStorage|null + */ + private ?\SplObjectStorage $callStack = null; + private array $wrappedListeners = []; + private array $orphanedEvents = []; + private string $currentRequestHash = ''; + + public function __construct( + private EventDispatcherInterface $dispatcher, + protected Stopwatch $stopwatch, + protected ?LoggerInterface $logger = null, + private ?RequestStack $requestStack = null, + protected readonly ?\Closure $disabled = null, + ) { + } + + public function addListener(string $eventName, callable|array $listener, int $priority = 0): void + { + $this->dispatcher->addListener($eventName, $listener, $priority); + } + + public function addSubscriber(EventSubscriberInterface $subscriber): void + { + $this->dispatcher->addSubscriber($subscriber); + } + + public function removeListener(string $eventName, callable|array $listener): void + { + if (isset($this->wrappedListeners[$eventName])) { + foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) { + if ($wrappedListener->getWrappedListener() === $listener || ($listener instanceof \Closure && $wrappedListener->getWrappedListener() == $listener)) { + $listener = $wrappedListener; + unset($this->wrappedListeners[$eventName][$index]); + break; + } + } + } + + $this->dispatcher->removeListener($eventName, $listener); + } + + public function removeSubscriber(EventSubscriberInterface $subscriber): void + { + $this->dispatcher->removeSubscriber($subscriber); + } + + public function getListeners(?string $eventName = null): array + { + return $this->dispatcher->getListeners($eventName); + } + + public function getListenerPriority(string $eventName, callable|array $listener): ?int + { + // we might have wrapped listeners for the event (if called while dispatching) + // in that case get the priority by wrapper + if (isset($this->wrappedListeners[$eventName])) { + foreach ($this->wrappedListeners[$eventName] as $wrappedListener) { + if ($wrappedListener->getWrappedListener() === $listener || ($listener instanceof \Closure && $wrappedListener->getWrappedListener() == $listener)) { + return $this->dispatcher->getListenerPriority($eventName, $wrappedListener); + } + } + } + + return $this->dispatcher->getListenerPriority($eventName, $listener); + } + + public function hasListeners(?string $eventName = null): bool + { + return $this->dispatcher->hasListeners($eventName); + } + + public function dispatch(object $event, ?string $eventName = null): object + { + if ($this->disabled?->__invoke()) { + return $this->dispatcher->dispatch($event, $eventName); + } + $eventName ??= $event::class; + + $this->callStack ??= new \SplObjectStorage(); + + $currentRequestHash = $this->currentRequestHash = $this->requestStack && ($request = $this->requestStack->getCurrentRequest()) ? spl_object_hash($request) : ''; + + if (null !== $this->logger && $event instanceof StoppableEventInterface && $event->isPropagationStopped()) { + $this->logger->debug(\sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName)); + } + + $this->preProcess($eventName); + try { + $this->beforeDispatch($eventName, $event); + try { + $e = $this->stopwatch->start($eventName, 'section'); + try { + $this->dispatcher->dispatch($event, $eventName); + } finally { + if ($e->isStarted()) { + $e->stop(); + } + } + } finally { + $this->afterDispatch($eventName, $event); + } + } finally { + $this->currentRequestHash = $currentRequestHash; + $this->postProcess($eventName); + } + + return $event; + } + + public function getCalledListeners(?Request $request = null): array + { + if (null === $this->callStack) { + return []; + } + + $hash = $request ? spl_object_hash($request) : null; + $called = []; + foreach ($this->callStack as $listener) { + [$eventName, $requestHash] = $this->callStack->getInfo(); + if (null === $hash || $hash === $requestHash) { + $called[] = $listener->getInfo($eventName); + } + } + + return $called; + } + + public function getNotCalledListeners(?Request $request = null): array + { + try { + $allListeners = $this->dispatcher instanceof EventDispatcher ? $this->getListenersWithPriority() : $this->getListenersWithoutPriority(); + } catch (\Exception $e) { + $this->logger?->info('An exception was thrown while getting the uncalled listeners.', ['exception' => $e]); + + // unable to retrieve the uncalled listeners + return []; + } + + $hash = $request ? spl_object_hash($request) : null; + $calledListeners = []; + + if (null !== $this->callStack) { + foreach ($this->callStack as $calledListener) { + [, $requestHash] = $this->callStack->getInfo(); + + if (null === $hash || $hash === $requestHash) { + $calledListeners[] = $calledListener->getWrappedListener(); + } + } + } + + $notCalled = []; + + foreach ($allListeners as $eventName => $listeners) { + foreach ($listeners as [$listener, $priority]) { + if (!\in_array($listener, $calledListeners, true)) { + if (!$listener instanceof WrappedListener) { + $listener = new WrappedListener($listener, null, $this->stopwatch, $this, $priority); + } + $notCalled[] = $listener->getInfo($eventName); + } + } + } + + uasort($notCalled, $this->sortNotCalledListeners(...)); + + return $notCalled; + } + + public function getOrphanedEvents(?Request $request = null): array + { + if ($request) { + return $this->orphanedEvents[spl_object_hash($request)] ?? []; + } + + if (!$this->orphanedEvents) { + return []; + } + + return array_merge(...array_values($this->orphanedEvents)); + } + + public function reset(): void + { + $this->callStack = null; + $this->orphanedEvents = []; + $this->currentRequestHash = ''; + } + + /** + * Proxies all method calls to the original event dispatcher. + * + * @param string $method The method name + * @param array $arguments The method arguments + */ + public function __call(string $method, array $arguments): mixed + { + return $this->dispatcher->{$method}(...$arguments); + } + + /** + * Called before dispatching the event. + */ + protected function beforeDispatch(string $eventName, object $event): void + { + } + + /** + * Called after dispatching the event. + */ + protected function afterDispatch(string $eventName, object $event): void + { + } + + private function preProcess(string $eventName): void + { + if (!$this->dispatcher->hasListeners($eventName)) { + $this->orphanedEvents[$this->currentRequestHash][] = $eventName; + + return; + } + + foreach ($this->dispatcher->getListeners($eventName) as $listener) { + $priority = $this->getListenerPriority($eventName, $listener); + $wrappedListener = new WrappedListener($listener instanceof WrappedListener ? $listener->getWrappedListener() : $listener, null, $this->stopwatch, $this); + $this->wrappedListeners[$eventName][] = $wrappedListener; + $this->dispatcher->removeListener($eventName, $listener); + $this->dispatcher->addListener($eventName, $wrappedListener, $priority); + $this->callStack[$wrappedListener] = [$eventName, $this->currentRequestHash]; + } + } + + private function postProcess(string $eventName): void + { + unset($this->wrappedListeners[$eventName]); + $skipped = false; + foreach ($this->dispatcher->getListeners($eventName) as $listener) { + if (!$listener instanceof WrappedListener) { // #12845: a new listener was added during dispatch. + continue; + } + // Unwrap listener + $priority = $this->getListenerPriority($eventName, $listener); + $this->dispatcher->removeListener($eventName, $listener); + $this->dispatcher->addListener($eventName, $listener->getWrappedListener(), $priority); + + if (null !== $this->logger) { + $context = ['event' => $eventName, 'listener' => $listener->getPretty()]; + } + + if ($listener->wasCalled()) { + $this->logger?->debug('Notified event "{event}" to listener "{listener}".', $context); + } else { + unset($this->callStack[$listener]); + } + + if (null !== $this->logger && $skipped) { + $this->logger->debug('Listener "{listener}" was not called for event "{event}".', $context); + } + + if ($listener->stoppedPropagation()) { + $this->logger?->debug('Listener "{listener}" stopped propagation of the event "{event}".', $context); + + $skipped = true; + } + } + } + + private function sortNotCalledListeners(array $a, array $b): int + { + if (0 !== $cmp = strcmp($a['event'], $b['event'])) { + return $cmp; + } + + if (\is_int($a['priority']) && !\is_int($b['priority'])) { + return 1; + } + + if (!\is_int($a['priority']) && \is_int($b['priority'])) { + return -1; + } + + if ($a['priority'] === $b['priority']) { + return 0; + } + + if ($a['priority'] > $b['priority']) { + return -1; + } + + return 1; + } + + private function getListenersWithPriority(): array + { + $result = []; + + $allListeners = new \ReflectionProperty(EventDispatcher::class, 'listeners'); + + foreach ($allListeners->getValue($this->dispatcher) as $eventName => $listenersByPriority) { + foreach ($listenersByPriority as $priority => $listeners) { + foreach ($listeners as $listener) { + $result[$eventName][] = [$listener, $priority]; + } + } + } + + return $result; + } + + private function getListenersWithoutPriority(): array + { + $result = []; + + foreach ($this->getListeners() as $eventName => $listeners) { + foreach ($listeners as $listener) { + $result[$eventName][] = [$listener, null]; + } + } + + return $result; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/Debug/WrappedListener.php b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/Debug/WrappedListener.php new file mode 100644 index 0000000..b83115b --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/Debug/WrappedListener.php @@ -0,0 +1,143 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Debug; + +use Psr\EventDispatcher\StoppableEventInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Component\VarDumper\Caster\ClassStub; + +/** + * @author Fabien Potencier + */ +final class WrappedListener +{ + private string|array|object $listener; + private ?\Closure $optimizedListener; + private string $name; + private bool $called = false; + private bool $stoppedPropagation = false; + private string $pretty; + private string $callableRef; + private ClassStub|string $stub; + private static bool $hasClassStub; + + public function __construct( + callable|array $listener, + ?string $name, + private Stopwatch $stopwatch, + private ?EventDispatcherInterface $dispatcher = null, + private ?int $priority = null, + ) { + $this->listener = $listener; + $this->optimizedListener = $listener instanceof \Closure ? $listener : (\is_callable($listener) ? $listener(...) : null); + + if (\is_array($listener)) { + [$this->name, $this->callableRef] = $this->parseListener($listener); + $this->pretty = $this->name.'::'.$listener[1]; + $this->callableRef .= '::'.$listener[1]; + } elseif ($listener instanceof \Closure) { + $r = new \ReflectionFunction($listener); + if ($r->isAnonymous()) { + $this->pretty = $this->name = 'closure'; + } elseif ($class = $r->getClosureCalledClass()) { + $this->name = $class->name; + $this->pretty = $this->name.'::'.$r->name; + } else { + $this->pretty = $this->name = $r->name; + } + } elseif (\is_string($listener)) { + $this->pretty = $this->name = $listener; + } else { + $this->name = get_debug_type($listener); + $this->pretty = $this->name.'::__invoke'; + $this->callableRef = $listener::class.'::__invoke'; + } + + if (null !== $name) { + $this->name = $name; + } + + self::$hasClassStub ??= class_exists(ClassStub::class); + } + + public function getWrappedListener(): callable|array + { + return $this->listener; + } + + public function wasCalled(): bool + { + return $this->called; + } + + public function stoppedPropagation(): bool + { + return $this->stoppedPropagation; + } + + public function getPretty(): string + { + return $this->pretty; + } + + public function getInfo(string $eventName): array + { + $this->stub ??= self::$hasClassStub ? new ClassStub($this->pretty.'()', $this->callableRef ?? $this->listener) : $this->pretty.'()'; + + return [ + 'event' => $eventName, + 'priority' => $this->priority ??= $this->dispatcher?->getListenerPriority($eventName, $this->listener), + 'pretty' => $this->pretty, + 'stub' => $this->stub, + ]; + } + + public function __invoke(object $event, string $eventName, EventDispatcherInterface $dispatcher): void + { + $dispatcher = $this->dispatcher ?: $dispatcher; + + $this->called = true; + $this->priority ??= $dispatcher->getListenerPriority($eventName, $this->listener); + + $e = $this->stopwatch->start($this->name, 'event_listener'); + + try { + ($this->optimizedListener ?? $this->listener)($event, $eventName, $dispatcher); + } finally { + if ($e->isStarted()) { + $e->stop(); + } + } + + if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) { + $this->stoppedPropagation = true; + } + } + + private function parseListener(array $listener): array + { + if ($listener[0] instanceof \Closure) { + foreach ((new \ReflectionFunction($listener[0]))->getAttributes(\Closure::class) as $attribute) { + if ($name = $attribute->getArguments()['name'] ?? false) { + return [$name, $attribute->getArguments()['class'] ?? $name]; + } + } + } + + if (\is_object($listener[0])) { + return [get_debug_type($listener[0]), $listener[0]::class]; + } + + return [$listener[0], $listener[0]]; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/DependencyInjection/AddEventAliasesPass.php b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/DependencyInjection/AddEventAliasesPass.php new file mode 100644 index 0000000..5308992 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/DependencyInjection/AddEventAliasesPass.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * This pass allows bundles to extend the list of event aliases. + * + * @author Alexander M. Turek + */ +class AddEventAliasesPass implements CompilerPassInterface +{ + public function __construct( + private array $eventAliases, + ) { + } + + public function process(ContainerBuilder $container): void + { + $eventAliases = $container->hasParameter('event_dispatcher.event_aliases') ? $container->getParameter('event_dispatcher.event_aliases') : []; + + $container->setParameter( + 'event_dispatcher.event_aliases', + array_merge($eventAliases, $this->eventAliases) + ); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php new file mode 100644 index 0000000..a0267ce --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php @@ -0,0 +1,213 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\DependencyInjection; + +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Contracts\EventDispatcher\Event; + +/** + * Compiler pass to register tagged services for an event dispatcher. + */ +class RegisterListenersPass implements CompilerPassInterface +{ + private array $hotPathEvents = []; + private array $noPreloadEvents = []; + + /** + * @return $this + */ + public function setHotPathEvents(array $hotPathEvents): static + { + $this->hotPathEvents = array_flip($hotPathEvents); + + return $this; + } + + /** + * @return $this + */ + public function setNoPreloadEvents(array $noPreloadEvents): static + { + $this->noPreloadEvents = array_flip($noPreloadEvents); + + return $this; + } + + public function process(ContainerBuilder $container): void + { + if (!$container->hasDefinition('event_dispatcher') && !$container->hasAlias('event_dispatcher')) { + return; + } + + $aliases = []; + + if ($container->hasParameter('event_dispatcher.event_aliases')) { + $aliases = $container->getParameter('event_dispatcher.event_aliases'); + } + + $globalDispatcherDefinition = $container->findDefinition('event_dispatcher'); + + foreach ($container->findTaggedServiceIds('kernel.event_listener', true) as $id => $events) { + $noPreload = 0; + + foreach ($events as $event) { + $priority = $event['priority'] ?? 0; + + if (!isset($event['event'])) { + if ($container->getDefinition($id)->hasTag('kernel.event_subscriber')) { + continue; + } + + $event['method'] ??= '__invoke'; + $event['event'] = $this->getEventFromTypeDeclaration($container, $id, $event['method']); + } + + $event['event'] = $aliases[$event['event']] ?? $event['event']; + + if (!isset($event['method'])) { + $event['method'] = 'on'.preg_replace_callback([ + '/(?<=\b|_)[a-z]/i', + '/[^a-z0-9]/i', + ], fn ($matches) => strtoupper($matches[0]), $event['event']); + $event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']); + + if (null !== ($class = $container->getDefinition($id)->getClass()) && ($r = $container->getReflectionClass($class, false)) && !$r->hasMethod($event['method'])) { + if (!$r->hasMethod('__invoke')) { + throw new InvalidArgumentException(\sprintf('None of the "%s" or "__invoke" methods exist for the service "%s". Please define the "method" attribute on "kernel.event_listener" tags.', $event['method'], $id)); + } + + $event['method'] = '__invoke'; + } + } + + $dispatcherDefinition = $globalDispatcherDefinition; + if (isset($event['dispatcher'])) { + $dispatcherDefinition = $container->findDefinition($event['dispatcher']); + } + + $dispatcherDefinition->addMethodCall('addListener', [$event['event'], [new ServiceClosureArgument(new Reference($id)), $event['method']], $priority]); + + if (isset($this->hotPathEvents[$event['event']])) { + $container->getDefinition($id)->addTag('container.hot_path'); + } elseif (isset($this->noPreloadEvents[$event['event']])) { + ++$noPreload; + } + } + + if ($noPreload && \count($events) === $noPreload) { + $container->getDefinition($id)->addTag('container.no_preload'); + } + } + + $extractingDispatcher = new ExtractingEventDispatcher(); + + foreach ($container->findTaggedServiceIds('kernel.event_subscriber', true) as $id => $tags) { + $def = $container->getDefinition($id); + + // We must assume that the class value has been correctly filled, even if the service is created by a factory + $class = $def->getClass(); + + if (!$r = $container->getReflectionClass($class)) { + throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + } + if (!$r->isSubclassOf(EventSubscriberInterface::class)) { + throw new InvalidArgumentException(\sprintf('Service "%s" must implement interface "%s".', $id, EventSubscriberInterface::class)); + } + $class = $r->name; + + $dispatcherDefinitions = []; + foreach ($tags as $attributes) { + if (!isset($attributes['dispatcher']) || isset($dispatcherDefinitions[$attributes['dispatcher']])) { + continue; + } + + $dispatcherDefinitions[$attributes['dispatcher']] = $container->findDefinition($attributes['dispatcher']); + } + + if (!$dispatcherDefinitions) { + $dispatcherDefinitions = [$globalDispatcherDefinition]; + } + + $noPreload = 0; + ExtractingEventDispatcher::$aliases = $aliases; + ExtractingEventDispatcher::$subscriber = $class; + $extractingDispatcher->addSubscriber($extractingDispatcher); + foreach ($extractingDispatcher->listeners as $args) { + $args[1] = [new ServiceClosureArgument(new Reference($id)), $args[1]]; + foreach ($dispatcherDefinitions as $dispatcherDefinition) { + $dispatcherDefinition->addMethodCall('addListener', $args); + } + + if (isset($this->hotPathEvents[$args[0]])) { + $container->getDefinition($id)->addTag('container.hot_path'); + } elseif (isset($this->noPreloadEvents[$args[0]])) { + ++$noPreload; + } + } + if ($noPreload && \count($extractingDispatcher->listeners) === $noPreload) { + $container->getDefinition($id)->addTag('container.no_preload'); + } + $extractingDispatcher->listeners = []; + ExtractingEventDispatcher::$aliases = []; + } + } + + private function getEventFromTypeDeclaration(ContainerBuilder $container, string $id, string $method): string + { + if ( + null === ($class = $container->getDefinition($id)->getClass()) + || !($r = $container->getReflectionClass($class, false)) + || !$r->hasMethod($method) + || 1 > ($m = $r->getMethod($method))->getNumberOfParameters() + || !($type = $m->getParameters()[0]->getType()) instanceof \ReflectionNamedType + || $type->isBuiltin() + || Event::class === ($name = $type->getName()) + ) { + throw new InvalidArgumentException(\sprintf('Service "%s" must define the "event" attribute on "kernel.event_listener" tags.', $id)); + } + + return $name; + } +} + +/** + * @internal + */ +class ExtractingEventDispatcher extends EventDispatcher implements EventSubscriberInterface +{ + public array $listeners = []; + + public static array $aliases = []; + public static string $subscriber; + + public function addListener(string $eventName, callable|array $listener, int $priority = 0): void + { + $this->listeners[] = [$eventName, $listener[1], $priority]; + } + + public static function getSubscribedEvents(): array + { + $events = []; + + foreach ([self::$subscriber, 'getSubscribedEvents']() as $eventName => $params) { + $events[self::$aliases[$eventName] ?? $eventName] = $params; + } + + return $events; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/EventDispatcher.php b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/EventDispatcher.php new file mode 100644 index 0000000..43bc16b --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/EventDispatcher.php @@ -0,0 +1,256 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +use Psr\EventDispatcher\StoppableEventInterface; +use Symfony\Component\EventDispatcher\Debug\WrappedListener; + +/** + * The EventDispatcherInterface is the central point of Symfony's event listener system. + * + * Listeners are registered on the manager and events are dispatched through the + * manager. + * + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Bernhard Schussek + * @author Fabien Potencier + * @author Jordi Boggiano + * @author Jordan Alliot + * @author Nicolas Grekas + */ +class EventDispatcher implements EventDispatcherInterface +{ + private array $listeners = []; + private array $sorted = []; + private array $optimized; + + public function __construct() + { + if (__CLASS__ === static::class) { + $this->optimized = []; + } + } + + public function dispatch(object $event, ?string $eventName = null): object + { + $eventName ??= $event::class; + + if (isset($this->optimized)) { + $listeners = $this->optimized[$eventName] ?? (empty($this->listeners[$eventName]) ? [] : $this->optimizeListeners($eventName)); + } else { + $listeners = $this->getListeners($eventName); + } + + if ($listeners) { + $this->callListeners($listeners, $eventName, $event); + } + + return $event; + } + + public function getListeners(?string $eventName = null): array + { + if (null !== $eventName) { + if (empty($this->listeners[$eventName])) { + return []; + } + + if (!isset($this->sorted[$eventName])) { + $this->sortListeners($eventName); + } + + return $this->sorted[$eventName]; + } + + foreach ($this->listeners as $eventName => $eventListeners) { + if (!isset($this->sorted[$eventName])) { + $this->sortListeners($eventName); + } + } + + return array_filter($this->sorted); + } + + public function getListenerPriority(string $eventName, callable|array $listener): ?int + { + if (empty($this->listeners[$eventName])) { + return null; + } + + if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) { + $listener[0] = $listener[0](); + $listener[1] ??= '__invoke'; + } + + foreach ($this->listeners[$eventName] as $priority => &$listeners) { + foreach ($listeners as &$v) { + if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure && 2 >= \count($v)) { + $v[0] = $v[0](); + $v[1] ??= '__invoke'; + } + if ($v === $listener || ($listener instanceof \Closure && $v == $listener)) { + return $priority; + } + } + } + + return null; + } + + public function hasListeners(?string $eventName = null): bool + { + if (null !== $eventName) { + return !empty($this->listeners[$eventName]); + } + + foreach ($this->listeners as $eventListeners) { + if ($eventListeners) { + return true; + } + } + + return false; + } + + public function addListener(string $eventName, callable|array $listener, int $priority = 0): void + { + $this->listeners[$eventName][$priority][] = $listener; + unset($this->sorted[$eventName], $this->optimized[$eventName]); + } + + public function removeListener(string $eventName, callable|array $listener): void + { + if (empty($this->listeners[$eventName])) { + return; + } + + if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) { + $listener[0] = $listener[0](); + $listener[1] ??= '__invoke'; + } + + foreach ($this->listeners[$eventName] as $priority => &$listeners) { + foreach ($listeners as $k => &$v) { + if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure && 2 >= \count($v)) { + $v[0] = $v[0](); + $v[1] ??= '__invoke'; + } + if ($v === $listener || ($listener instanceof \Closure && $v == $listener)) { + unset($listeners[$k], $this->sorted[$eventName], $this->optimized[$eventName]); + } + } + + if (!$listeners) { + unset($this->listeners[$eventName][$priority]); + } + } + } + + public function addSubscriber(EventSubscriberInterface $subscriber): void + { + foreach ($subscriber->getSubscribedEvents() as $eventName => $params) { + if (\is_string($params)) { + $this->addListener($eventName, [$subscriber, $params]); + } elseif (\is_string($params[0])) { + $this->addListener($eventName, [$subscriber, $params[0]], $params[1] ?? 0); + } else { + foreach ($params as $listener) { + $this->addListener($eventName, [$subscriber, $listener[0]], $listener[1] ?? 0); + } + } + } + } + + public function removeSubscriber(EventSubscriberInterface $subscriber): void + { + foreach ($subscriber->getSubscribedEvents() as $eventName => $params) { + if (\is_array($params) && \is_array($params[0])) { + foreach ($params as $listener) { + $this->removeListener($eventName, [$subscriber, $listener[0]]); + } + } else { + $this->removeListener($eventName, [$subscriber, \is_string($params) ? $params : $params[0]]); + } + } + } + + /** + * Triggers the listeners of an event. + * + * This method can be overridden to add functionality that is executed + * for each listener. + * + * @param callable[] $listeners The event listeners + * @param string $eventName The name of the event to dispatch + * @param object $event The event object to pass to the event handlers/listeners + */ + protected function callListeners(iterable $listeners, string $eventName, object $event): void + { + $stoppable = $event instanceof StoppableEventInterface; + + foreach ($listeners as $listener) { + if ($stoppable && $event->isPropagationStopped()) { + break; + } + $listener($event, $eventName, $this); + } + } + + /** + * Sorts the internal list of listeners for the given event by priority. + */ + private function sortListeners(string $eventName): void + { + krsort($this->listeners[$eventName]); + $this->sorted[$eventName] = []; + + foreach ($this->listeners[$eventName] as &$listeners) { + foreach ($listeners as &$listener) { + if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) { + $listener[0] = $listener[0](); + $listener[1] ??= '__invoke'; + } + $this->sorted[$eventName][] = $listener; + } + } + } + + /** + * Optimizes the internal list of listeners for the given event by priority. + */ + private function optimizeListeners(string $eventName): array + { + krsort($this->listeners[$eventName]); + $this->optimized[$eventName] = []; + + foreach ($this->listeners[$eventName] as &$listeners) { + foreach ($listeners as &$listener) { + $closure = &$this->optimized[$eventName][]; + if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) { + $closure = static function (...$args) use (&$listener, &$closure) { + if ($listener[0] instanceof \Closure) { + $listener[0] = $listener[0](); + $listener[1] ??= '__invoke'; + } + ($closure = $listener(...))(...$args); + }; + } else { + $closure = $listener instanceof WrappedListener ? $listener : $listener(...); + } + } + } + + return $this->optimized[$eventName]; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/EventDispatcherInterface.php b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/EventDispatcherInterface.php new file mode 100644 index 0000000..99f8b1a --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/EventDispatcherInterface.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface as ContractsEventDispatcherInterface; + +/** + * The EventDispatcherInterface is the central point of Symfony's event listener system. + * Listeners are registered on the manager and events are dispatched through the + * manager. + * + * @author Bernhard Schussek + */ +interface EventDispatcherInterface extends ContractsEventDispatcherInterface +{ + /** + * Adds an event listener that listens on the specified events. + * + * @param int $priority The higher this value, the earlier an event + * listener will be triggered in the chain (defaults to 0) + */ + public function addListener(string $eventName, callable $listener, int $priority = 0): void; + + /** + * Adds an event subscriber. + * + * The subscriber is asked for all the events it is + * interested in and added as a listener for these events. + */ + public function addSubscriber(EventSubscriberInterface $subscriber): void; + + /** + * Removes an event listener from the specified events. + */ + public function removeListener(string $eventName, callable $listener): void; + + public function removeSubscriber(EventSubscriberInterface $subscriber): void; + + /** + * Gets the listeners of a specific event or all listeners sorted by descending priority. + * + * @return array + */ + public function getListeners(?string $eventName = null): array; + + /** + * Gets the listener priority for a specific event. + * + * Returns null if the event or the listener does not exist. + */ + public function getListenerPriority(string $eventName, callable $listener): ?int; + + /** + * Checks whether an event has any registered listeners. + */ + public function hasListeners(?string $eventName = null): bool; +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/EventSubscriberInterface.php b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/EventSubscriberInterface.php new file mode 100644 index 0000000..2085e42 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/EventSubscriberInterface.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * An EventSubscriber knows itself what events it is interested in. + * If an EventSubscriber is added to an EventDispatcherInterface, the manager invokes + * {@link getSubscribedEvents} and registers the subscriber as a listener for all + * returned events. + * + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Bernhard Schussek + */ +interface EventSubscriberInterface +{ + /** + * Returns an array of event names this subscriber wants to listen to. + * + * The array keys are event names and the value can be: + * + * * The method name to call (priority defaults to 0) + * * An array composed of the method name to call and the priority + * * An array of arrays composed of the method names to call and respective + * priorities, or 0 if unset + * + * For instance: + * + * * ['eventName' => 'methodName'] + * * ['eventName' => ['methodName', $priority]] + * * ['eventName' => [['methodName1', $priority], ['methodName2']]] + * + * The code must not depend on runtime state as it will only be called at compile time. + * All logic depending on runtime state must be put into the individual methods handling the events. + * + * @return array> + */ + public static function getSubscribedEvents(); +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/GenericEvent.php b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/GenericEvent.php new file mode 100644 index 0000000..87f61ad --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/GenericEvent.php @@ -0,0 +1,155 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +use Symfony\Contracts\EventDispatcher\Event; + +/** + * Event encapsulation class. + * + * Encapsulates events thus decoupling the observer from the subject they encapsulate. + * + * @author Drak + * + * @implements \ArrayAccess + * @implements \IteratorAggregate + */ +class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate +{ + /** + * Encapsulate an event with $subject and $arguments. + * + * @param mixed $subject The subject of the event, usually an object or a callable + * @param array $arguments Arguments to store in the event + */ + public function __construct( + protected mixed $subject = null, + protected array $arguments = [], + ) { + } + + /** + * Getter for subject property. + */ + public function getSubject(): mixed + { + return $this->subject; + } + + /** + * Get argument by key. + * + * @throws \InvalidArgumentException if key is not found + */ + public function getArgument(string $key): mixed + { + if ($this->hasArgument($key)) { + return $this->arguments[$key]; + } + + throw new \InvalidArgumentException(\sprintf('Argument "%s" not found.', $key)); + } + + /** + * Add argument to event. + * + * @return $this + */ + public function setArgument(string $key, mixed $value): static + { + $this->arguments[$key] = $value; + + return $this; + } + + /** + * Getter for all arguments. + */ + public function getArguments(): array + { + return $this->arguments; + } + + /** + * Set args property. + * + * @return $this + */ + public function setArguments(array $args = []): static + { + $this->arguments = $args; + + return $this; + } + + /** + * Has argument. + */ + public function hasArgument(string $key): bool + { + return \array_key_exists($key, $this->arguments); + } + + /** + * ArrayAccess for argument getter. + * + * @param string $key Array key + * + * @throws \InvalidArgumentException if key does not exist in $this->args + */ + public function offsetGet(mixed $key): mixed + { + return $this->getArgument($key); + } + + /** + * ArrayAccess for argument setter. + * + * @param string $key Array key to set + */ + public function offsetSet(mixed $key, mixed $value): void + { + $this->setArgument($key, $value); + } + + /** + * ArrayAccess for unset argument. + * + * @param string $key Array key + */ + public function offsetUnset(mixed $key): void + { + if ($this->hasArgument($key)) { + unset($this->arguments[$key]); + } + } + + /** + * ArrayAccess has argument. + * + * @param string $key Array key + */ + public function offsetExists(mixed $key): bool + { + return $this->hasArgument($key); + } + + /** + * IteratorAggregate for iterating over the object like an array. + * + * @return \ArrayIterator + */ + public function getIterator(): \ArrayIterator + { + return new \ArrayIterator($this->arguments); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php new file mode 100644 index 0000000..a6d078e --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * A read-only proxy for an event dispatcher. + * + * @author Bernhard Schussek + */ +class ImmutableEventDispatcher implements EventDispatcherInterface +{ + public function __construct( + private EventDispatcherInterface $dispatcher, + ) { + } + + public function dispatch(object $event, ?string $eventName = null): object + { + return $this->dispatcher->dispatch($event, $eventName); + } + + public function addListener(string $eventName, callable|array $listener, int $priority = 0): never + { + throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.'); + } + + public function addSubscriber(EventSubscriberInterface $subscriber): never + { + throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.'); + } + + public function removeListener(string $eventName, callable|array $listener): never + { + throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.'); + } + + public function removeSubscriber(EventSubscriberInterface $subscriber): never + { + throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.'); + } + + public function getListeners(?string $eventName = null): array + { + return $this->dispatcher->getListeners($eventName); + } + + public function getListenerPriority(string $eventName, callable|array $listener): ?int + { + return $this->dispatcher->getListenerPriority($eventName, $listener); + } + + public function hasListeners(?string $eventName = null): bool + { + return $this->dispatcher->hasListeners($eventName); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/LICENSE b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/LICENSE new file mode 100644 index 0000000..0138f8f --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/README.md b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/README.md new file mode 100644 index 0000000..dcdb68d --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/README.md @@ -0,0 +1,15 @@ +EventDispatcher Component +========================= + +The EventDispatcher component provides tools that allow your application +components to communicate with each other by dispatching events and listening to +them. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/event_dispatcher.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/lib/SymfonyMailer/vendor/symfony/event-dispatcher/composer.json b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/composer.json new file mode 100644 index 0000000..598bbdc --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/event-dispatcher/composer.json @@ -0,0 +1,47 @@ +{ + "name": "symfony/event-dispatcher", + "type": "library", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "require-dev": { + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0", + "psr/log": "^1|^2|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\EventDispatcher\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/CHANGELOG.md b/lib/SymfonyMailer/vendor/symfony/mailer/CHANGELOG.md new file mode 100644 index 0000000..3816cc4 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/CHANGELOG.md @@ -0,0 +1,130 @@ +CHANGELOG +========= + +7.3 +--- + + * Add DSN param `retry_period` to override default email transport retry period + * Add `Dsn::getBooleanOption()` + * Add DSN param `source_ip` to allow binding to a (specific) IPv4 or IPv6 address. + * Add DSN param `require_tls` to enforce use of TLS/STARTTLS + * Add `DkimSignedMessageListener`, `SmimeEncryptedMessageListener`, and `SmimeSignedMessageListener` + +7.2 +--- + + * Deprecate `TransportFactoryTestCase`, extend `AbstractTransportFactoryTestCase` instead + + The `testIncompleteDsnException()` test is no longer provided by default. If you make use of it by implementing the `incompleteDsnProvider()` data providers, + you now need to use the `IncompleteDsnTestTrait`. + + * Make `TransportFactoryTestCase` compatible with PHPUnit 10+ + * Support unicode email addresses such as "dømi@dømi.example" + +7.1 +--- + + * Dispatch Postmark's "406 - Inactive recipient" API error code as a `PostmarkDeliveryEvent` instead of throwing an exception + * Add DSN param `auto_tls` to disable automatic STARTTLS + * Add support for allowing some users even if `recipients` is defined in `EnvelopeListener` + +7.0 +--- + + * Remove the OhMySmtp bridge in favor of the MailPace bridge + +6.4 +--- + + * Add DSN parameter `peer_fingerprint` to verify TLS certificate fingerprint + * Change the default port for the `mailjet+smtp` transport from 465 to 587 + +6.3 +--- + + * Add `MessageEvent::reject()` to allow rejecting an email before sending it + * Change the default port for the `mailgun+smtp` transport from 465 to 587 + * Add `$authenticators` parameter in `EsmtpTransport` constructor and `EsmtpTransport::setAuthenticators()` + to allow overriding of default eSMTP authenticators + +6.2.7 +----- + + * [BC BREAK] The following data providers for `TransportFactoryTestCase` are now static: + `supportsProvider()`, `createProvider()`, `unsupportedSchemeProvider()`and `incompleteDsnProvider()` + +6.2 +--- + + * Add a `mailer:test` command + * Add `SentMessageEvent` and `FailedMessageEvent` events + +6.1 +--- + + * Make `start()` and `stop()` methods public on `SmtpTransport` + * Improve extensibility of `EsmtpTransport` + +6.0 +--- + + * The `HttpTransportException` class takes a string at first argument + +5.4 +--- + + * Enable the mailer to operate on any PSR-14-compatible event dispatcher + +5.3 +--- + + * added the `mailer` monolog channel and set it on all transport definitions + +5.2.0 +----- + + * added `NativeTransportFactory` to configure a transport based on php.ini settings + * added `local_domain`, `restart_threshold`, `restart_threshold_sleep` and `ping_threshold` options for `smtp` + * added `command` option for `sendmail` + +4.4.0 +----- + + * [BC BREAK] changed the `NullTransport` DSN from `smtp://null` to `null://null` + * [BC BREAK] renamed `SmtpEnvelope` to `Envelope`, renamed `DelayedSmtpEnvelope` to + `DelayedEnvelope` + * [BC BREAK] changed the syntax for failover and roundrobin DSNs + + Before: + + dummy://a || dummy://b (for failover) + dummy://a && dummy://b (for roundrobin) + + After: + + failover(dummy://a dummy://b) + roundrobin(dummy://a dummy://b) + + * added support for multiple transports on a `Mailer` instance + * [BC BREAK] removed the `auth_mode` DSN option (it is now always determined automatically) + * STARTTLS cannot be enabled anymore (it is used automatically if TLS is disabled and the server supports STARTTLS) + * [BC BREAK] Removed the `encryption` DSN option (use `smtps` instead) + * Added support for the `smtps` protocol (does the same as using `smtp` and port `465`) + * Added PHPUnit constraints + * Added `MessageDataCollector` + * Added `MessageEvents` and `MessageLoggerListener` to allow collecting sent emails + * [BC BREAK] `TransportInterface` has a new `__toString()` method + * [BC BREAK] Classes `AbstractApiTransport` and `AbstractHttpTransport` moved under `Transport` sub-namespace. + * [BC BREAK] Transports depend on `Symfony\Contracts\EventDispatcher\EventDispatcherInterface` + instead of `Symfony\Component\EventDispatcher\EventDispatcherInterface`. + * Added possibility to register custom transport for dsn by implementing + `Symfony\Component\Mailer\Transport\TransportFactoryInterface` and tagging with `mailer.transport_factory` tag in DI. + * Added `Symfony\Component\Mailer\Test\TransportFactoryTestCase` to ease testing custom transport factories. + * Added `SentMessage::getDebug()` and `TransportExceptionInterface::getDebug` to help debugging + * Made `MessageEvent` final + * add DSN parameter `verify_peer` to disable TLS peer verification for SMTP transport + +4.3.0 +----- + + * Added the component. diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Command/MailerTestCommand.php b/lib/SymfonyMailer/vendor/symfony/mailer/Command/MailerTestCommand.php new file mode 100644 index 0000000..8e00f62 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Command/MailerTestCommand.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Command; + +use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Mailer\Transport\TransportInterface; +use Symfony\Component\Mime\Email; + +/** + * A console command to test Mailer transports. + */ +#[AsCommand(name: 'mailer:test', description: 'Test Mailer transports by sending an email')] +final class MailerTestCommand extends Command +{ + public function __construct(private TransportInterface $transport) + { + parent::__construct(); + } + + protected function configure(): void + { + $this + ->addArgument('to', InputArgument::REQUIRED, 'The recipient of the message') + ->addOption('from', null, InputOption::VALUE_REQUIRED, 'The sender of the message', 'from@example.org') + ->addOption('subject', null, InputOption::VALUE_REQUIRED, 'The subject of the message', 'Testing transport') + ->addOption('body', null, InputOption::VALUE_REQUIRED, 'The body of the message', 'Testing body') + ->addOption('transport', null, InputOption::VALUE_REQUIRED, 'The transport to be used') + ->setHelp(<<<'EOF' +The %command.name% command tests a Mailer transport by sending a simple email message: + +php %command.full_name% to@example.com + +You can also specify a specific transport: + + php %command.full_name% to@example.com --transport=transport_name + +Note that this command bypasses the Messenger bus if configured. + +EOF + ); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $message = (new Email()) + ->to($input->getArgument('to')) + ->from($input->getOption('from')) + ->subject($input->getOption('subject')) + ->text($input->getOption('body')) + ; + if ($transport = $input->getOption('transport')) { + $message->getHeaders()->addTextHeader('X-Transport', $transport); + } + + $this->transport->send($message); + + return 0; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/DataCollector/MessageDataCollector.php b/lib/SymfonyMailer/vendor/symfony/mailer/DataCollector/MessageDataCollector.php new file mode 100644 index 0000000..5c9ac35 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/DataCollector/MessageDataCollector.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\DataCollector; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DataCollector; +use Symfony\Component\Mailer\Event\MessageEvents; +use Symfony\Component\Mailer\EventListener\MessageLoggerListener; + +/** + * @author Fabien Potencier + */ +final class MessageDataCollector extends DataCollector +{ + private MessageEvents $events; + + public function __construct(MessageLoggerListener $logger) + { + $this->events = $logger->getEvents(); + } + + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void + { + $this->data['events'] = $this->events; + } + + public function getEvents(): MessageEvents + { + return $this->data['events']; + } + + /** + * @internal + */ + public function base64Encode(string $data): string + { + return base64_encode($data); + } + + public function reset(): void + { + $this->data = []; + } + + public function getName(): string + { + return 'mailer'; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/DelayedEnvelope.php b/lib/SymfonyMailer/vendor/symfony/mailer/DelayedEnvelope.php new file mode 100644 index 0000000..18a8612 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/DelayedEnvelope.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer; + +use Symfony\Component\Mailer\Exception\LogicException; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Header\Headers; +use Symfony\Component\Mime\Message; + +/** + * @author Fabien Potencier + * + * @internal + */ +final class DelayedEnvelope extends Envelope +{ + private bool $senderSet = false; + private bool $recipientsSet = false; + + public function __construct( + private Message $message, + ) { + } + + public function setSender(Address $sender): void + { + parent::setSender($sender); + + $this->senderSet = true; + } + + public function getSender(): Address + { + if (!$this->senderSet) { + parent::setSender(self::getSenderFromHeaders($this->message->getHeaders())); + } + + return parent::getSender(); + } + + public function setRecipients(array $recipients): void + { + parent::setRecipients($recipients); + + $this->recipientsSet = (bool) parent::getRecipients(); + } + + /** + * @return Address[] + */ + public function getRecipients(): array + { + if ($this->recipientsSet) { + return parent::getRecipients(); + } + + return self::getRecipientsFromHeaders($this->message->getHeaders()); + } + + private static function getRecipientsFromHeaders(Headers $headers): array + { + $recipients = []; + foreach (['to', 'cc', 'bcc'] as $name) { + foreach ($headers->all($name) as $header) { + foreach ($header->getAddresses() as $address) { + $recipients[] = $address; + } + } + } + + return $recipients; + } + + private static function getSenderFromHeaders(Headers $headers): Address + { + if ($sender = $headers->get('Sender')) { + return $sender->getAddress(); + } + if ($return = $headers->get('Return-Path')) { + return $return->getAddress(); + } + if ($from = $headers->get('From')) { + return $from->getAddresses()[0]; + } + + throw new LogicException('Unable to determine the sender of the message.'); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Envelope.php b/lib/SymfonyMailer/vendor/symfony/mailer/Envelope.php new file mode 100644 index 0000000..42fec5b --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Envelope.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer; + +use Symfony\Component\Mailer\Exception\InvalidArgumentException; +use Symfony\Component\Mailer\Exception\LogicException; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +class Envelope +{ + private Address $sender; + private array $recipients = []; + + /** + * @param Address[] $recipients + */ + public function __construct(Address $sender, array $recipients) + { + $this->setSender($sender); + $this->setRecipients($recipients); + } + + public static function create(RawMessage $message): self + { + if (RawMessage::class === $message::class) { + throw new LogicException('Cannot send a RawMessage instance without an explicit Envelope.'); + } + + return new DelayedEnvelope($message); + } + + public function setSender(Address $sender): void + { + // to ensure deliverability of bounce emails independent of UTF-8 capabilities of SMTP servers + if (!preg_match('/^[^@\x80-\xFF]++@/', $sender->getAddress())) { + throw new InvalidArgumentException(\sprintf('Invalid sender "%s": non-ASCII characters not supported in local-part of email.', $sender->getAddress())); + } + $this->sender = $sender; + } + + /** + * @return Address Returns a "mailbox" as specified by RFC 2822 + * Must be converted to an "addr-spec" when used as a "MAIL FROM" value in SMTP (use getAddress()) + */ + public function getSender(): Address + { + return $this->sender; + } + + /** + * @param Address[] $recipients + */ + public function setRecipients(array $recipients): void + { + if (!$recipients) { + throw new InvalidArgumentException('An envelope must have at least one recipient.'); + } + + $this->recipients = []; + foreach ($recipients as $recipient) { + if (!$recipient instanceof Address) { + throw new InvalidArgumentException(\sprintf('A recipient must be an instance of "%s" (got "%s").', Address::class, get_debug_type($recipient))); + } + $this->recipients[] = new Address($recipient->getAddress()); + } + } + + /** + * @return Address[] + */ + public function getRecipients(): array + { + return $this->recipients; + } + + /** + * Returns true if any address' localpart contains at least one + * non-ASCII character, and false if all addresses have all-ASCII + * localparts. + * + * This helps to decide whether to the SMTPUTF8 extensions (RFC + * 6530 and following) for any given message. + * + * The SMTPUTF8 extension is strictly required if any address + * contains a non-ASCII character in its localpart. If non-ASCII + * is only used in domains (e.g. horst@freiherr-von-mühlhausen.de) + * then it is possible to send the message using IDN encoding + * instead of SMTPUTF8. The most common software will display the + * message as intended. + */ + public function anyAddressHasUnicodeLocalpart(): bool + { + if ($this->getSender()->hasUnicodeLocalpart()) { + return true; + } + foreach ($this->getRecipients() as $r) { + if ($r->hasUnicodeLocalpart()) { + return true; + } + } + + return false; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Event/FailedMessageEvent.php b/lib/SymfonyMailer/vendor/symfony/mailer/Event/FailedMessageEvent.php new file mode 100644 index 0000000..4808c65 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Event/FailedMessageEvent.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Event; + +use Symfony\Component\Mime\RawMessage; +use Symfony\Contracts\EventDispatcher\Event; + +/** + * @author Fabien Potencier + */ +final class FailedMessageEvent extends Event +{ + public function __construct( + private RawMessage $message, + private \Throwable $error, + ) { + } + + public function getMessage(): RawMessage + { + return $this->message; + } + + public function getError(): \Throwable + { + return $this->error; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Event/MessageEvent.php b/lib/SymfonyMailer/vendor/symfony/mailer/Event/MessageEvent.php new file mode 100644 index 0000000..524bd69 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Event/MessageEvent.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Event; + +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Exception\LogicException; +use Symfony\Component\Messenger\Stamp\StampInterface; +use Symfony\Component\Mime\RawMessage; +use Symfony\Contracts\EventDispatcher\Event; + +/** + * Allows the transformation of a Message and the Envelope before the email is sent. + * + * @author Fabien Potencier + */ +final class MessageEvent extends Event +{ + private bool $rejected = false; + + /** @var StampInterface[] */ + private array $stamps = []; + + public function __construct( + private RawMessage $message, + private Envelope $envelope, + private string $transport, + private bool $queued = false, + ) { + } + + public function getMessage(): RawMessage + { + return $this->message; + } + + public function setMessage(RawMessage $message): void + { + $this->message = $message; + } + + public function getEnvelope(): Envelope + { + return $this->envelope; + } + + public function setEnvelope(Envelope $envelope): void + { + $this->envelope = $envelope; + } + + public function getTransport(): string + { + return $this->transport; + } + + public function isQueued(): bool + { + return $this->queued; + } + + public function isRejected(): bool + { + return $this->rejected; + } + + public function reject(): void + { + $this->rejected = true; + $this->stopPropagation(); + } + + public function addStamp(StampInterface $stamp): void + { + if (!$this->queued) { + throw new LogicException(\sprintf('Cannot call "%s()" on a message that is not meant to be queued.', __METHOD__)); + } + + $this->stamps[] = $stamp; + } + + /** + * @return StampInterface[] + */ + public function getStamps(): array + { + if (!$this->queued) { + throw new LogicException(\sprintf('Cannot call "%s()" on a message that is not meant to be queued.', __METHOD__)); + } + + return $this->stamps; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Event/MessageEvents.php b/lib/SymfonyMailer/vendor/symfony/mailer/Event/MessageEvents.php new file mode 100644 index 0000000..2b438e3 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Event/MessageEvents.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Event; + +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +class MessageEvents +{ + /** + * @var MessageEvent[] + */ + private array $events = []; + + /** + * @var array + */ + private array $transports = []; + + public function add(MessageEvent $event): void + { + $this->events[] = $event; + $this->transports[$event->getTransport()] = true; + } + + public function getTransports(): array + { + return array_keys($this->transports); + } + + /** + * @return MessageEvent[] + */ + public function getEvents(?string $name = null): array + { + if (null === $name) { + return $this->events; + } + + $events = []; + foreach ($this->events as $event) { + if ($name === $event->getTransport()) { + $events[] = $event; + } + } + + return $events; + } + + /** + * @return RawMessage[] + */ + public function getMessages(?string $name = null): array + { + $events = $this->getEvents($name); + $messages = []; + foreach ($events as $event) { + $messages[] = $event->getMessage(); + } + + return $messages; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Event/SentMessageEvent.php b/lib/SymfonyMailer/vendor/symfony/mailer/Event/SentMessageEvent.php new file mode 100644 index 0000000..a412a9f --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Event/SentMessageEvent.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Event; + +use Symfony\Component\Mailer\SentMessage; +use Symfony\Contracts\EventDispatcher\Event; + +/** + * @author Fabien Potencier + */ +final class SentMessageEvent extends Event +{ + public function __construct(private SentMessage $message) + { + } + + public function getMessage(): SentMessage + { + return $this->message; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/DkimSignedMessageListener.php b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/DkimSignedMessageListener.php new file mode 100644 index 0000000..cc16a72 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/DkimSignedMessageListener.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mime\Crypto\DkimSigner; +use Symfony\Component\Mime\Message; + +/** + * Signs messages using DKIM. + * + * @author Elías Fernández + */ +class DkimSignedMessageListener implements EventSubscriberInterface +{ + public function __construct( + private DkimSigner $signer, + ) { + } + + public function onMessage(MessageEvent $event): void + { + $message = $event->getMessage(); + if (!$message instanceof Message) { + return; + } + $event->setMessage($this->signer->sign($message)); + } + + public static function getSubscribedEvents(): array + { + return [ + MessageEvent::class => ['onMessage', -128], + ]; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/EnvelopeListener.php b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/EnvelopeListener.php new file mode 100644 index 0000000..9a1e39c --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/EnvelopeListener.php @@ -0,0 +1,96 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Message; + +/** + * Manipulates the Envelope of a Message. + * + * @author Fabien Potencier + * @author Grégoire Pineau + */ +class EnvelopeListener implements EventSubscriberInterface +{ + private ?Address $sender = null; + + /** + * @var Address[]|null + */ + private ?array $recipients = null; + + /** + * @param array $recipients + * @param string[] $allowedRecipients An array of regex to match the allowed recipients + */ + public function __construct( + Address|string|null $sender = null, + ?array $recipients = null, + private array $allowedRecipients = [], + ) { + if (null !== $sender) { + $this->sender = Address::create($sender); + } + if (null !== $recipients) { + $this->recipients = Address::createArray($recipients); + } + } + + public function onMessage(MessageEvent $event): void + { + if ($this->sender) { + $event->getEnvelope()->setSender($this->sender); + + $message = $event->getMessage(); + if ($message instanceof Message) { + if (!$message->getHeaders()->has('Sender') && !$message->getHeaders()->has('From')) { + $message->getHeaders()->addMailboxHeader('Sender', $this->sender); + } + } + } + + if ($this->recipients) { + $recipients = $this->recipients; + if ($this->allowedRecipients) { + foreach ($event->getEnvelope()->getRecipients() as $recipient) { + foreach ($this->allowedRecipients as $allowedRecipient) { + if (!preg_match('{\A'.$allowedRecipient.'\z}', $recipient->getAddress())) { + continue; + } + // dedup + foreach ($recipients as $r) { + if ($r->getName() === $recipient->getName() && $r->getAddress() === $recipient->getAddress()) { + continue 2; + } + } + + $recipients[] = $recipient; + continue 2; + } + } + } + + $event->getEnvelope()->setRecipients($recipients); + } + } + + public static function getSubscribedEvents(): array + { + return [ + // should be the last one to allow header changes by other listeners first + MessageEvent::class => ['onMessage', -255], + ]; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/MessageListener.php b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/MessageListener.php new file mode 100644 index 0000000..906e410 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/MessageListener.php @@ -0,0 +1,133 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mailer\Exception\InvalidArgumentException; +use Symfony\Component\Mailer\Exception\RuntimeException; +use Symfony\Component\Mime\BodyRendererInterface; +use Symfony\Component\Mime\Header\Headers; +use Symfony\Component\Mime\Header\MailboxListHeader; +use Symfony\Component\Mime\Message; + +/** + * Manipulates the headers and the body of a Message. + * + * @author Fabien Potencier + */ +class MessageListener implements EventSubscriberInterface +{ + public const HEADER_SET_IF_EMPTY = 1; + public const HEADER_ADD = 2; + public const HEADER_REPLACE = 3; + public const DEFAULT_RULES = [ + 'from' => self::HEADER_SET_IF_EMPTY, + 'return-path' => self::HEADER_SET_IF_EMPTY, + 'reply-to' => self::HEADER_ADD, + 'to' => self::HEADER_SET_IF_EMPTY, + 'cc' => self::HEADER_ADD, + 'bcc' => self::HEADER_ADD, + ]; + + private array $headerRules = []; + + public function __construct( + private ?Headers $headers = null, + private ?BodyRendererInterface $renderer = null, + array $headerRules = self::DEFAULT_RULES, + ) { + foreach ($headerRules as $headerName => $rule) { + $this->addHeaderRule($headerName, $rule); + } + } + + public function addHeaderRule(string $headerName, int $rule): void + { + if ($rule < 1 || $rule > 3) { + throw new InvalidArgumentException(\sprintf('The "%d" rule is not supported.', $rule)); + } + + $this->headerRules[strtolower($headerName)] = $rule; + } + + public function onMessage(MessageEvent $event): void + { + $message = $event->getMessage(); + if (!$message instanceof Message) { + return; + } + + $this->setHeaders($message); + $this->renderMessage($message); + } + + private function setHeaders(Message $message): void + { + if (!$this->headers) { + return; + } + + $headers = $message->getHeaders(); + foreach ($this->headers->all() as $name => $header) { + if (!$headers->has($name)) { + $headers->add($header); + + continue; + } + + switch ($this->headerRules[$name] ?? self::HEADER_SET_IF_EMPTY) { + case self::HEADER_SET_IF_EMPTY: + break; + + case self::HEADER_REPLACE: + $headers->remove($name); + $headers->add($header); + + break; + + case self::HEADER_ADD: + if (!Headers::isUniqueHeader($name)) { + $headers->add($header); + + break; + } + + $h = $headers->get($name); + if (!$h instanceof MailboxListHeader) { + throw new RuntimeException(\sprintf('Unable to set header "%s".', $name)); + } + + Headers::checkHeaderClass($header); + foreach ($header->getAddresses() as $address) { + $h->addAddress($address); + } + } + } + } + + private function renderMessage(Message $message): void + { + if (!$this->renderer) { + return; + } + + $this->renderer->render($message); + } + + public static function getSubscribedEvents(): array + { + return [ + MessageEvent::class => 'onMessage', + ]; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/MessageLoggerListener.php b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/MessageLoggerListener.php new file mode 100644 index 0000000..3a3283f --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/MessageLoggerListener.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mailer\Event\MessageEvents; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Logs Messages. + * + * @author Fabien Potencier + */ +class MessageLoggerListener implements EventSubscriberInterface, ResetInterface +{ + private MessageEvents $events; + + public function __construct( + protected ?\Closure $disabled = null, + ) { + $this->events = new MessageEvents(); + } + + public function reset(): void + { + $this->events = new MessageEvents(); + } + + public function onMessage(MessageEvent $event): void + { + if ($this->disabled?->__invoke()) { + return; + } + + $this->events->add($event); + } + + public function getEvents(): MessageEvents + { + return $this->events; + } + + public static function getSubscribedEvents(): array + { + return [ + MessageEvent::class => ['onMessage', -255], + ]; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/MessengerTransportListener.php b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/MessengerTransportListener.php new file mode 100644 index 0000000..8cf8cc8 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/MessengerTransportListener.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Messenger\Stamp\TransportNamesStamp; +use Symfony\Component\Mime\Message; + +/** + * Allows messages to be sent to specific Messenger transports via the "X-Bus-Transport" MIME header. + * + * @author Fabien Potencier + */ +final class MessengerTransportListener implements EventSubscriberInterface +{ + public function onMessage(MessageEvent $event): void + { + if (!$event->isQueued()) { + return; + } + + $message = $event->getMessage(); + if (!$message instanceof Message || !$message->getHeaders()->has('X-Bus-Transport')) { + return; + } + + $names = $message->getHeaders()->get('X-Bus-Transport')->getBody(); + $names = array_map('trim', explode(',', $names)); + $event->addStamp(new TransportNamesStamp($names)); + $message->getHeaders()->remove('X-Bus-Transport'); + } + + public static function getSubscribedEvents(): array + { + return [ + MessageEvent::class => 'onMessage', + ]; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/SmimeCertificateRepositoryInterface.php b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/SmimeCertificateRepositoryInterface.php new file mode 100644 index 0000000..b5d9081 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/SmimeCertificateRepositoryInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\EventListener; + +/** + * Encrypts messages using S/MIME. + * + * @author Florent Morselli + */ +interface SmimeCertificateRepositoryInterface +{ + /** + * @return ?string The path to the certificate. null if not found + */ + public function findCertificatePathFor(string $email): ?string; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/SmimeEncryptedMessageListener.php b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/SmimeEncryptedMessageListener.php new file mode 100644 index 0000000..24bc574 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/SmimeEncryptedMessageListener.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mime\Crypto\SMimeEncrypter; +use Symfony\Component\Mime\Message; + +/** + * Encrypts messages using S/MIME. + * + * @author Elías Fernández + */ +final class SmimeEncryptedMessageListener implements EventSubscriberInterface +{ + public function __construct( + private readonly SmimeCertificateRepositoryInterface $smimeRepository, + private readonly ?int $cipher = null, + ) { + } + + public function onMessage(MessageEvent $event): void + { + $message = $event->getMessage(); + if (!$message instanceof Message) { + return; + } + if (!$message->getHeaders()->has('X-SMime-Encrypt')) { + return; + } + $message->getHeaders()->remove('X-SMime-Encrypt'); + $certificatePaths = []; + foreach ($event->getEnvelope()->getRecipients() as $recipient) { + $certificatePath = $this->smimeRepository->findCertificatePathFor($recipient->getAddress()); + if (null === $certificatePath) { + return; + } + $certificatePaths[] = $certificatePath; + } + if (0 === \count($certificatePaths)) { + return; + } + $encrypter = new SMimeEncrypter($certificatePaths, $this->cipher); + + $event->setMessage($encrypter->encrypt($message)); + } + + public static function getSubscribedEvents(): array + { + return [ + MessageEvent::class => ['onMessage', -128], + ]; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/SmimeSignedMessageListener.php b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/SmimeSignedMessageListener.php new file mode 100644 index 0000000..d94578f --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/EventListener/SmimeSignedMessageListener.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mime\Crypto\SMimeSigner; +use Symfony\Component\Mime\Message; + +/** + * Signs messages using S/MIME. + * + * @author Elías Fernández + */ +class SmimeSignedMessageListener implements EventSubscriberInterface +{ + public function __construct( + private SMimeSigner $signer, + ) { + } + + public function onMessage(MessageEvent $event): void + { + $message = $event->getMessage(); + if (!$message instanceof Message) { + return; + } + + $event->setMessage($this->signer->sign($message)); + } + + public static function getSubscribedEvents(): array + { + return [ + MessageEvent::class => ['onMessage', -128], + ]; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Exception/ExceptionInterface.php b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/ExceptionInterface.php new file mode 100644 index 0000000..2f0f3a6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * Exception interface for all exceptions thrown by the component. + * + * @author Fabien Potencier + */ +interface ExceptionInterface extends \Throwable +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Exception/HttpTransportException.php b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/HttpTransportException.php new file mode 100644 index 0000000..1fd5d52 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/HttpTransportException.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Fabien Potencier + */ +class HttpTransportException extends TransportException +{ + public function __construct( + string $message, + private ResponseInterface $response, + int $code = 0, + ?\Throwable $previous = null, + ) { + parent::__construct($message, $code, $previous); + } + + public function getResponse(): ResponseInterface + { + return $this->response; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Exception/IncompleteDsnException.php b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/IncompleteDsnException.php new file mode 100644 index 0000000..f2618b6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/IncompleteDsnException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * @author Konstantin Myakshin + */ +class IncompleteDsnException extends InvalidArgumentException +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Exception/InvalidArgumentException.php b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..ba53334 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/InvalidArgumentException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * @author Fabien Potencier + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Exception/LogicException.php b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/LogicException.php new file mode 100644 index 0000000..487c0a3 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/LogicException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * @author Fabien Potencier + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Exception/RuntimeException.php b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/RuntimeException.php new file mode 100644 index 0000000..44b79cc --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/RuntimeException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * @author Fabien Potencier + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Exception/TransportException.php b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/TransportException.php new file mode 100644 index 0000000..ea538d6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/TransportException.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * @author Fabien Potencier + */ +class TransportException extends RuntimeException implements TransportExceptionInterface +{ + private string $debug = ''; + + public function getDebug(): string + { + return $this->debug; + } + + public function appendDebug(string $debug): void + { + $this->debug .= $debug; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Exception/TransportExceptionInterface.php b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/TransportExceptionInterface.php new file mode 100644 index 0000000..4318f5c --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/TransportExceptionInterface.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * @author Fabien Potencier + */ +interface TransportExceptionInterface extends ExceptionInterface +{ + public function getDebug(): string; + + public function appendDebug(string $debug): void; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Exception/UnexpectedResponseException.php b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/UnexpectedResponseException.php new file mode 100644 index 0000000..e779df1 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/UnexpectedResponseException.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +class UnexpectedResponseException extends TransportException +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Exception/UnsupportedSchemeException.php b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/UnsupportedSchemeException.php new file mode 100644 index 0000000..6746bc7 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Exception/UnsupportedSchemeException.php @@ -0,0 +1,121 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +use Symfony\Component\Mailer\Bridge; +use Symfony\Component\Mailer\Transport\Dsn; + +/** + * @author Konstantin Myakshin + */ +class UnsupportedSchemeException extends LogicException +{ + private const SCHEME_TO_PACKAGE_MAP = [ + 'ahasend' => [ + 'class' => Bridge\AhaSend\Transport\AhaSendTransportFactory::class, + 'package' => 'symfony/aha-send-mailer', + ], + 'azure' => [ + 'class' => Bridge\Azure\Transport\AzureTransportFactory::class, + 'package' => 'symfony/azure-mailer', + ], + 'brevo' => [ + 'class' => Bridge\Brevo\Transport\BrevoTransportFactory::class, + 'package' => 'symfony/brevo-mailer', + ], + 'gmail' => [ + 'class' => Bridge\Google\Transport\GmailTransportFactory::class, + 'package' => 'symfony/google-mailer', + ], + 'infobip' => [ + 'class' => Bridge\Infobip\Transport\InfobipTransportFactory::class, + 'package' => 'symfony/infobip-mailer', + ], + 'mailersend' => [ + 'class' => Bridge\MailerSend\Transport\MailerSendTransportFactory::class, + 'package' => 'symfony/mailersend-mailer', + ], + 'mailgun' => [ + 'class' => Bridge\Mailgun\Transport\MailgunTransportFactory::class, + 'package' => 'symfony/mailgun-mailer', + ], + 'mailjet' => [ + 'class' => Bridge\Mailjet\Transport\MailjetTransportFactory::class, + 'package' => 'symfony/mailjet-mailer', + ], + 'mailomat' => [ + 'class' => Bridge\Mailomat\Transport\MailomatTransportFactory::class, + 'package' => 'symfony/mailomat-mailer', + ], + 'mailpace' => [ + 'class' => Bridge\MailPace\Transport\MailPaceTransportFactory::class, + 'package' => 'symfony/mail-pace-mailer', + ], + 'mandrill' => [ + 'class' => Bridge\Mailchimp\Transport\MandrillTransportFactory::class, + 'package' => 'symfony/mailchimp-mailer', + ], + 'postal' => [ + 'class' => Bridge\Postal\Transport\PostalTransportFactory::class, + 'package' => 'symfony/postal-mailer', + ], + 'postmark' => [ + 'class' => Bridge\Postmark\Transport\PostmarkTransportFactory::class, + 'package' => 'symfony/postmark-mailer', + ], + 'mailtrap' => [ + 'class' => Bridge\Mailtrap\Transport\MailtrapTransportFactory::class, + 'package' => 'symfony/mailtrap-mailer', + ], + 'resend' => [ + 'class' => Bridge\Resend\Transport\ResendTransportFactory::class, + 'package' => 'symfony/resend-mailer', + ], + 'scaleway' => [ + 'class' => Bridge\Scaleway\Transport\ScalewayTransportFactory::class, + 'package' => 'symfony/scaleway-mailer', + ], + 'sendgrid' => [ + 'class' => Bridge\Sendgrid\Transport\SendgridTransportFactory::class, + 'package' => 'symfony/sendgrid-mailer', + ], + 'ses' => [ + 'class' => Bridge\Amazon\Transport\SesTransportFactory::class, + 'package' => 'symfony/amazon-mailer', + ], + 'sweego' => [ + 'class' => Bridge\Sweego\Transport\SweegoTransportFactory::class, + 'package' => 'symfony/sweego-mailer', + ], + ]; + + public function __construct(Dsn $dsn, ?string $name = null, array $supported = []) + { + $provider = $dsn->getScheme(); + if (false !== $pos = strpos($provider, '+')) { + $provider = substr($provider, 0, $pos); + } + $package = self::SCHEME_TO_PACKAGE_MAP[$provider] ?? null; + if ($package && !class_exists($package['class'])) { + parent::__construct(\sprintf('Unable to send emails via "%s" as the bridge is not installed. Try running "composer require %s".', $provider, $package['package'])); + + return; + } + + $message = \sprintf('The "%s" scheme is not supported', $dsn->getScheme()); + if ($name && $supported) { + $message .= \sprintf('; supported schemes for mailer "%s" are: "%s"', $name, implode('", "', $supported)); + } + + parent::__construct($message.'.'); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Header/MetadataHeader.php b/lib/SymfonyMailer/vendor/symfony/mailer/Header/MetadataHeader.php new file mode 100644 index 0000000..7c7b13f --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Header/MetadataHeader.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Header; + +use Symfony\Component\Mime\Header\UnstructuredHeader; + +/** + * @author Kevin Bond + */ +final class MetadataHeader extends UnstructuredHeader +{ + public function __construct( + private string $key, + string $value, + ) { + parent::__construct('X-Metadata-'.$key, $value); + } + + public function getKey(): string + { + return $this->key; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Header/TagHeader.php b/lib/SymfonyMailer/vendor/symfony/mailer/Header/TagHeader.php new file mode 100644 index 0000000..7115cae --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Header/TagHeader.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Header; + +use Symfony\Component\Mime\Header\UnstructuredHeader; + +/** + * @author Kevin Bond + */ +final class TagHeader extends UnstructuredHeader +{ + public function __construct(string $value) + { + parent::__construct('X-Tag', $value); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/LICENSE b/lib/SymfonyMailer/vendor/symfony/mailer/LICENSE new file mode 100644 index 0000000..f37c76b --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2019-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Mailer.php b/lib/SymfonyMailer/vendor/symfony/mailer/Mailer.php new file mode 100644 index 0000000..2c9cff4 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Mailer.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mailer\Messenger\SendEmailMessage; +use Symfony\Component\Mailer\Transport\TransportInterface; +use Symfony\Component\Messenger\Exception\HandlerFailedException; +use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +final class Mailer implements MailerInterface +{ + public function __construct( + private TransportInterface $transport, + private ?MessageBusInterface $bus = null, + private ?EventDispatcherInterface $dispatcher = null, + ) { + } + + public function send(RawMessage $message, ?Envelope $envelope = null): void + { + if (null === $this->bus) { + $this->transport->send($message, $envelope); + + return; + } + + $stamps = []; + if (null !== $this->dispatcher) { + // The dispatched event here has `queued` set to `true`; the goal is NOT to render the message, but to let + // listeners do something before a message is sent to the queue. + // We are using a cloned message as we still want to dispatch the **original** message, not the one modified by listeners. + // That's because the listeners will run again when the email is sent via Messenger by the transport (see `AbstractTransport`). + // Listeners should act depending on the `$queued` argument of the `MessageEvent` instance. + $clonedMessage = clone $message; + $clonedEnvelope = null !== $envelope ? clone $envelope : Envelope::create($clonedMessage); + $event = new MessageEvent($clonedMessage, $clonedEnvelope, (string) $this->transport, true); + $this->dispatcher->dispatch($event); + $stamps = $event->getStamps(); + + if ($event->isRejected()) { + return; + } + } + + try { + $this->bus->dispatch(new SendEmailMessage($message, $envelope), $stamps); + } catch (HandlerFailedException $e) { + foreach ($e->getWrappedExceptions() as $nested) { + if ($nested instanceof TransportExceptionInterface) { + throw $nested; + } + } + throw $e; + } + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/MailerInterface.php b/lib/SymfonyMailer/vendor/symfony/mailer/MailerInterface.php new file mode 100644 index 0000000..ebac4b5 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/MailerInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer; + +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mime\RawMessage; + +/** + * Interface for mailers able to send emails synchronously and/or asynchronously. + * + * Implementations must support synchronous and asynchronous sending. + * + * @author Fabien Potencier + */ +interface MailerInterface +{ + /** + * @throws TransportExceptionInterface + */ + public function send(RawMessage $message, ?Envelope $envelope = null): void; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Messenger/MessageHandler.php b/lib/SymfonyMailer/vendor/symfony/mailer/Messenger/MessageHandler.php new file mode 100644 index 0000000..06fbdb0 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Messenger/MessageHandler.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Messenger; + +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mailer\Transport\TransportInterface; + +/** + * @author Fabien Potencier + */ +class MessageHandler +{ + public function __construct( + private TransportInterface $transport, + ) { + } + + public function __invoke(SendEmailMessage $message): ?SentMessage + { + return $this->transport->send($message->getMessage(), $message->getEnvelope()); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Messenger/SendEmailMessage.php b/lib/SymfonyMailer/vendor/symfony/mailer/Messenger/SendEmailMessage.php new file mode 100644 index 0000000..a2043ec --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Messenger/SendEmailMessage.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Messenger; + +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +class SendEmailMessage +{ + public function __construct( + private RawMessage $message, + private ?Envelope $envelope = null, + ) { + } + + public function getMessage(): RawMessage + { + return $this->message; + } + + public function getEnvelope(): ?Envelope + { + return $this->envelope; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/README.md b/lib/SymfonyMailer/vendor/symfony/mailer/README.md new file mode 100644 index 0000000..050d04e --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/README.md @@ -0,0 +1,87 @@ +Mailer Component +================ + +The Mailer component helps sending emails. + +Getting Started +--------------- + +```bash +composer require symfony/mailer +``` + +```php +use Symfony\Component\Mailer\Transport; +use Symfony\Component\Mailer\Mailer; +use Symfony\Component\Mime\Email; + +$transport = Transport::fromDsn('smtp://localhost'); +$mailer = new Mailer($transport); + +$email = (new Email()) + ->from('hello@example.com') + ->to('you@example.com') + //->cc('cc@example.com') + //->bcc('bcc@example.com') + //->replyTo('fabien@example.com') + //->priority(Email::PRIORITY_HIGH) + ->subject('Time for Symfony Mailer!') + ->text('Sending emails is fun again!') + ->html('

See Twig integration for better HTML integration!

'); + +$mailer->send($email); +``` + +To enable the Twig integration of the Mailer, require `symfony/twig-bridge` and +set up the `BodyRenderer`: + +```php +use Symfony\Bridge\Twig\Mime\BodyRenderer; +use Symfony\Bridge\Twig\Mime\TemplatedEmail; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\Mailer\EventListener\MessageListener; +use Symfony\Component\Mailer\Mailer; +use Symfony\Component\Mailer\Transport; +use Twig\Environment as TwigEnvironment; + +$twig = new TwigEnvironment(...); +$messageListener = new MessageListener(null, new BodyRenderer($twig)); + +$eventDispatcher = new EventDispatcher(); +$eventDispatcher->addSubscriber($messageListener); + +$transport = Transport::fromDsn('smtp://localhost', $eventDispatcher); +$mailer = new Mailer($transport, null, $eventDispatcher); + +$email = (new TemplatedEmail()) + // ... + ->htmlTemplate('emails/signup.html.twig') + ->context([ + 'expiration_date' => new \DateTimeImmutable('+7 days'), + 'username' => 'foo', + ]) +; +$mailer->send($email); +``` + +Sponsor +------- + +The Mailer component for Symfony 7.2 is [backed][1] by: + + * [Sweego][2], a European email and SMS sending platform for developers and product builders. Easily create, deliver, and monitor your emails and notifications. + +Help Symfony by [sponsoring][3] its development! + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/mailer.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) + +[1]: https://symfony.com/backers +[2]: https://www.sweego.io/ +[3]: https://symfony.com/sponsor diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/SentMessage.php b/lib/SymfonyMailer/vendor/symfony/mailer/SentMessage.php new file mode 100644 index 0000000..bee79d1 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/SentMessage.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer; + +use Symfony\Component\Mime\Message; +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +class SentMessage +{ + private RawMessage $original; + private RawMessage $raw; + private string $messageId; + private string $debug = ''; + + /** + * @internal + */ + public function __construct( + RawMessage $message, + private Envelope $envelope, + ) { + $message->ensureValidity(); + + $this->original = $message; + + if ($message instanceof Message) { + $message = clone $message; + $headers = $message->getHeaders(); + if (!$headers->has('Message-ID')) { + $headers->addIdHeader('Message-ID', $message->generateMessageId()); + } + $this->messageId = $headers->get('Message-ID')->getId(); + $this->raw = new RawMessage($message->toIterable()); + } else { + $this->raw = $message; + } + } + + public function getMessage(): RawMessage + { + return $this->raw; + } + + public function getOriginalMessage(): RawMessage + { + return $this->original; + } + + public function getEnvelope(): Envelope + { + return $this->envelope; + } + + public function setMessageId(string $id): void + { + $this->messageId = $id; + } + + public function getMessageId(): string + { + return $this->messageId; + } + + public function getDebug(): string + { + return $this->debug; + } + + public function appendDebug(string $debug): void + { + $this->debug .= $debug; + } + + public function toString(): string + { + return $this->raw->toString(); + } + + public function toIterable(): iterable + { + return $this->raw->toIterable(); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Test/AbstractTransportFactoryTestCase.php b/lib/SymfonyMailer/vendor/symfony/mailer/Test/AbstractTransportFactoryTestCase.php new file mode 100644 index 0000000..c378948 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Test/AbstractTransportFactoryTestCase.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Test; + +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\TestCase; +use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; +use Symfony\Component\Mailer\Transport\Dsn; +use Symfony\Component\Mailer\Transport\TransportFactoryInterface; +use Symfony\Component\Mailer\Transport\TransportInterface; + +abstract class AbstractTransportFactoryTestCase extends TestCase +{ + protected const USER = 'u$er'; + protected const PASSWORD = 'pa$s'; + + abstract public function getFactory(): TransportFactoryInterface; + + /** + * @psalm-return iterable + */ + abstract public static function supportsProvider(): iterable; + + /** + * @psalm-return iterable + */ + abstract public static function createProvider(): iterable; + + /** + * @psalm-return iterable + */ + abstract public static function unsupportedSchemeProvider(): iterable; + + /** + * @dataProvider supportsProvider + */ + #[DataProvider('supportsProvider')] + public function testSupports(Dsn $dsn, bool $supports) + { + $factory = $this->getFactory(); + + $this->assertSame($supports, $factory->supports($dsn)); + } + + /** + * @dataProvider createProvider + */ + #[DataProvider('createProvider')] + public function testCreate(Dsn $dsn, TransportInterface $transport) + { + $factory = $this->getFactory(); + + $this->assertEquals($transport, $factory->create($dsn)); + if (str_contains('smtp', $dsn->getScheme())) { + $this->assertStringMatchesFormat($dsn->getScheme().'://%S'.$dsn->getHost().'%S', (string) $transport); + } + } + + /** + * @dataProvider unsupportedSchemeProvider + */ + #[DataProvider('unsupportedSchemeProvider')] + public function testUnsupportedSchemeException(Dsn $dsn, ?string $message = null) + { + $factory = $this->getFactory(); + + $this->expectException(UnsupportedSchemeException::class); + if (null !== $message) { + $this->expectExceptionMessage($message); + } + + $factory->create($dsn); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Test/Constraint/EmailCount.php b/lib/SymfonyMailer/vendor/symfony/mailer/Test/Constraint/EmailCount.php new file mode 100644 index 0000000..c63889d --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Test/Constraint/EmailCount.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\Mailer\Event\MessageEvents; + +final class EmailCount extends Constraint +{ + public function __construct( + private int $expectedValue, + private ?string $transport = null, + private bool $queued = false, + ) { + } + + public function toString(): string + { + return \sprintf('%shas %s "%d" emails', $this->transport ? $this->transport.' ' : '', $this->queued ? 'queued' : 'sent', $this->expectedValue); + } + + /** + * @param MessageEvents $events + */ + protected function matches($events): bool + { + return $this->expectedValue === $this->countEmails($events); + } + + /** + * @param MessageEvents $events + */ + protected function failureDescription($events): string + { + return \sprintf('the Transport %s (%d %s)', $this->toString(), $this->countEmails($events), $this->queued ? 'queued' : 'sent'); + } + + private function countEmails(MessageEvents $events): int + { + $count = 0; + foreach ($events->getEvents($this->transport) as $event) { + if ( + ($this->queued && $event->isQueued()) + || (!$this->queued && !$event->isQueued()) + ) { + ++$count; + } + } + + return $count; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Test/Constraint/EmailIsQueued.php b/lib/SymfonyMailer/vendor/symfony/mailer/Test/Constraint/EmailIsQueued.php new file mode 100644 index 0000000..46436aa --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Test/Constraint/EmailIsQueued.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\Mailer\Event\MessageEvent; + +final class EmailIsQueued extends Constraint +{ + public function toString(): string + { + return 'is queued'; + } + + /** + * @param MessageEvent $event + */ + protected function matches($event): bool + { + return $event->isQueued(); + } + + /** + * @param MessageEvent $event + */ + protected function failureDescription($event): string + { + return 'the Email '.$this->toString(); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Test/IncompleteDsnTestTrait.php b/lib/SymfonyMailer/vendor/symfony/mailer/Test/IncompleteDsnTestTrait.php new file mode 100644 index 0000000..fbf322a --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Test/IncompleteDsnTestTrait.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Test; + +use PHPUnit\Framework\Attributes\DataProvider; +use Symfony\Component\Mailer\Exception\IncompleteDsnException; +use Symfony\Component\Mailer\Transport\Dsn; + +trait IncompleteDsnTestTrait +{ + /** + * @psalm-return iterable + */ + abstract public static function incompleteDsnProvider(): iterable; + + /** + * @dataProvider incompleteDsnProvider + */ + #[DataProvider('incompleteDsnProvider')] + public function testIncompleteDsnException(Dsn $dsn) + { + $factory = $this->getFactory(); + + $this->expectException(IncompleteDsnException::class); + $factory->create($dsn); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Test/TransportFactoryTestCase.php b/lib/SymfonyMailer/vendor/symfony/mailer/Test/TransportFactoryTestCase.php new file mode 100644 index 0000000..782bba3 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Test/TransportFactoryTestCase.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Test; + +use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Transport\Dsn; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * A test case to ease testing Transport Factory. + * + * @author Konstantin Myakshin + * + * @deprecated since Symfony 7.2, use AbstractTransportFactoryTestCase instead + */ +abstract class TransportFactoryTestCase extends AbstractTransportFactoryTestCase +{ + use IncompleteDsnTestTrait; + + protected EventDispatcherInterface $dispatcher; + protected HttpClientInterface $client; + protected LoggerInterface $logger; + + /** + * @psalm-return iterable + */ + public static function unsupportedSchemeProvider(): iterable + { + return []; + } + + /** + * @psalm-return iterable + */ + public static function incompleteDsnProvider(): iterable + { + return []; + } + + protected function getDispatcher(): EventDispatcherInterface + { + return $this->dispatcher ??= $this->createMock(EventDispatcherInterface::class); + } + + protected function getClient(): HttpClientInterface + { + return $this->client ??= $this->createMock(HttpClientInterface::class); + } + + protected function getLogger(): LoggerInterface + { + return $this->logger ??= $this->createMock(LoggerInterface::class); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport.php new file mode 100644 index 0000000..773603d --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport.php @@ -0,0 +1,201 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Bridge\AhaSend\Transport\AhaSendTransportFactory; +use Symfony\Component\Mailer\Bridge\Amazon\Transport\SesTransportFactory; +use Symfony\Component\Mailer\Bridge\Azure\Transport\AzureTransportFactory; +use Symfony\Component\Mailer\Bridge\Brevo\Transport\BrevoTransportFactory; +use Symfony\Component\Mailer\Bridge\Google\Transport\GmailTransportFactory; +use Symfony\Component\Mailer\Bridge\Infobip\Transport\InfobipTransportFactory; +use Symfony\Component\Mailer\Bridge\Mailchimp\Transport\MandrillTransportFactory; +use Symfony\Component\Mailer\Bridge\MailerSend\Transport\MailerSendTransportFactory; +use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunTransportFactory; +use Symfony\Component\Mailer\Bridge\Mailjet\Transport\MailjetTransportFactory; +use Symfony\Component\Mailer\Bridge\Mailomat\Transport\MailomatTransportFactory; +use Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceTransportFactory; +use Symfony\Component\Mailer\Bridge\Mailtrap\Transport\MailtrapTransportFactory; +use Symfony\Component\Mailer\Bridge\Postal\Transport\PostalTransportFactory; +use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkTransportFactory; +use Symfony\Component\Mailer\Bridge\Resend\Transport\ResendTransportFactory; +use Symfony\Component\Mailer\Bridge\Scaleway\Transport\ScalewayTransportFactory; +use Symfony\Component\Mailer\Bridge\Sendgrid\Transport\SendgridTransportFactory; +use Symfony\Component\Mailer\Bridge\Sweego\Transport\SweegoTransportFactory; +use Symfony\Component\Mailer\Exception\InvalidArgumentException; +use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; +use Symfony\Component\Mailer\Transport\Dsn; +use Symfony\Component\Mailer\Transport\FailoverTransport; +use Symfony\Component\Mailer\Transport\NativeTransportFactory; +use Symfony\Component\Mailer\Transport\NullTransportFactory; +use Symfony\Component\Mailer\Transport\RoundRobinTransport; +use Symfony\Component\Mailer\Transport\SendmailTransportFactory; +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransportFactory; +use Symfony\Component\Mailer\Transport\TransportFactoryInterface; +use Symfony\Component\Mailer\Transport\TransportInterface; +use Symfony\Component\Mailer\Transport\Transports; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * @author Fabien Potencier + * @author Konstantin Myakshin + */ +final class Transport +{ + private const FACTORY_CLASSES = [ + AhaSendTransportFactory::class, + AzureTransportFactory::class, + BrevoTransportFactory::class, + GmailTransportFactory::class, + InfobipTransportFactory::class, + MailerSendTransportFactory::class, + MailgunTransportFactory::class, + MailjetTransportFactory::class, + MailomatTransportFactory::class, + MailPaceTransportFactory::class, + MandrillTransportFactory::class, + PostalTransportFactory::class, + PostmarkTransportFactory::class, + MailtrapTransportFactory::class, + ResendTransportFactory::class, + ScalewayTransportFactory::class, + SendgridTransportFactory::class, + SesTransportFactory::class, + SweegoTransportFactory::class, + ]; + + public static function fromDsn(#[\SensitiveParameter] string $dsn, ?EventDispatcherInterface $dispatcher = null, ?HttpClientInterface $client = null, ?LoggerInterface $logger = null): TransportInterface + { + $factory = new self(iterator_to_array(self::getDefaultFactories($dispatcher, $client, $logger))); + + return $factory->fromString($dsn); + } + + public static function fromDsns(#[\SensitiveParameter] array $dsns, ?EventDispatcherInterface $dispatcher = null, ?HttpClientInterface $client = null, ?LoggerInterface $logger = null): TransportInterface + { + $factory = new self(iterator_to_array(self::getDefaultFactories($dispatcher, $client, $logger))); + + return $factory->fromStrings($dsns); + } + + /** + * @param TransportFactoryInterface[] $factories + */ + public function __construct( + private iterable $factories, + ) { + } + + public function fromStrings(#[\SensitiveParameter] array $dsns): Transports + { + $transports = []; + foreach ($dsns as $name => $dsn) { + $transports[$name] = $this->fromString($dsn); + } + + return new Transports($transports); + } + + public function fromString(#[\SensitiveParameter] string $dsn): TransportInterface + { + [$transport, $offset] = $this->parseDsn($dsn); + if ($offset !== \strlen($dsn)) { + throw new InvalidArgumentException('The mailer DSN has some garbage at the end.'); + } + + return $transport; + } + + private function parseDsn(#[\SensitiveParameter] string $dsn, int $offset = 0): array + { + static $keywords = [ + 'failover' => FailoverTransport::class, + 'roundrobin' => RoundRobinTransport::class, + ]; + + while (true) { + foreach ($keywords as $name => $class) { + $name .= '('; + if ($name === substr($dsn, $offset, \strlen($name))) { + $offset += \strlen($name) - 1; + preg_match('{\(([^()]|(?R))*\)}A', $dsn, $matches, 0, $offset); + if (!isset($matches[0])) { + continue; + } + + ++$offset; + $args = []; + while (true) { + [$arg, $offset] = $this->parseDsn($dsn, $offset); + $args[] = $arg; + if (\strlen($dsn) === $offset) { + break; + } + ++$offset; + if (')' === $dsn[$offset - 1]) { + break; + } + } + + parse_str(substr($dsn, $offset + 1), $query); + if ($period = $query['retry_period'] ?? 0) { + return [new $class($args, (int) $period), $offset + \strlen('retry_period='.$period) + 1]; + } + + return [new $class($args), $offset]; + } + } + + if (preg_match('{(\w+)\(}A', $dsn, $matches, 0, $offset)) { + throw new InvalidArgumentException(\sprintf('The "%s" keyword is not valid (valid ones are "%s"), ', $matches[1], implode('", "', array_keys($keywords)))); + } + + if ($pos = strcspn($dsn, ' )', $offset)) { + return [$this->fromDsnObject(Dsn::fromString(substr($dsn, $offset, $pos))), $offset + $pos]; + } + + return [$this->fromDsnObject(Dsn::fromString(substr($dsn, $offset))), \strlen($dsn)]; + } + } + + public function fromDsnObject(Dsn $dsn): TransportInterface + { + foreach ($this->factories as $factory) { + if ($factory->supports($dsn)) { + return $factory->create($dsn); + } + } + + throw new UnsupportedSchemeException($dsn); + } + + /** + * @return \Traversable + */ + public static function getDefaultFactories(?EventDispatcherInterface $dispatcher = null, ?HttpClientInterface $client = null, ?LoggerInterface $logger = null): \Traversable + { + foreach (self::FACTORY_CLASSES as $factoryClass) { + if (class_exists($factoryClass)) { + yield new $factoryClass($dispatcher, $client, $logger); + } + } + + yield new NullTransportFactory($dispatcher, $client, $logger); + + yield new SendmailTransportFactory($dispatcher, $client, $logger); + + yield new EsmtpTransportFactory($dispatcher, $client, $logger); + + yield new NativeTransportFactory($dispatcher, $client, $logger); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractApiTransport.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractApiTransport.php new file mode 100644 index 0000000..6bd49e1 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractApiTransport.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Exception\RuntimeException; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Email; +use Symfony\Component\Mime\MessageConverter; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Fabien Potencier + */ +abstract class AbstractApiTransport extends AbstractHttpTransport +{ + abstract protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $envelope): ResponseInterface; + + protected function doSendHttp(SentMessage $message): ResponseInterface + { + try { + $email = MessageConverter::toEmail($message->getOriginalMessage()); + } catch (\Exception $e) { + throw new RuntimeException(\sprintf('Unable to send message with the "%s" transport: ', __CLASS__).$e->getMessage(), 0, $e); + } + + return $this->doSendApi($message, $email, $message->getEnvelope()); + } + + /** + * @return Address[] + */ + protected function getRecipients(Email $email, Envelope $envelope): array + { + return array_filter($envelope->getRecipients(), fn (Address $address) => false === \in_array($address, array_merge($email->getCc(), $email->getBcc()), true)); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractHttpTransport.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractHttpTransport.php new file mode 100644 index 0000000..edae92e --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractHttpTransport.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\HttpClient; +use Symfony\Component\Mailer\Exception\HttpTransportException; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Victor Bocharsky + */ +abstract class AbstractHttpTransport extends AbstractTransport +{ + protected ?string $host = null; + protected ?int $port = null; + + public function __construct( + protected ?HttpClientInterface $client = null, + ?EventDispatcherInterface $dispatcher = null, + ?LoggerInterface $logger = null, + ) { + if (null === $client) { + if (!class_exists(HttpClient::class)) { + throw new \LogicException(\sprintf('You cannot use "%s" as the HttpClient component is not installed. Try running "composer require symfony/http-client".', __CLASS__)); + } + + $this->client = HttpClient::create(); + } + + parent::__construct($dispatcher, $logger); + } + + /** + * @return $this + */ + public function setHost(?string $host): static + { + $this->host = $host; + + return $this; + } + + /** + * @return $this + */ + public function setPort(?int $port): static + { + $this->port = $port; + + return $this; + } + + abstract protected function doSendHttp(SentMessage $message): ResponseInterface; + + protected function doSend(SentMessage $message): void + { + try { + $response = $this->doSendHttp($message); + $message->appendDebug($response->getInfo('debug') ?? ''); + } catch (HttpTransportException $e) { + $e->appendDebug($e->getResponse()->getInfo('debug') ?? ''); + + throw $e; + } + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractTransport.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractTransport.php new file mode 100644 index 0000000..718a3bf --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractTransport.php @@ -0,0 +1,136 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; +use Symfony\Bridge\Twig\Mime\TemplatedEmail; +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Event\FailedMessageEvent; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mailer\Event\SentMessageEvent; +use Symfony\Component\Mailer\Exception\LogicException; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\BodyRendererInterface; +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +abstract class AbstractTransport implements TransportInterface +{ + private LoggerInterface $logger; + private float $rate = 0; + private float $lastSent = 0; + + public function __construct( + private ?EventDispatcherInterface $dispatcher = null, + ?LoggerInterface $logger = null, + ) { + $this->logger = $logger ?? new NullLogger(); + } + + /** + * Sets the maximum number of messages to send per second (0 to disable). + * + * @return $this + */ + public function setMaxPerSecond(float $rate): static + { + if (0 >= $rate) { + $rate = 0; + } + + $this->rate = $rate; + $this->lastSent = 0; + + return $this; + } + + public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage + { + $message = clone $message; + $envelope = null !== $envelope ? clone $envelope : Envelope::create($message); + + try { + if (!$this->dispatcher) { + $sentMessage = new SentMessage($message, $envelope); + $this->doSend($sentMessage); + + return $sentMessage; + } + + $event = new MessageEvent($message, $envelope, (string) $this); + $this->dispatcher->dispatch($event); + if ($event->isRejected()) { + return null; + } + + $envelope = $event->getEnvelope(); + $message = $event->getMessage(); + + if ($message instanceof TemplatedEmail && !$message->isRendered()) { + throw new LogicException(\sprintf('You must configure a "%s" when a "%s" instance has a text or HTML template set.', BodyRendererInterface::class, get_debug_type($message))); + } + + $sentMessage = new SentMessage($message, $envelope); + + try { + $this->doSend($sentMessage); + } catch (\Throwable $error) { + $this->dispatcher->dispatch(new FailedMessageEvent($message, $error)); + $this->checkThrottling(); + + throw $error; + } + + $this->dispatcher->dispatch(new SentMessageEvent($sentMessage)); + + return $sentMessage; + } finally { + $this->checkThrottling(); + } + } + + abstract protected function doSend(SentMessage $message): void; + + /** + * @param Address[] $addresses + * + * @return string[] + */ + protected function stringifyAddresses(array $addresses): array + { + return array_map(fn (Address $a) => $a->toString(), $addresses); + } + + protected function getLogger(): LoggerInterface + { + return $this->logger; + } + + private function checkThrottling(): void + { + if (0 == $this->rate) { + return; + } + + $sleep = (1 / $this->rate) - (microtime(true) - $this->lastSent); + if (0 < $sleep) { + $this->logger->debug(\sprintf('Email transport "%s" sleeps for %.2f seconds', __CLASS__, $sleep)); + usleep((int) ($sleep * 1000000)); + } + $this->lastSent = microtime(true); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractTransportFactory.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractTransportFactory.php new file mode 100644 index 0000000..5de1508 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/AbstractTransportFactory.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Exception\IncompleteDsnException; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * @author Konstantin Myakshin + */ +abstract class AbstractTransportFactory implements TransportFactoryInterface +{ + public function __construct( + protected ?EventDispatcherInterface $dispatcher = null, + protected ?HttpClientInterface $client = null, + protected ?LoggerInterface $logger = null, + ) { + } + + public function supports(Dsn $dsn): bool + { + return \in_array($dsn->getScheme(), $this->getSupportedSchemes(), true); + } + + abstract protected function getSupportedSchemes(): array; + + protected function getUser(Dsn $dsn): string + { + return $dsn->getUser() ?? throw new IncompleteDsnException('User is not set.'); + } + + protected function getPassword(Dsn $dsn): string + { + return $dsn->getPassword() ?? throw new IncompleteDsnException('Password is not set.'); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Dsn.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Dsn.php new file mode 100644 index 0000000..3bb201e --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Dsn.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Exception\InvalidArgumentException; + +/** + * @author Konstantin Myakshin + */ +final class Dsn +{ + public function __construct( + private string $scheme, + private string $host, + private ?string $user = null, + #[\SensitiveParameter] private ?string $password = null, + private ?int $port = null, + private array $options = [], + ) { + } + + public static function fromString(#[\SensitiveParameter] string $dsn): self + { + if (false === $params = parse_url($dsn)) { + throw new InvalidArgumentException('The mailer DSN is invalid.'); + } + + if (!isset($params['scheme'])) { + throw new InvalidArgumentException('The mailer DSN must contain a scheme.'); + } + + if (!isset($params['host'])) { + throw new InvalidArgumentException('The mailer DSN must contain a host (use "default" by default).'); + } + + $user = '' !== ($params['user'] ?? '') ? rawurldecode($params['user']) : null; + $password = '' !== ($params['pass'] ?? '') ? rawurldecode($params['pass']) : null; + $port = $params['port'] ?? null; + parse_str($params['query'] ?? '', $query); + + return new self($params['scheme'], $params['host'], $user, $password, $port, $query); + } + + public function getScheme(): string + { + return $this->scheme; + } + + public function getHost(): string + { + return $this->host; + } + + public function getUser(): ?string + { + return $this->user; + } + + public function getPassword(): ?string + { + return $this->password; + } + + public function getPort(?int $default = null): ?int + { + return $this->port ?? $default; + } + + public function getOption(string $key, mixed $default = null): mixed + { + return $this->options[$key] ?? $default; + } + + public function getBooleanOption(string $key, bool $default = false): bool + { + return filter_var($this->getOption($key, $default), \FILTER_VALIDATE_BOOLEAN); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/FailoverTransport.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/FailoverTransport.php new file mode 100644 index 0000000..d6a7477 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/FailoverTransport.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +/** + * Uses several Transports using a failover algorithm. + * + * @author Fabien Potencier + */ +class FailoverTransport extends RoundRobinTransport +{ + private ?TransportInterface $currentTransport = null; + + protected function getNextTransport(): ?TransportInterface + { + if (null === $this->currentTransport || $this->isTransportDead($this->currentTransport)) { + $this->currentTransport = parent::getNextTransport(); + } + + return $this->currentTransport; + } + + protected function getInitialCursor(): int + { + return 0; + } + + protected function getNameSymbol(): string + { + return 'failover'; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/NativeTransportFactory.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/NativeTransportFactory.php new file mode 100644 index 0000000..8afa53c --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/NativeTransportFactory.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; +use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport; +use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream; + +/** + * Factory that configures a transport (sendmail or SMTP) based on php.ini settings. + * + * @author Laurent VOULLEMIER + */ +final class NativeTransportFactory extends AbstractTransportFactory +{ + public function create(Dsn $dsn): TransportInterface + { + if (!\in_array($dsn->getScheme(), $this->getSupportedSchemes(), true)) { + throw new UnsupportedSchemeException($dsn, 'native', $this->getSupportedSchemes()); + } + + if ($sendMailPath = ini_get('sendmail_path')) { + return new SendmailTransport($sendMailPath, $this->dispatcher, $this->logger); + } + + if ('\\' !== \DIRECTORY_SEPARATOR) { + throw new TransportException('sendmail_path is not configured in php.ini.'); + } + + // Only for windows hosts; at this point non-windows + // host have already thrown an exception or returned a transport + $host = ini_get('SMTP'); + $port = (int) ini_get('smtp_port'); + + if (!$host || !$port) { + throw new TransportException('smtp or smtp_port is not configured in php.ini.'); + } + + $socketStream = new SocketStream(); + $socketStream->setHost($host); + $socketStream->setPort($port); + if (465 !== $port) { + $socketStream->disableTls(); + } + + return new SmtpTransport($socketStream, $this->dispatcher, $this->logger); + } + + protected function getSupportedSchemes(): array + { + return ['native']; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/NullTransport.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/NullTransport.php new file mode 100644 index 0000000..92fb82a --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/NullTransport.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\SentMessage; + +/** + * Pretends messages have been sent, but just ignores them. + * + * @author Fabien Potencier + */ +final class NullTransport extends AbstractTransport +{ + protected function doSend(SentMessage $message): void + { + } + + public function __toString(): string + { + return 'null://'; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/NullTransportFactory.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/NullTransportFactory.php new file mode 100644 index 0000000..4c45f39 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/NullTransportFactory.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; + +/** + * @author Konstantin Myakshin + */ +final class NullTransportFactory extends AbstractTransportFactory +{ + public function create(Dsn $dsn): TransportInterface + { + if ('null' === $dsn->getScheme()) { + return new NullTransport($this->dispatcher, $this->logger); + } + + throw new UnsupportedSchemeException($dsn, 'null', $this->getSupportedSchemes()); + } + + protected function getSupportedSchemes(): array + { + return ['null']; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/RoundRobinTransport.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/RoundRobinTransport.php new file mode 100644 index 0000000..754aca8 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/RoundRobinTransport.php @@ -0,0 +1,123 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mime\RawMessage; + +/** + * Uses several Transports using a round robin algorithm. + * + * @author Fabien Potencier + */ +class RoundRobinTransport implements TransportInterface +{ + /** + * @var \SplObjectStorage + */ + private \SplObjectStorage $deadTransports; + private int $cursor = -1; + + /** + * @param TransportInterface[] $transports + */ + public function __construct( + private array $transports, + private int $retryPeriod = 60, + ) { + if (!$transports) { + throw new TransportException(\sprintf('"%s" must have at least one transport configured.', static::class)); + } + + $this->deadTransports = new \SplObjectStorage(); + } + + public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage + { + $exception = null; + + while ($transport = $this->getNextTransport()) { + try { + return $transport->send(clone $message, $envelope); + } catch (TransportExceptionInterface $e) { + $exception ??= new TransportException('All transports failed.'); + $exception->appendDebug(\sprintf("Transport \"%s\": %s\n", $transport, $e->getDebug())); + $this->deadTransports[$transport] = microtime(true); + } + } + + throw $exception ?? new TransportException('No transports found.'); + } + + public function __toString(): string + { + return $this->getNameSymbol().'('.implode(' ', array_map('strval', $this->transports)).')'; + } + + /** + * Rotates the transport list around and returns the first instance. + */ + protected function getNextTransport(): ?TransportInterface + { + if (-1 === $this->cursor) { + $this->cursor = $this->getInitialCursor(); + } + + $cursor = $this->cursor; + while (true) { + $transport = $this->transports[$cursor]; + + if (!$this->isTransportDead($transport)) { + break; + } + + if ((microtime(true) - $this->deadTransports[$transport]) > $this->retryPeriod) { + unset($this->deadTransports[$transport]); + + break; + } + + if ($this->cursor === $cursor = $this->moveCursor($cursor)) { + return null; + } + } + + $this->cursor = $this->moveCursor($cursor); + + return $transport; + } + + protected function isTransportDead(TransportInterface $transport): bool + { + return $this->deadTransports->offsetExists($transport); + } + + protected function getInitialCursor(): int + { + // the cursor initial value is randomized so that + // when are not in a daemon, we are still rotating the transports + return mt_rand(0, \count($this->transports) - 1); + } + + protected function getNameSymbol(): string + { + return 'roundrobin'; + } + + private function moveCursor(int $cursor): int + { + return ++$cursor >= \count($this->transports) ? 0 : $cursor; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/SendmailTransport.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/SendmailTransport.php new file mode 100644 index 0000000..45cf503 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/SendmailTransport.php @@ -0,0 +1,124 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport; +use Symfony\Component\Mailer\Transport\Smtp\Stream\AbstractStream; +use Symfony\Component\Mailer\Transport\Smtp\Stream\ProcessStream; +use Symfony\Component\Mime\RawMessage; + +/** + * SendmailTransport for sending mail through a Sendmail/Postfix (etc..) binary. + * + * Transport can be instantiated through SendmailTransportFactory or NativeTransportFactory: + * + * - SendmailTransportFactory to use most common sendmail path and recommended options + * - NativeTransportFactory when configuration is set via php.ini + * + * @author Fabien Potencier + * @author Chris Corbyn + */ +class SendmailTransport extends AbstractTransport +{ + private string $command = '/usr/sbin/sendmail -bs'; + private ProcessStream $stream; + private ?SmtpTransport $transport = null; + + /** + * Constructor. + * + * Supported modes are -bs and -t, with any additional flags desired. + * + * The recommended mode is "-bs" since it is interactive and failure notifications are hence possible. + * Note that the -t mode does not support error reporting and does not support Bcc properly (the Bcc headers are not removed). + * + * If using -t mode, you are strongly advised to include -oi or -i in the flags (like /usr/sbin/sendmail -oi -t) + * + * -f flag will be appended automatically if one is not present. + */ + public function __construct(?string $command = null, ?EventDispatcherInterface $dispatcher = null, ?LoggerInterface $logger = null) + { + parent::__construct($dispatcher, $logger); + + if (null !== $command) { + if (!str_contains($command, ' -bs') && !str_contains($command, ' -t')) { + throw new \InvalidArgumentException(\sprintf('Unsupported sendmail command flags "%s"; must be one of "-bs" or "-t" but can include additional flags.', $command)); + } + + $this->command = $command; + } + + $this->stream = new ProcessStream(); + if (str_contains($this->command, ' -bs')) { + $this->stream->setCommand($this->command); + $this->stream->setInteractive(true); + $this->transport = new SmtpTransport($this->stream, $dispatcher, $logger); + } + } + + public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage + { + if ($this->transport) { + return $this->transport->send($message, $envelope); + } + + return parent::send($message, $envelope); + } + + public function __toString(): string + { + if ($this->transport) { + return (string) $this->transport; + } + + return 'smtp://sendmail'; + } + + protected function doSend(SentMessage $message): void + { + $this->getLogger()->debug(\sprintf('Email transport "%s" starting', __CLASS__)); + + $command = $this->command; + + if ($recipients = $message->getEnvelope()->getRecipients()) { + $command = str_replace(' -t', '', $command); + } + + if (!str_contains($command, ' -f')) { + $command .= ' -f'.escapeshellarg($message->getEnvelope()->getSender()->getEncodedAddress()); + } + + $chunks = AbstractStream::replace("\r\n", "\n", $message->toIterable()); + + if (!str_contains($command, ' -i') && !str_contains($command, ' -oi')) { + $chunks = AbstractStream::replace("\n.", "\n..", $chunks); + } + + foreach ($recipients as $recipient) { + $command .= ' '.escapeshellarg($recipient->getEncodedAddress()); + } + + $this->stream->setCommand($command); + $this->stream->initialize(); + foreach ($chunks as $chunk) { + $this->stream->write($chunk, false); + } + $this->stream->flush(); + $this->stream->terminate(); + + $this->getLogger()->debug(\sprintf('Email transport "%s" stopped', __CLASS__)); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/SendmailTransportFactory.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/SendmailTransportFactory.php new file mode 100644 index 0000000..6d977e7 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/SendmailTransportFactory.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; + +/** + * @author Konstantin Myakshin + */ +final class SendmailTransportFactory extends AbstractTransportFactory +{ + public function create(Dsn $dsn): TransportInterface + { + if ('sendmail+smtp' === $dsn->getScheme() || 'sendmail' === $dsn->getScheme()) { + return new SendmailTransport($dsn->getOption('command'), $this->dispatcher, $this->logger); + } + + throw new UnsupportedSchemeException($dsn, 'sendmail', $this->getSupportedSchemes()); + } + + protected function getSupportedSchemes(): array + { + return ['sendmail', 'sendmail+smtp']; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/AuthenticatorInterface.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/AuthenticatorInterface.php new file mode 100644 index 0000000..98ea2d4 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/AuthenticatorInterface.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Auth; + +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; + +/** + * An Authentication mechanism. + * + * @author Chris Corbyn + */ +interface AuthenticatorInterface +{ + /** + * Tries to authenticate the user. + * + * @throws TransportExceptionInterface + */ + public function authenticate(EsmtpTransport $client): void; + + /** + * Gets the name of the AUTH mechanism this Authenticator handles. + */ + public function getAuthKeyword(): string; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/CramMd5Authenticator.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/CramMd5Authenticator.php new file mode 100644 index 0000000..ce8df85 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/CramMd5Authenticator.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Auth; + +use Symfony\Component\Mailer\Exception\InvalidArgumentException; +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; + +/** + * Handles CRAM-MD5 authentication. + * + * @author Chris Corbyn + */ +class CramMd5Authenticator implements AuthenticatorInterface +{ + public function getAuthKeyword(): string + { + return 'CRAM-MD5'; + } + + /** + * @see https://www.ietf.org/rfc/rfc4954.txt + */ + public function authenticate(EsmtpTransport $client): void + { + $challenge = $client->executeCommand("AUTH CRAM-MD5\r\n", [334]); + $challenge = base64_decode(substr($challenge, 4)); + $message = base64_encode($client->getUsername().' '.$this->getResponse($client->getPassword(), $challenge)); + $client->executeCommand(\sprintf("%s\r\n", $message), [235]); + } + + /** + * Generates a CRAM-MD5 response from a server challenge. + */ + private function getResponse(#[\SensitiveParameter] string $secret, string $challenge): string + { + if (!$secret) { + throw new InvalidArgumentException('A non-empty secret is required.'); + } + + if (\strlen($secret) > 64) { + $secret = pack('H32', md5($secret)); + } + + if (\strlen($secret) < 64) { + $secret = str_pad($secret, 64, \chr(0)); + } + + $kipad = substr($secret, 0, 64) ^ str_repeat(\chr(0x36), 64); + $kopad = substr($secret, 0, 64) ^ str_repeat(\chr(0x5C), 64); + + $inner = pack('H32', md5($kipad.$challenge)); + + return md5($kopad.$inner); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/LoginAuthenticator.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/LoginAuthenticator.php new file mode 100644 index 0000000..82fe453 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/LoginAuthenticator.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Auth; + +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; + +/** + * Handles LOGIN authentication. + * + * @author Chris Corbyn + */ +class LoginAuthenticator implements AuthenticatorInterface +{ + public function getAuthKeyword(): string + { + return 'LOGIN'; + } + + /** + * @see https://www.ietf.org/rfc/rfc4954.txt + */ + public function authenticate(EsmtpTransport $client): void + { + $client->executeCommand("AUTH LOGIN\r\n", [334]); + $client->executeCommand(\sprintf("%s\r\n", base64_encode($client->getUsername())), [334]); + $client->executeCommand(\sprintf("%s\r\n", base64_encode($client->getPassword())), [235]); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/PlainAuthenticator.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/PlainAuthenticator.php new file mode 100644 index 0000000..7a6fefa --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/PlainAuthenticator.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Auth; + +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; + +/** + * Handles PLAIN authentication. + * + * @author Chris Corbyn + */ +class PlainAuthenticator implements AuthenticatorInterface +{ + public function getAuthKeyword(): string + { + return 'PLAIN'; + } + + /** + * @see https://www.ietf.org/rfc/rfc4954.txt + */ + public function authenticate(EsmtpTransport $client): void + { + $client->executeCommand(\sprintf("AUTH PLAIN %s\r\n", base64_encode($client->getUsername().\chr(0).$client->getUsername().\chr(0).$client->getPassword())), [235]); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/XOAuth2Authenticator.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/XOAuth2Authenticator.php new file mode 100644 index 0000000..c3aaa49 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Auth/XOAuth2Authenticator.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Auth; + +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; + +/** + * Handles XOAUTH2 authentication. + * + * @author xu.li + * + * @see https://developers.google.com/google-apps/gmail/xoauth2_protocol + */ +class XOAuth2Authenticator implements AuthenticatorInterface +{ + public function getAuthKeyword(): string + { + return 'XOAUTH2'; + } + + /** + * @see https://developers.google.com/google-apps/gmail/xoauth2_protocol#the_sasl_xoauth2_mechanism + */ + public function authenticate(EsmtpTransport $client): void + { + $client->executeCommand('AUTH XOAUTH2 '.base64_encode('user='.$client->getUsername()."\1auth=Bearer ".$client->getPassword()."\1\1")."\r\n", [235]); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/EsmtpTransport.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/EsmtpTransport.php new file mode 100644 index 0000000..1c332d6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/EsmtpTransport.php @@ -0,0 +1,271 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mailer\Exception\UnexpectedResponseException; +use Symfony\Component\Mailer\Transport\Smtp\Auth\AuthenticatorInterface; +use Symfony\Component\Mailer\Transport\Smtp\Stream\AbstractStream; +use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream; + +/** + * Sends Emails over SMTP with ESMTP support. + * + * @author Fabien Potencier + * @author Chris Corbyn + */ +class EsmtpTransport extends SmtpTransport +{ + private array $authenticators = []; + private string $username = ''; + private string $password = ''; + private array $capabilities; + private bool $autoTls = true; + private bool $requireTls = false; + + public function __construct(string $host = 'localhost', int $port = 0, ?bool $tls = null, ?EventDispatcherInterface $dispatcher = null, ?LoggerInterface $logger = null, ?AbstractStream $stream = null, ?array $authenticators = null) + { + parent::__construct($stream, $dispatcher, $logger); + + if (null === $authenticators) { + // fallback to default authenticators + // order is important here (roughly most secure and popular first) + $authenticators = [ + new Auth\CramMd5Authenticator(), + new Auth\LoginAuthenticator(), + new Auth\PlainAuthenticator(), + new Auth\XOAuth2Authenticator(), + ]; + } + $this->setAuthenticators($authenticators); + + /** @var SocketStream $stream */ + $stream = $this->getStream(); + + if (null === $tls) { + if (465 === $port) { + $tls = true; + } else { + $tls = \defined('OPENSSL_VERSION_NUMBER') && 0 === $port && 'localhost' !== $host; + } + } + if (!$tls) { + $stream->disableTls(); + } + if (0 === $port) { + $port = $tls ? 465 : 25; + } + + $stream->setHost($host); + $stream->setPort($port); + } + + /** + * @return $this + */ + public function setUsername(string $username): static + { + $this->username = $username; + + return $this; + } + + public function getUsername(): string + { + return $this->username; + } + + /** + * @return $this + */ + public function setPassword(#[\SensitiveParameter] string $password): static + { + $this->password = $password; + + return $this; + } + + public function getPassword(): string + { + return $this->password; + } + + /** + * @return $this + */ + public function setAutoTls(bool $autoTls): static + { + $this->autoTls = $autoTls; + + return $this; + } + + public function isAutoTls(): bool + { + return $this->autoTls; + } + + /** + * @return $this + */ + public function setRequireTls(bool $requireTls): static + { + $this->requireTls = $requireTls; + + return $this; + } + + public function isTlsRequired(): bool + { + return $this->requireTls; + } + + public function setAuthenticators(array $authenticators): void + { + $this->authenticators = []; + foreach ($authenticators as $authenticator) { + $this->addAuthenticator($authenticator); + } + } + + public function addAuthenticator(AuthenticatorInterface $authenticator): void + { + $this->authenticators[] = $authenticator; + } + + public function executeCommand(string $command, array $codes): string + { + return [250] === $codes && str_starts_with($command, 'HELO ') ? $this->doEhloCommand() : parent::executeCommand($command, $codes); + } + + final protected function getCapabilities(): array + { + return $this->capabilities; + } + + private function doEhloCommand(): string + { + try { + $response = $this->executeCommand(\sprintf("EHLO %s\r\n", $this->getLocalDomain()), [250]); + } catch (TransportExceptionInterface $e) { + try { + return parent::executeCommand(\sprintf("HELO %s\r\n", $this->getLocalDomain()), [250]); + } catch (TransportExceptionInterface $ex) { + if (!$ex->getCode()) { + throw $e; + } + + throw $ex; + } + } + + $this->capabilities = $this->parseCapabilities($response); + + /** @var SocketStream $stream */ + $stream = $this->getStream(); + $tlsStarted = $stream->isTls(); + // WARNING: !$stream->isTLS() is right, 100% sure :) + // if you think that the ! should be removed, read the code again + // if doing so "fixes" your issue then it probably means your SMTP server behaves incorrectly or is wrongly configured + if ($this->autoTls && !$stream->isTLS() && \defined('OPENSSL_VERSION_NUMBER') && \array_key_exists('STARTTLS', $this->capabilities)) { + $this->executeCommand("STARTTLS\r\n", [220]); + + if (!$stream->startTLS()) { + throw new TransportException('Unable to connect with STARTTLS.'); + } + + $tlsStarted = true; + $response = $this->executeCommand(\sprintf("EHLO %s\r\n", $this->getLocalDomain()), [250]); + $this->capabilities = $this->parseCapabilities($response); + } + + if (!$tlsStarted && $this->isTlsRequired()) { + throw new TransportException('TLS required but neither TLS or STARTTLS are in use.'); + } + + if (\array_key_exists('AUTH', $this->capabilities)) { + $this->handleAuth($this->capabilities['AUTH']); + } + + return $response; + } + + private function parseCapabilities(string $ehloResponse): array + { + $capabilities = []; + $lines = explode("\r\n", trim($ehloResponse)); + array_shift($lines); + foreach ($lines as $line) { + if (preg_match('/^[0-9]{3}[ -]([A-Z0-9-]+)((?:[ =].*)?)$/Di', $line, $matches)) { + $value = strtoupper(ltrim($matches[2], ' =')); + $capabilities[strtoupper($matches[1])] = $value ? explode(' ', $value) : []; + } + } + + return $capabilities; + } + + protected function serverSupportsSmtpUtf8(): bool + { + return \array_key_exists('SMTPUTF8', $this->capabilities); + } + + private function handleAuth(array $modes): void + { + if (!$this->username) { + return; + } + + $code = null; + $authNames = []; + $errors = []; + $modes = array_map('strtolower', $modes); + foreach ($this->authenticators as $authenticator) { + if (!\in_array(strtolower($authenticator->getAuthKeyword()), $modes, true)) { + continue; + } + + $code = null; + $authNames[] = $authenticator->getAuthKeyword(); + try { + $authenticator->authenticate($this); + + return; + } catch (UnexpectedResponseException $e) { + $code = $e->getCode(); + + try { + $this->executeCommand("RSET\r\n", [250]); + } catch (TransportExceptionInterface) { + // ignore this exception as it probably means that the server error was final + } + + // keep the error message, but tries the other authenticators + $errors[$authenticator->getAuthKeyword()] = $e->getMessage(); + } + } + + if (!$authNames) { + throw new TransportException(\sprintf('Failed to find an authenticator supported by the SMTP server, which currently supports: "%s".', implode('", "', $modes)), $code ?: 504); + } + + $message = \sprintf('Failed to authenticate on SMTP server with username "%s" using the following authenticators: "%s".', $this->username, implode('", "', $authNames)); + foreach ($errors as $name => $error) { + $message .= \sprintf(' Authenticator "%s" returned "%s".', $name, $error); + } + + throw new TransportException($message, $code ?: 535); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/EsmtpTransportFactory.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/EsmtpTransportFactory.php new file mode 100644 index 0000000..acfa2c4 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/EsmtpTransportFactory.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp; + +use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; +use Symfony\Component\Mailer\Transport\AbstractTransportFactory; +use Symfony\Component\Mailer\Transport\Dsn; +use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream; +use Symfony\Component\Mailer\Transport\TransportInterface; + +/** + * @author Konstantin Myakshin + */ +final class EsmtpTransportFactory extends AbstractTransportFactory +{ + public function create(Dsn $dsn): TransportInterface + { + if (!\in_array($dsn->getScheme(), $this->getSupportedSchemes(), true)) { + throw new UnsupportedSchemeException($dsn, 'smtp', $this->getSupportedSchemes()); + } + + $autoTls = '' === $dsn->getOption('auto_tls') || filter_var($dsn->getOption('auto_tls', true), \FILTER_VALIDATE_BOOL); + $tls = 'smtps' === $dsn->getScheme() ? true : ($autoTls ? null : false); + $port = $dsn->getPort(0); + $host = $dsn->getHost(); + + $transport = new EsmtpTransport($host, $port, $tls, $this->dispatcher, $this->logger); + $transport->setAutoTls($autoTls); + $transport->setRequireTls($dsn->getBooleanOption('require_tls')); + + /** @var SocketStream $stream */ + $stream = $transport->getStream(); + if ('' !== $sourceIp = $dsn->getOption('source_ip', '')) { + $stream->setSourceIp($sourceIp); + } + $streamOptions = $stream->getStreamOptions(); + + if ('' !== $dsn->getOption('verify_peer') && !filter_var($dsn->getOption('verify_peer', true), \FILTER_VALIDATE_BOOL)) { + $streamOptions['ssl']['verify_peer'] = false; + $streamOptions['ssl']['verify_peer_name'] = false; + } + + if (null !== $peerFingerprint = $dsn->getOption('peer_fingerprint')) { + $streamOptions['ssl']['peer_fingerprint'] = $peerFingerprint; + } + + $stream->setStreamOptions($streamOptions); + + if ($user = $dsn->getUser()) { + $transport->setUsername($user); + } + + if ($password = $dsn->getPassword()) { + $transport->setPassword($password); + } + + if (null !== ($localDomain = $dsn->getOption('local_domain'))) { + $transport->setLocalDomain($localDomain); + } + + if (null !== ($maxPerSecond = $dsn->getOption('max_per_second'))) { + $transport->setMaxPerSecond((float) $maxPerSecond); + } + + if (null !== ($restartThreshold = $dsn->getOption('restart_threshold'))) { + $transport->setRestartThreshold((int) $restartThreshold, (int) $dsn->getOption('restart_threshold_sleep', 0)); + } + + if (null !== ($pingThreshold = $dsn->getOption('ping_threshold'))) { + $transport->setPingThreshold((int) $pingThreshold); + } + + return $transport; + } + + protected function getSupportedSchemes(): array + { + return ['smtp', 'smtps']; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/SmtpTransport.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/SmtpTransport.php new file mode 100644 index 0000000..1ddf521 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/SmtpTransport.php @@ -0,0 +1,393 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Exception\InvalidArgumentException; +use Symfony\Component\Mailer\Exception\LogicException; +use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mailer\Exception\UnexpectedResponseException; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mailer\Transport\AbstractTransport; +use Symfony\Component\Mailer\Transport\Smtp\Stream\AbstractStream; +use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream; +use Symfony\Component\Mime\RawMessage; + +/** + * Sends emails over SMTP. + * + * @author Fabien Potencier + * @author Chris Corbyn + */ +class SmtpTransport extends AbstractTransport +{ + private bool $started = false; + private int $restartThreshold = 100; + private int $restartThresholdSleep = 0; + private int $restartCounter = 0; + private int $pingThreshold = 100; + private float $lastMessageTime = 0; + private AbstractStream $stream; + private string $domain = '[127.0.0.1]'; + + public function __construct(?AbstractStream $stream = null, ?EventDispatcherInterface $dispatcher = null, ?LoggerInterface $logger = null) + { + parent::__construct($dispatcher, $logger); + + $this->stream = $stream ?? new SocketStream(); + } + + public function getStream(): AbstractStream + { + return $this->stream; + } + + /** + * Sets the maximum number of messages to send before re-starting the transport. + * + * By default, the threshold is set to 100 (and no sleep at restart). + * + * @param int $threshold The maximum number of messages (0 to disable) + * @param int $sleep The number of seconds to sleep between stopping and re-starting the transport + * + * @return $this + */ + public function setRestartThreshold(int $threshold, int $sleep = 0): static + { + $this->restartThreshold = $threshold; + $this->restartThresholdSleep = $sleep; + + return $this; + } + + /** + * Sets the minimum number of seconds required between two messages, before the server is pinged. + * If the transport wants to send a message and the time since the last message exceeds the specified threshold, + * the transport will ping the server first (NOOP command) to check if the connection is still alive. + * Otherwise the message will be sent without pinging the server first. + * + * Do not set the threshold too low, as the SMTP server may drop the connection if there are too many + * non-mail commands (like pinging the server with NOOP). + * + * By default, the threshold is set to 100 seconds. + * + * @param int $seconds The minimum number of seconds between two messages required to ping the server + * + * @return $this + */ + public function setPingThreshold(int $seconds): static + { + $this->pingThreshold = $seconds; + + return $this; + } + + /** + * Sets the name of the local domain that will be used in HELO. + * + * This should be a fully-qualified domain name and should be truly the domain + * you're using. + * + * If your server does not have a domain name, use the IP address. This will + * automatically be wrapped in square brackets as described in RFC 5321, + * section 4.1.3. + * + * @return $this + */ + public function setLocalDomain(string $domain): static + { + if ('' !== $domain && '[' !== $domain[0]) { + if (filter_var($domain, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) { + $domain = '['.$domain.']'; + } elseif (filter_var($domain, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { + $domain = '[IPv6:'.$domain.']'; + } + } + + $this->domain = $domain; + + return $this; + } + + /** + * Gets the name of the domain that will be used in HELO. + * + * If an IP address was specified, this will be returned wrapped in square + * brackets as described in RFC 5321, section 4.1.3. + */ + public function getLocalDomain(): string + { + return $this->domain; + } + + public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage + { + try { + $message = parent::send($message, $envelope); + } catch (TransportExceptionInterface $e) { + if ($this->started) { + try { + $this->executeCommand("RSET\r\n", [250]); + } catch (TransportExceptionInterface) { + // ignore this exception as it probably means that the server error was final + } + } + + throw $e; + } + + $this->checkRestartThreshold(); + + return $message; + } + + protected function parseMessageId(string $mtaResult): string + { + $regexps = [ + '/250 Ok (?P[0-9a-f-]+)\r?$/mis', + '/250 Ok:? queued as (?P[A-Z0-9]+)\r?$/mis', + ]; + $matches = []; + foreach ($regexps as $regexp) { + if (preg_match($regexp, $mtaResult, $matches)) { + return $matches['id']; + } + } + + return ''; + } + + public function __toString(): string + { + if ($this->stream instanceof SocketStream) { + $name = \sprintf('smtp%s://%s', ($tls = $this->stream->isTLS()) ? 's' : '', $this->stream->getHost()); + $port = $this->stream->getPort(); + if (!(25 === $port || ($tls && 465 === $port))) { + $name .= ':'.$port; + } + + return $name; + } + + return 'smtp://sendmail'; + } + + /** + * Runs a command against the stream, expecting the given response codes. + * + * @param int[] $codes + * + * @throws TransportException when an invalid response if received + */ + public function executeCommand(string $command, array $codes): string + { + $this->stream->write($command); + $response = $this->getFullResponse(); + $this->assertResponseCode($response, $codes); + + return $response; + } + + protected function doSend(SentMessage $message): void + { + if (microtime(true) - $this->lastMessageTime > $this->pingThreshold) { + $this->ping(); + } + + try { + if (!$this->started) { + $this->start(); + } + + $envelope = $message->getEnvelope(); + $this->doMailFromCommand($envelope->getSender()->getEncodedAddress(), $envelope->anyAddressHasUnicodeLocalpart()); + foreach ($envelope->getRecipients() as $recipient) { + $this->doRcptToCommand($recipient->getEncodedAddress()); + } + + $this->executeCommand("DATA\r\n", [354]); + try { + foreach (AbstractStream::replace("\r\n.", "\r\n..", $message->toIterable()) as $chunk) { + $this->stream->write($chunk, false); + } + $this->stream->flush(); + } catch (TransportExceptionInterface $e) { + throw $e; + } catch (\Exception $e) { + $this->stream->terminate(); + $this->started = false; + $this->getLogger()->debug(\sprintf('Email transport "%s" stopped', __CLASS__)); + throw $e; + } + $mtaResult = $this->executeCommand("\r\n.\r\n", [250]); + $message->appendDebug($this->stream->getDebug()); + $this->lastMessageTime = microtime(true); + + if ($mtaResult && $messageId = $this->parseMessageId($mtaResult)) { + $message->setMessageId($messageId); + } + } catch (TransportExceptionInterface $e) { + $e->appendDebug($this->stream->getDebug()); + $this->lastMessageTime = 0; + throw $e; + } + } + + protected function serverSupportsSmtpUtf8(): bool + { + return false; + } + + private function doHeloCommand(): void + { + $this->executeCommand(\sprintf("HELO %s\r\n", $this->domain), [250]); + } + + private function doMailFromCommand(string $address, bool $smtputf8): void + { + if ($smtputf8 && !$this->serverSupportsSmtpUtf8()) { + throw new InvalidArgumentException('Invalid addresses: non-ASCII characters not supported in local-part of email.'); + } + $this->executeCommand(\sprintf("MAIL FROM:<%s>%s\r\n", $address, $smtputf8 ? ' SMTPUTF8' : ''), [250]); + } + + private function doRcptToCommand(string $address): void + { + $this->executeCommand(\sprintf("RCPT TO:<%s>\r\n", $address), [250, 251, 252]); + } + + public function start(): void + { + if ($this->started) { + return; + } + + $this->getLogger()->debug(\sprintf('Email transport "%s" starting', __CLASS__)); + + $this->stream->initialize(); + $this->assertResponseCode($this->getFullResponse(), [220]); + $this->doHeloCommand(); + $this->started = true; + $this->lastMessageTime = 0; + + $this->getLogger()->debug(\sprintf('Email transport "%s" started', __CLASS__)); + } + + /** + * Manually disconnect from the SMTP server. + * + * In most cases this is not necessary since the disconnect happens automatically on termination. + * In cases of long-running scripts, this might however make sense to avoid keeping an open + * connection to the SMTP server in between sending emails. + */ + public function stop(): void + { + if (!$this->started) { + return; + } + + $this->getLogger()->debug(\sprintf('Email transport "%s" stopping', __CLASS__)); + + try { + $this->executeCommand("QUIT\r\n", [221]); + } catch (TransportExceptionInterface) { + } finally { + $this->stream->terminate(); + $this->started = false; + $this->getLogger()->debug(\sprintf('Email transport "%s" stopped', __CLASS__)); + } + } + + private function ping(): void + { + if (!$this->started) { + return; + } + + try { + $this->executeCommand("NOOP\r\n", [250]); + } catch (TransportExceptionInterface) { + $this->stop(); + } + } + + /** + * @throws TransportException if a response code is incorrect + */ + private function assertResponseCode(string $response, array $codes): void + { + if (!$codes) { + throw new LogicException('You must set the expected response code.'); + } + + [$code] = sscanf($response, '%3d'); + $valid = \in_array($code, $codes); + + if (!$valid || !$response) { + $codeStr = $code ? \sprintf('code "%s"', $code) : 'empty code'; + $responseStr = $response ? \sprintf(', with message "%s"', trim($response)) : ''; + + throw new UnexpectedResponseException(\sprintf('Expected response code "%s" but got ', implode('/', $codes)).$codeStr.$responseStr.'.', $code ?: 0); + } + } + + private function getFullResponse(): string + { + $response = ''; + do { + $line = $this->stream->readLine(); + $response .= $line; + } while ($line && isset($line[3]) && ' ' !== $line[3]); + + return $response; + } + + private function checkRestartThreshold(): void + { + // when using sendmail via non-interactive mode, the transport is never "started" + if (!$this->started) { + return; + } + + ++$this->restartCounter; + if ($this->restartCounter < $this->restartThreshold) { + return; + } + + $this->stop(); + if (0 < $sleep = $this->restartThresholdSleep) { + $this->getLogger()->debug(\sprintf('Email transport "%s" sleeps for %d seconds after stopping', __CLASS__, $sleep)); + + sleep($sleep); + } + $this->start(); + $this->restartCounter = 0; + } + + public function __serialize(): array + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __unserialize(array $data): void + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + public function __destruct() + { + $this->stop(); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Stream/AbstractStream.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Stream/AbstractStream.php new file mode 100644 index 0000000..9cd8463 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Stream/AbstractStream.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Stream; + +use Symfony\Component\Mailer\Exception\TransportException; + +/** + * A stream supporting remote sockets and local processes. + * + * @author Fabien Potencier + * @author Nicolas Grekas + * @author Chris Corbyn + * + * @internal + */ +abstract class AbstractStream +{ + /** @var resource|null */ + protected $stream; + /** @var resource|null */ + protected $in; + /** @var resource|null */ + protected $out; + protected $err; + + private string $debug = ''; + + public function write(string $bytes, bool $debug = true): void + { + if ($debug) { + $timestamp = (new \DateTimeImmutable())->format('Y-m-d\TH:i:s.up'); + foreach (explode("\n", trim($bytes)) as $line) { + $this->debug .= \sprintf("[%s] > %s\n", $timestamp, $line); + } + } + + $bytesToWrite = \strlen($bytes); + $totalBytesWritten = 0; + while ($totalBytesWritten < $bytesToWrite) { + $bytesWritten = @fwrite($this->in, substr($bytes, $totalBytesWritten)); + if (false === $bytesWritten || 0 === $bytesWritten) { + throw new TransportException('Unable to write bytes on the wire.'); + } + + $totalBytesWritten += $bytesWritten; + } + } + + /** + * Flushes the contents of the stream (empty it) and set the internal pointer to the beginning. + */ + public function flush(): void + { + fflush($this->in); + } + + /** + * Performs any initialization needed. + */ + abstract public function initialize(): void; + + public function terminate(): void + { + $this->stream = $this->err = $this->out = $this->in = null; + } + + public function readLine(): string + { + if (feof($this->out)) { + return ''; + } + + $line = @fgets($this->out); + if ('' === $line || false === $line) { + if (stream_get_meta_data($this->out)['timed_out']) { + throw new TransportException(\sprintf('Connection to "%s" timed out.', $this->getReadConnectionDescription())); + } + if (feof($this->out)) { // don't use "eof" metadata, it's not accurate on Windows + throw new TransportException(\sprintf('Connection to "%s" has been closed unexpectedly.', $this->getReadConnectionDescription())); + } + if (false === $line) { + throw new TransportException(\sprintf('Unable to read from connection to "%s": ', $this->getReadConnectionDescription().error_get_last()['message'] ?? '')); + } + } + + $this->debug .= \sprintf('[%s] < %s', (new \DateTimeImmutable())->format('Y-m-d\TH:i:s.up'), $line); + + return $line; + } + + public function getDebug(): string + { + $debug = $this->debug; + $this->debug = ''; + + return $debug; + } + + public static function replace(string $from, string $to, iterable $chunks): \Generator + { + if ('' === $from) { + yield from $chunks; + + return; + } + + $carry = ''; + $fromLen = \strlen($from); + + foreach ($chunks as $chunk) { + if ('' === $chunk = $carry.$chunk) { + continue; + } + + if (str_contains($chunk, $from)) { + $chunk = explode($from, $chunk); + $carry = array_pop($chunk); + + yield implode($to, $chunk).$to; + } else { + $carry = $chunk; + } + + if (\strlen($carry) > $fromLen) { + yield substr($carry, 0, -$fromLen); + $carry = substr($carry, -$fromLen); + } + } + + if ('' !== $carry) { + yield $carry; + } + } + + abstract protected function getReadConnectionDescription(): string; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Stream/ProcessStream.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Stream/ProcessStream.php new file mode 100644 index 0000000..e635147 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Stream/ProcessStream.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Stream; + +use Symfony\Component\Mailer\Exception\TransportException; + +/** + * A stream supporting local processes. + * + * @author Fabien Potencier + * @author Chris Corbyn + * + * @internal + */ +final class ProcessStream extends AbstractStream +{ + private string $command; + private bool $interactive = false; + + public function setCommand(string $command): void + { + $this->command = $command; + } + + public function setInteractive(bool $interactive): void + { + $this->interactive = $interactive; + } + + public function initialize(): void + { + $descriptorSpec = [ + 0 => ['pipe', 'r'], + 1 => ['pipe', 'w'], + 2 => ['pipe', '\\' === \DIRECTORY_SEPARATOR ? 'a' : 'w'], + ]; + $pipes = []; + $this->stream = proc_open($this->command, $descriptorSpec, $pipes); + stream_set_blocking($pipes[2], false); + if ($err = stream_get_contents($pipes[2])) { + throw new TransportException('Process could not be started: '.$err); + } + $this->in = &$pipes[0]; + $this->out = &$pipes[1]; + $this->err = &$pipes[2]; + } + + public function terminate(): void + { + if (null !== $this->stream) { + fclose($this->in); + $out = stream_get_contents($this->out); + fclose($this->out); + $err = stream_get_contents($this->err); + fclose($this->err); + if (0 !== $exitCode = proc_close($this->stream)) { + $errorMessage = 'Process failed with exit code '.$exitCode.': '.$out.$err; + } + } + + parent::terminate(); + + if (!$this->interactive && isset($errorMessage)) { + throw new TransportException($errorMessage); + } + } + + protected function getReadConnectionDescription(): string + { + return 'process '.$this->command; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Stream/SocketStream.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Stream/SocketStream.php new file mode 100644 index 0000000..560afb6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Smtp/Stream/SocketStream.php @@ -0,0 +1,193 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Stream; + +use Symfony\Component\Mailer\Exception\TransportException; + +/** + * A stream supporting remote sockets. + * + * @author Fabien Potencier + * @author Chris Corbyn + * + * @internal + */ +final class SocketStream extends AbstractStream +{ + private string $url; + private string $host = 'localhost'; + private int $port = 465; + private float $timeout; + private bool $tls = true; + private ?string $sourceIp = null; + private array $streamContextOptions = []; + + /** + * @return $this + */ + public function setTimeout(float $timeout): static + { + $this->timeout = $timeout; + + return $this; + } + + public function getTimeout(): float + { + return $this->timeout ?? (float) \ini_get('default_socket_timeout'); + } + + /** + * Literal IPv6 addresses should be wrapped in square brackets. + * + * @return $this + */ + public function setHost(string $host): static + { + $this->host = $host; + + return $this; + } + + public function getHost(): string + { + return $this->host; + } + + /** + * @return $this + */ + public function setPort(int $port): static + { + $this->port = $port; + + return $this; + } + + public function getPort(): int + { + return $this->port; + } + + /** + * Sets the TLS/SSL on the socket (disables STARTTLS). + * + * @return $this + */ + public function disableTls(): static + { + $this->tls = false; + + return $this; + } + + public function isTLS(): bool + { + return $this->tls; + } + + /** + * @return $this + */ + public function setStreamOptions(array $options): static + { + $this->streamContextOptions = $options; + + return $this; + } + + public function getStreamOptions(): array + { + return $this->streamContextOptions; + } + + /** + * Sets the source IP. + * + * IPv6 addresses should be wrapped in square brackets. + * + * @return $this + */ + public function setSourceIp(string $ip): static + { + $this->sourceIp = $ip; + + return $this; + } + + /** + * Returns the IP used to connect to the destination. + */ + public function getSourceIp(): ?string + { + return $this->sourceIp; + } + + public function initialize(): void + { + $this->url = $this->host.':'.$this->port; + if ($this->tls) { + $this->url = 'ssl://'.$this->url; + } + $options = []; + if ($this->sourceIp) { + $options['socket']['bindto'] = $this->sourceIp.':0'; + } + if ($this->streamContextOptions) { + $options = array_merge($options, $this->streamContextOptions); + } + // do it unconditionally as it will be used by STARTTLS as well if supported + $options['ssl']['crypto_method'] ??= \STREAM_CRYPTO_METHOD_TLS_CLIENT | \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT | \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; + $streamContext = stream_context_create($options); + + $timeout = $this->getTimeout(); + set_error_handler(function ($type, $msg) { + throw new TransportException(\sprintf('Connection could not be established with host "%s": ', $this->url).$msg); + }); + try { + $this->stream = stream_socket_client($this->url, $errno, $errstr, $timeout, \STREAM_CLIENT_CONNECT, $streamContext); + } finally { + restore_error_handler(); + } + + stream_set_blocking($this->stream, true); + stream_set_timeout($this->stream, (int) $timeout, (int) (($timeout - (int) $timeout) * 1000000)); + $this->in = &$this->stream; + $this->out = &$this->stream; + } + + public function startTLS(): bool + { + set_error_handler(function ($type, $msg) { + throw new TransportException('Unable to connect with STARTTLS: '.$msg); + }); + try { + return stream_socket_enable_crypto($this->stream, true); + } finally { + restore_error_handler(); + } + } + + public function terminate(): void + { + if (null !== $this->stream) { + fclose($this->stream); + } + + parent::terminate(); + } + + protected function getReadConnectionDescription(): string + { + return $this->url; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/TransportFactoryInterface.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/TransportFactoryInterface.php new file mode 100644 index 0000000..9785ae8 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/TransportFactoryInterface.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Exception\IncompleteDsnException; +use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; + +/** + * @author Konstantin Myakshin + */ +interface TransportFactoryInterface +{ + /** + * @throws UnsupportedSchemeException + * @throws IncompleteDsnException + */ + public function create(Dsn $dsn): TransportInterface; + + public function supports(Dsn $dsn): bool; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/TransportInterface.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/TransportInterface.php new file mode 100644 index 0000000..01570ca --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/TransportInterface.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mime\RawMessage; + +/** + * Interface for all mailer transports. + * + * When sending emails, you should prefer MailerInterface implementations + * as they allow asynchronous sending. + * + * @author Fabien Potencier + */ +interface TransportInterface extends \Stringable +{ + /** + * @throws TransportExceptionInterface + */ + public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Transports.php b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Transports.php new file mode 100644 index 0000000..1d97ea6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/Transport/Transports.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Exception\InvalidArgumentException; +use Symfony\Component\Mailer\Exception\LogicException; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mime\Message; +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +final class Transports implements TransportInterface +{ + /** + * @var array + */ + private array $transports = []; + private TransportInterface $default; + + /** + * @param iterable $transports + */ + public function __construct(iterable $transports) + { + foreach ($transports as $name => $transport) { + $this->default ??= $transport; + $this->transports[$name] = $transport; + } + + if (!$this->transports) { + throw new LogicException(\sprintf('"%s" must have at least one transport configured.', __CLASS__)); + } + } + + public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage + { + /** @var Message $message */ + if (RawMessage::class === $message::class || !$message->getHeaders()->has('X-Transport')) { + return $this->default->send($message, $envelope); + } + + $headers = $message->getHeaders(); + $transport = $headers->get('X-Transport')->getBody(); + $headers->remove('X-Transport'); + + if (!isset($this->transports[$transport])) { + throw new InvalidArgumentException(\sprintf('The "%s" transport does not exist (available transports: "%s").', $transport, implode('", "', array_keys($this->transports)))); + } + + try { + return $this->transports[$transport]->send($message, $envelope); + } catch (\Throwable $e) { + $headers->addTextHeader('X-Transport', $transport); + + throw $e; + } + } + + public function __toString(): string + { + return '['.implode(',', array_keys($this->transports)).']'; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mailer/composer.json b/lib/SymfonyMailer/vendor/symfony/mailer/composer.json new file mode 100644 index 0000000..4336e72 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mailer/composer.json @@ -0,0 +1,47 @@ +{ + "name": "symfony/mailer", + "type": "library", + "description": "Helps sending emails", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=8.2", + "egulias/email-validator": "^2.1.10|^3|^4", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/mime": "^7.2", + "symfony/service-contracts": "^2.5|^3" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/twig-bridge": "<6.4" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Mailer\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Address.php b/lib/SymfonyMailer/vendor/symfony/mime/Address.php new file mode 100644 index 0000000..25d2f95 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Address.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Egulias\EmailValidator\EmailValidator; +use Egulias\EmailValidator\Validation\MessageIDValidation; +use Egulias\EmailValidator\Validation\RFCValidation; +use Symfony\Component\Mime\Encoder\IdnAddressEncoder; +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Exception\LogicException; +use Symfony\Component\Mime\Exception\RfcComplianceException; + +/** + * @author Fabien Potencier + */ +final class Address +{ + /** + * A regex that matches a structure like 'Name '. + * It matches anything between the first < and last > as email address. + * This allows to use a single string to construct an Address, which can be convenient to use in + * config, and allows to have more readable config. + * This does not try to cover all edge cases for address. + */ + private const FROM_STRING_PATTERN = '~(?[^<]*)<(?.*)>[^>]*~'; + + private static EmailValidator $validator; + private static IdnAddressEncoder $encoder; + + private string $address; + private string $name; + + public function __construct(string $address, string $name = '') + { + if (!class_exists(EmailValidator::class)) { + throw new LogicException(\sprintf('The "%s" class cannot be used as it needs "%s". Try running "composer require egulias/email-validator".', __CLASS__, EmailValidator::class)); + } + + self::$validator ??= new EmailValidator(); + + $this->address = trim($address); + $this->name = trim(str_replace(["\n", "\r"], '', $name)); + + if (!self::$validator->isValid($this->address, class_exists(MessageIDValidation::class) ? new MessageIDValidation() : new RFCValidation())) { + throw new RfcComplianceException(\sprintf('Email "%s" does not comply with addr-spec of RFC 2822.', $address)); + } + } + + public function getAddress(): string + { + return $this->address; + } + + public function getName(): string + { + return $this->name; + } + + public function getEncodedAddress(): string + { + self::$encoder ??= new IdnAddressEncoder(); + + return self::$encoder->encodeString($this->address); + } + + public function toString(): string + { + return ($n = $this->getEncodedName()) ? $n.' <'.$this->getEncodedAddress().'>' : $this->getEncodedAddress(); + } + + public function getEncodedName(): string + { + if ('' === $this->getName()) { + return ''; + } + + return \sprintf('"%s"', preg_replace('/"/u', '\"', $this->getName())); + } + + public static function create(self|string $address): self + { + if ($address instanceof self) { + return $address; + } + + if (!str_contains($address, '<')) { + return new self($address); + } + + if (!preg_match(self::FROM_STRING_PATTERN, $address, $matches)) { + throw new InvalidArgumentException(\sprintf('Could not parse "%s" to a "%s" instance.', $address, self::class)); + } + + return new self($matches['addrSpec'], trim($matches['displayName'], ' \'"')); + } + + /** + * @param array $addresses + * + * @return Address[] + */ + public static function createArray(array $addresses): array + { + $addrs = []; + foreach ($addresses as $address) { + $addrs[] = self::create($address); + } + + return $addrs; + } + + /** + * Returns true if this address' localpart contains at least one + * non-ASCII character, and false if it is only ASCII (or empty). + * + * This is a helper for Envelope, which has to decide whether to + * the SMTPUTF8 extensions (RFC 6530 and following) for any given + * message. + * + * The SMTPUTF8 extension is strictly required if any address + * contains a non-ASCII character in its localpart. If non-ASCII + * is only used in domains (e.g. horst@freiherr-von-mühlhausen.de) + * then it is possible to send the message using IDN encoding + * instead of SMTPUTF8. The most common software will display the + * message as intended. + */ + public function hasUnicodeLocalpart(): bool + { + return (bool) preg_match('/[\x80-\xFF].*@/', $this->address); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/BodyRendererInterface.php b/lib/SymfonyMailer/vendor/symfony/mime/BodyRendererInterface.php new file mode 100644 index 0000000..d692172 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/BodyRendererInterface.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +/** + * @author Fabien Potencier + */ +interface BodyRendererInterface +{ + public function render(Message $message): void; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/CHANGELOG.md b/lib/SymfonyMailer/vendor/symfony/mime/CHANGELOG.md new file mode 100644 index 0000000..8d593e6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/CHANGELOG.md @@ -0,0 +1,57 @@ +CHANGELOG +========= + +7.0 +--- + + * Remove `Email::attachPart()`, use `Email::addPart()` instead + * Argument `$body` is now required (at least null) in `Message::setBody()` + * Require explicit argument when calling `Message::setBody()` + +6.3 +--- + + * Support detection of related parts if `Content-Id` is used instead of the name + * Add `TextPart::getDisposition()` + +6.2 +--- + + * Add `File` + * Deprecate `Email::attachPart()`, use `addPart()` instead + * Deprecate calling `Message::setBody()` without arguments + +6.1 +--- + + * Add `DataPart::getFilename()` and `DataPart::getContentType()` + +6.0 +--- + + * Remove `Address::fromString()`, use `Address::create()` instead + * Remove `Serializable` interface from `RawMessage` + +5.2.0 +----- + + * Add support for DKIM + * Deprecated `Address::fromString()`, use `Address::create()` instead + +4.4.0 +----- + + * [BC BREAK] Removed `NamedAddress` (`Address` now supports a name) + * Added PHPUnit constraints + * Added `AbstractPart::asDebugString()` + * Added `Address::fromString()` + +4.3.3 +----- + + * [BC BREAK] Renamed method `Headers::getAll()` to `Headers::all()`. + +4.3.0 +----- + + * Introduced the component as experimental diff --git a/lib/SymfonyMailer/vendor/symfony/mime/CharacterStream.php b/lib/SymfonyMailer/vendor/symfony/mime/CharacterStream.php new file mode 100644 index 0000000..572cf82 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/CharacterStream.php @@ -0,0 +1,211 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +/** + * @author Fabien Potencier + * @author Xavier De Cock + * + * @internal + */ +final class CharacterStream +{ + /** Pre-computed for optimization */ + private const UTF8_LENGTH_MAP = [ + "\x00" => 1, "\x01" => 1, "\x02" => 1, "\x03" => 1, "\x04" => 1, "\x05" => 1, "\x06" => 1, "\x07" => 1, + "\x08" => 1, "\x09" => 1, "\x0a" => 1, "\x0b" => 1, "\x0c" => 1, "\x0d" => 1, "\x0e" => 1, "\x0f" => 1, + "\x10" => 1, "\x11" => 1, "\x12" => 1, "\x13" => 1, "\x14" => 1, "\x15" => 1, "\x16" => 1, "\x17" => 1, + "\x18" => 1, "\x19" => 1, "\x1a" => 1, "\x1b" => 1, "\x1c" => 1, "\x1d" => 1, "\x1e" => 1, "\x1f" => 1, + "\x20" => 1, "\x21" => 1, "\x22" => 1, "\x23" => 1, "\x24" => 1, "\x25" => 1, "\x26" => 1, "\x27" => 1, + "\x28" => 1, "\x29" => 1, "\x2a" => 1, "\x2b" => 1, "\x2c" => 1, "\x2d" => 1, "\x2e" => 1, "\x2f" => 1, + "\x30" => 1, "\x31" => 1, "\x32" => 1, "\x33" => 1, "\x34" => 1, "\x35" => 1, "\x36" => 1, "\x37" => 1, + "\x38" => 1, "\x39" => 1, "\x3a" => 1, "\x3b" => 1, "\x3c" => 1, "\x3d" => 1, "\x3e" => 1, "\x3f" => 1, + "\x40" => 1, "\x41" => 1, "\x42" => 1, "\x43" => 1, "\x44" => 1, "\x45" => 1, "\x46" => 1, "\x47" => 1, + "\x48" => 1, "\x49" => 1, "\x4a" => 1, "\x4b" => 1, "\x4c" => 1, "\x4d" => 1, "\x4e" => 1, "\x4f" => 1, + "\x50" => 1, "\x51" => 1, "\x52" => 1, "\x53" => 1, "\x54" => 1, "\x55" => 1, "\x56" => 1, "\x57" => 1, + "\x58" => 1, "\x59" => 1, "\x5a" => 1, "\x5b" => 1, "\x5c" => 1, "\x5d" => 1, "\x5e" => 1, "\x5f" => 1, + "\x60" => 1, "\x61" => 1, "\x62" => 1, "\x63" => 1, "\x64" => 1, "\x65" => 1, "\x66" => 1, "\x67" => 1, + "\x68" => 1, "\x69" => 1, "\x6a" => 1, "\x6b" => 1, "\x6c" => 1, "\x6d" => 1, "\x6e" => 1, "\x6f" => 1, + "\x70" => 1, "\x71" => 1, "\x72" => 1, "\x73" => 1, "\x74" => 1, "\x75" => 1, "\x76" => 1, "\x77" => 1, + "\x78" => 1, "\x79" => 1, "\x7a" => 1, "\x7b" => 1, "\x7c" => 1, "\x7d" => 1, "\x7e" => 1, "\x7f" => 1, + "\x80" => 0, "\x81" => 0, "\x82" => 0, "\x83" => 0, "\x84" => 0, "\x85" => 0, "\x86" => 0, "\x87" => 0, + "\x88" => 0, "\x89" => 0, "\x8a" => 0, "\x8b" => 0, "\x8c" => 0, "\x8d" => 0, "\x8e" => 0, "\x8f" => 0, + "\x90" => 0, "\x91" => 0, "\x92" => 0, "\x93" => 0, "\x94" => 0, "\x95" => 0, "\x96" => 0, "\x97" => 0, + "\x98" => 0, "\x99" => 0, "\x9a" => 0, "\x9b" => 0, "\x9c" => 0, "\x9d" => 0, "\x9e" => 0, "\x9f" => 0, + "\xa0" => 0, "\xa1" => 0, "\xa2" => 0, "\xa3" => 0, "\xa4" => 0, "\xa5" => 0, "\xa6" => 0, "\xa7" => 0, + "\xa8" => 0, "\xa9" => 0, "\xaa" => 0, "\xab" => 0, "\xac" => 0, "\xad" => 0, "\xae" => 0, "\xaf" => 0, + "\xb0" => 0, "\xb1" => 0, "\xb2" => 0, "\xb3" => 0, "\xb4" => 0, "\xb5" => 0, "\xb6" => 0, "\xb7" => 0, + "\xb8" => 0, "\xb9" => 0, "\xba" => 0, "\xbb" => 0, "\xbc" => 0, "\xbd" => 0, "\xbe" => 0, "\xbf" => 0, + "\xc0" => 2, "\xc1" => 2, "\xc2" => 2, "\xc3" => 2, "\xc4" => 2, "\xc5" => 2, "\xc6" => 2, "\xc7" => 2, + "\xc8" => 2, "\xc9" => 2, "\xca" => 2, "\xcb" => 2, "\xcc" => 2, "\xcd" => 2, "\xce" => 2, "\xcf" => 2, + "\xd0" => 2, "\xd1" => 2, "\xd2" => 2, "\xd3" => 2, "\xd4" => 2, "\xd5" => 2, "\xd6" => 2, "\xd7" => 2, + "\xd8" => 2, "\xd9" => 2, "\xda" => 2, "\xdb" => 2, "\xdc" => 2, "\xdd" => 2, "\xde" => 2, "\xdf" => 2, + "\xe0" => 3, "\xe1" => 3, "\xe2" => 3, "\xe3" => 3, "\xe4" => 3, "\xe5" => 3, "\xe6" => 3, "\xe7" => 3, + "\xe8" => 3, "\xe9" => 3, "\xea" => 3, "\xeb" => 3, "\xec" => 3, "\xed" => 3, "\xee" => 3, "\xef" => 3, + "\xf0" => 4, "\xf1" => 4, "\xf2" => 4, "\xf3" => 4, "\xf4" => 4, "\xf5" => 4, "\xf6" => 4, "\xf7" => 4, + "\xf8" => 5, "\xf9" => 5, "\xfa" => 5, "\xfb" => 5, "\xfc" => 6, "\xfd" => 6, "\xfe" => 0, "\xff" => 0, + ]; + + private string $data = ''; + private int $dataSize = 0; + private array $map = []; + private int $charCount = 0; + private int $currentPos = 0; + private int $fixedWidth = 0; + + /** + * @param resource|string $input + */ + public function __construct($input, ?string $charset = 'utf-8') + { + $charset = strtolower(trim($charset)) ?: 'utf-8'; + if ('utf-8' === $charset || 'utf8' === $charset) { + $this->fixedWidth = 0; + $this->map = ['p' => [], 'i' => []]; + } else { + $this->fixedWidth = match ($charset) { + // 16 bits + 'ucs2', + 'ucs-2', + 'utf16', + 'utf-16' => 2, + // 32 bits + 'ucs4', + 'ucs-4', + 'utf32', + 'utf-32' => 4, + // 7-8 bit charsets: (us-)?ascii, (iso|iec)-?8859-?[0-9]+, windows-?125[0-9], cp-?[0-9]+, ansi, macintosh, + // koi-?7, koi-?8-?.+, mik, (cork|t1), v?iscii + // and fallback + default => 1, + }; + } + if (\is_resource($input)) { + $blocks = 16372; + while (false !== $read = fread($input, $blocks)) { + $this->write($read); + } + } else { + $this->write($input); + } + } + + public function read(int $length): ?string + { + if ($this->currentPos >= $this->charCount) { + return null; + } + $length = ($this->currentPos + $length > $this->charCount) ? $this->charCount - $this->currentPos : $length; + if ($this->fixedWidth > 0) { + $len = $length * $this->fixedWidth; + $ret = substr($this->data, $this->currentPos * $this->fixedWidth, $len); + $this->currentPos += $length; + } else { + $end = $this->currentPos + $length; + $end = min($end, $this->charCount); + $ret = ''; + $start = 0; + if ($this->currentPos > 0) { + $start = $this->map['p'][$this->currentPos - 1]; + } + $to = $start; + for (; $this->currentPos < $end; ++$this->currentPos) { + if (isset($this->map['i'][$this->currentPos])) { + $ret .= substr($this->data, $start, $to - $start).'?'; + $start = $this->map['p'][$this->currentPos]; + } else { + $to = $this->map['p'][$this->currentPos]; + } + } + $ret .= substr($this->data, $start, $to - $start); + } + + return $ret; + } + + public function readBytes(int $length): ?array + { + if (null !== $read = $this->read($length)) { + return array_map('ord', str_split($read, 1)); + } + + return null; + } + + public function setPointer(int $charOffset): void + { + if ($this->charCount < $charOffset) { + $charOffset = $this->charCount; + } + $this->currentPos = $charOffset; + } + + public function write(string $chars): void + { + $ignored = ''; + $this->data .= $chars; + if ($this->fixedWidth > 0) { + $strlen = \strlen($chars); + $ignoredL = $strlen % $this->fixedWidth; + $ignored = $ignoredL ? substr($chars, -$ignoredL) : ''; + $this->charCount += ($strlen - $ignoredL) / $this->fixedWidth; + } else { + $this->charCount += $this->getUtf8CharPositions($chars, $this->dataSize, $ignored); + } + $this->dataSize = \strlen($this->data) - \strlen($ignored); + } + + private function getUtf8CharPositions(string $string, int $startOffset, string &$ignoredChars): int + { + $strlen = \strlen($string); + $charPos = \count($this->map['p']); + $foundChars = 0; + $invalid = false; + for ($i = 0; $i < $strlen; ++$i) { + $char = $string[$i]; + $size = self::UTF8_LENGTH_MAP[$char]; + if (0 == $size) { + /* char is invalid, we must wait for a resync */ + $invalid = true; + continue; + } + + if ($invalid) { + /* We mark the chars as invalid and start a new char */ + $this->map['p'][$charPos + $foundChars] = $startOffset + $i; + $this->map['i'][$charPos + $foundChars] = true; + ++$foundChars; + $invalid = false; + } + if (($i + $size) > $strlen) { + $ignoredChars = substr($string, $i); + break; + } + for ($j = 1; $j < $size; ++$j) { + $char = $string[$i + $j]; + if ($char > "\x7F" && $char < "\xC0") { + // Valid - continue parsing + } else { + /* char is invalid, we must wait for a resync */ + $invalid = true; + continue 2; + } + } + /* Ok we got a complete char here */ + $this->map['p'][$charPos + $foundChars] = $startOffset + $i + $size; + $i += $j - 1; + ++$foundChars; + } + + return $foundChars; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Crypto/DkimOptions.php b/lib/SymfonyMailer/vendor/symfony/mime/Crypto/DkimOptions.php new file mode 100644 index 0000000..cee4e7c --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Crypto/DkimOptions.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Crypto; + +/** + * A helper providing autocompletion for available DkimSigner options. + * + * @author Fabien Potencier + */ +final class DkimOptions +{ + private array $options = []; + + public function toArray(): array + { + return $this->options; + } + + /** + * @return $this + */ + public function algorithm(string $algo): static + { + $this->options['algorithm'] = $algo; + + return $this; + } + + /** + * @return $this + */ + public function signatureExpirationDelay(int $show): static + { + $this->options['signature_expiration_delay'] = $show; + + return $this; + } + + /** + * @return $this + */ + public function bodyMaxLength(int $max): static + { + $this->options['body_max_length'] = $max; + + return $this; + } + + /** + * @return $this + */ + public function bodyShowLength(bool $show): static + { + $this->options['body_show_length'] = $show; + + return $this; + } + + /** + * @return $this + */ + public function headerCanon(string $canon): static + { + $this->options['header_canon'] = $canon; + + return $this; + } + + /** + * @return $this + */ + public function bodyCanon(string $canon): static + { + $this->options['body_canon'] = $canon; + + return $this; + } + + /** + * @return $this + */ + public function headersToIgnore(array $headers): static + { + $this->options['headers_to_ignore'] = $headers; + + return $this; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Crypto/DkimSigner.php b/lib/SymfonyMailer/vendor/symfony/mime/Crypto/DkimSigner.php new file mode 100644 index 0000000..378aea7 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Crypto/DkimSigner.php @@ -0,0 +1,217 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Crypto; + +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Exception\RuntimeException; +use Symfony\Component\Mime\Header\UnstructuredHeader; +use Symfony\Component\Mime\Message; +use Symfony\Component\Mime\Part\AbstractPart; + +/** + * @author Fabien Potencier + * + * RFC 6376 and 8301 + */ +final class DkimSigner +{ + public const CANON_SIMPLE = 'simple'; + public const CANON_RELAXED = 'relaxed'; + + public const ALGO_SHA256 = 'rsa-sha256'; + public const ALGO_ED25519 = 'ed25519-sha256'; // RFC 8463 + + private \OpenSSLAsymmetricKey $key; + + /** + * @param string $pk The private key as a string or the path to the file containing the private key, should be prefixed with file:// (in PEM format) + * @param string $passphrase A passphrase of the private key (if any) + */ + public function __construct( + string $pk, + private string $domainName, + private string $selector, + private array $defaultOptions = [], + string $passphrase = '', + ) { + if (!\extension_loaded('openssl')) { + throw new \LogicException('PHP extension "openssl" is required to use DKIM.'); + } + $this->key = openssl_pkey_get_private($pk, $passphrase) ?: throw new InvalidArgumentException('Unable to load DKIM private key: '.openssl_error_string()); + $this->defaultOptions += [ + 'algorithm' => self::ALGO_SHA256, + 'signature_expiration_delay' => 0, + 'body_max_length' => \PHP_INT_MAX, + 'body_show_length' => false, + 'header_canon' => self::CANON_RELAXED, + 'body_canon' => self::CANON_RELAXED, + 'headers_to_ignore' => [], + ]; + } + + public function sign(Message $message, array $options = []): Message + { + $options += $this->defaultOptions; + if (!\in_array($options['algorithm'], [self::ALGO_SHA256, self::ALGO_ED25519], true)) { + throw new InvalidArgumentException(\sprintf('Invalid DKIM signing algorithm "%s".', $options['algorithm'])); + } + $headersToIgnore['return-path'] = true; + $headersToIgnore['x-transport'] = true; + foreach ($options['headers_to_ignore'] as $name) { + $headersToIgnore[strtolower($name)] = true; + } + unset($headersToIgnore['from']); + $signedHeaderNames = []; + $headerCanonData = ''; + $headers = $message->getPreparedHeaders(); + foreach ($headers->getNames() as $name) { + foreach ($headers->all($name) as $header) { + if (isset($headersToIgnore[strtolower($header->getName())])) { + continue; + } + + if ('' !== $header->getBodyAsString()) { + $headerCanonData .= $this->canonicalizeHeader($header->toString(), $options['header_canon']); + $signedHeaderNames[] = $header->getName(); + } + } + } + + [$bodyHash, $bodyLength] = $this->hashBody($message->getBody(), $options['body_canon'], $options['body_max_length']); + + $params = [ + 'v' => '1', + 'q' => 'dns/txt', + 'a' => $options['algorithm'], + 'bh' => base64_encode($bodyHash), + 'd' => $this->domainName, + 'h' => implode(': ', $signedHeaderNames), + 'i' => '@'.$this->domainName, + 's' => $this->selector, + 't' => time(), + 'c' => $options['header_canon'].'/'.$options['body_canon'], + ]; + + if ($options['body_show_length']) { + $params['l'] = $bodyLength; + } + if ($options['signature_expiration_delay']) { + $params['x'] = $params['t'] + $options['signature_expiration_delay']; + } + $value = ''; + foreach ($params as $k => $v) { + $value .= $k.'='.$v.'; '; + } + $value = trim($value); + $header = new UnstructuredHeader('DKIM-Signature', $value); + $headerCanonData .= rtrim($this->canonicalizeHeader($header->toString()."\r\n b=", $options['header_canon'])); + if (self::ALGO_SHA256 === $options['algorithm']) { + if (!openssl_sign($headerCanonData, $signature, $this->key, \OPENSSL_ALGO_SHA256)) { + throw new RuntimeException('Unable to sign DKIM hash: '.openssl_error_string()); + } + } else { + throw new \RuntimeException(\sprintf('The "%s" DKIM signing algorithm is not supported yet.', self::ALGO_ED25519)); + } + $header->setValue($value.' b='.trim(chunk_split(base64_encode($signature), 73, ' '))); + $headers->add($header); + + return new Message($headers, $message->getBody()); + } + + private function canonicalizeHeader(string $header, string $headerCanon): string + { + if (self::CANON_RELAXED !== $headerCanon) { + return $header."\r\n"; + } + + $exploded = explode(':', $header, 2); + $name = strtolower(trim($exploded[0])); + $value = str_replace("\r\n", '', $exploded[1]); + $value = trim(preg_replace("/[ \t][ \t]+/", ' ', $value)); + + return $name.':'.$value."\r\n"; + } + + private function hashBody(AbstractPart $body, string $bodyCanon, int $maxLength): array + { + $hash = hash_init('sha256'); + $relaxed = self::CANON_RELAXED === $bodyCanon; + $currentLine = ''; + $emptyCounter = 0; + $isSpaceSequence = false; + $length = 0; + foreach ($body->bodyToIterable() as $chunk) { + $canon = ''; + for ($i = 0, $len = \strlen($chunk); $i < $len; ++$i) { + switch ($chunk[$i]) { + case "\r": + break; + case "\n": + // previous char is always \r + if ($relaxed) { + $isSpaceSequence = false; + } + if ('' === $currentLine) { + ++$emptyCounter; + } else { + $currentLine = ''; + $canon .= "\r\n"; + } + break; + case ' ': + case "\t": + if ($relaxed) { + $isSpaceSequence = true; + break; + } + // no break + default: + if ($emptyCounter > 0) { + $canon .= str_repeat("\r\n", $emptyCounter); + $emptyCounter = 0; + } + if ($isSpaceSequence) { + $currentLine .= ' '; + $canon .= ' '; + $isSpaceSequence = false; + } + $currentLine .= $chunk[$i]; + $canon .= $chunk[$i]; + } + } + + if ($length + \strlen($canon) >= $maxLength) { + $canon = substr($canon, 0, $maxLength - $length); + $length += \strlen($canon); + hash_update($hash, $canon); + + break; + } + + $length += \strlen($canon); + hash_update($hash, $canon); + } + + // Add trailing Line return if last line is non empty + if ('' !== $currentLine) { + hash_update($hash, "\r\n"); + $length += \strlen("\r\n"); + } + + if (!$relaxed && 0 === $length) { + hash_update($hash, "\r\n"); + $length = 2; + } + + return [hash_final($hash, true), $length]; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Crypto/SMime.php b/lib/SymfonyMailer/vendor/symfony/mime/Crypto/SMime.php new file mode 100644 index 0000000..f72ba01 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Crypto/SMime.php @@ -0,0 +1,111 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Crypto; + +use Symfony\Component\Mime\Exception\RuntimeException; +use Symfony\Component\Mime\Part\SMimePart; + +/** + * @author Sebastiaan Stok + * + * @internal + */ +abstract class SMime +{ + protected function normalizeFilePath(string $path): string + { + if (!file_exists($path)) { + throw new RuntimeException(\sprintf('File does not exist: "%s".', $path)); + } + + return 'file://'.str_replace('\\', '/', realpath($path)); + } + + protected function iteratorToFile(iterable $iterator, $stream): void + { + foreach ($iterator as $chunk) { + fwrite($stream, $chunk); + } + } + + protected function convertMessageToSMimePart($stream, string $type, string $subtype): SMimePart + { + rewind($stream); + + $headers = ''; + + while (!feof($stream)) { + $buffer = fread($stream, 78); + $headers .= $buffer; + + // Detect ending of header list + if (preg_match('/(\r\n\r\n|\n\n)/', $headers, $match)) { + $headersPosEnd = strpos($headers, $headerBodySeparator = $match[0]); + + break; + } + } + + $headers = $this->getMessageHeaders(trim(substr($headers, 0, $headersPosEnd))); + + fseek($stream, $headersPosEnd + \strlen($headerBodySeparator)); + + return new SMimePart($this->getStreamIterator($stream), $type, $subtype, $this->getParametersFromHeader($headers['content-type'])); + } + + protected function getStreamIterator($stream): iterable + { + while (!feof($stream)) { + yield str_replace("\n", "\r\n", str_replace("\r\n", "\n", fread($stream, 16372))); + } + } + + private function getMessageHeaders(string $headerData): array + { + $headers = []; + $headerLines = explode("\r\n", str_replace("\n", "\r\n", str_replace("\r\n", "\n", $headerData))); + $currentHeaderName = ''; + + // Transform header lines into an associative array + foreach ($headerLines as $headerLine) { + // Empty lines between headers indicate a new mime-entity + if ('' === $headerLine) { + break; + } + + // Handle headers that span multiple lines + if (!str_contains($headerLine, ':')) { + $headers[$currentHeaderName] .= ' '.trim($headerLine); + continue; + } + + $header = explode(':', $headerLine, 2); + $currentHeaderName = strtolower($header[0]); + $headers[$currentHeaderName] = trim($header[1]); + } + + return $headers; + } + + private function getParametersFromHeader(string $header): array + { + $params = []; + + preg_match_all('/(?P[a-z-0-9]+)=(?P"[^"]+"|(?:[^\s;]+|$))(?:\s+;)?/i', $header, $matches); + + foreach ($matches['value'] as $pos => $paramValue) { + $params[$matches['name'][$pos]] = trim($paramValue, '"'); + } + + return $params; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Crypto/SMimeEncrypter.php b/lib/SymfonyMailer/vendor/symfony/mime/Crypto/SMimeEncrypter.php new file mode 100644 index 0000000..d7c0af6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Crypto/SMimeEncrypter.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Crypto; + +use Symfony\Component\Mime\Exception\RuntimeException; +use Symfony\Component\Mime\Message; + +/** + * @author Sebastiaan Stok + */ +final class SMimeEncrypter extends SMime +{ + private string|array $certs; + private int $cipher; + + /** + * @param string|string[] $certificate The path (or array of paths) of the file(s) containing the X.509 certificate(s) + * @param int|null $cipher A set of algorithms used to encrypt the message. Must be one of these PHP constants: https://php.net/openssl.ciphers + */ + public function __construct(string|array $certificate, ?int $cipher = null) + { + if (!\extension_loaded('openssl')) { + throw new \LogicException('PHP extension "openssl" is required to use SMime.'); + } + + if (\is_array($certificate)) { + $this->certs = array_map($this->normalizeFilePath(...), $certificate); + } else { + $this->certs = $this->normalizeFilePath($certificate); + } + + $this->cipher = $cipher ?? \OPENSSL_CIPHER_AES_256_CBC; + } + + public function encrypt(Message $message): Message + { + $bufferFile = tmpfile(); + $outputFile = tmpfile(); + + $this->iteratorToFile($message->toIterable(), $bufferFile); + + if (!@openssl_pkcs7_encrypt(stream_get_meta_data($bufferFile)['uri'], stream_get_meta_data($outputFile)['uri'], $this->certs, [], 0, $this->cipher)) { + throw new RuntimeException(\sprintf('Failed to encrypt S/Mime message. Error: "%s".', openssl_error_string())); + } + + $mimePart = $this->convertMessageToSMimePart($outputFile, 'application', 'pkcs7-mime'); + $mimePart->getHeaders() + ->addTextHeader('Content-Transfer-Encoding', 'base64') + ->addParameterizedHeader('Content-Disposition', 'attachment', ['name' => 'smime.p7m']) + ; + + return new Message($message->getHeaders(), $mimePart); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Crypto/SMimeSigner.php b/lib/SymfonyMailer/vendor/symfony/mime/Crypto/SMimeSigner.php new file mode 100644 index 0000000..d17e177 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Crypto/SMimeSigner.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Crypto; + +use Symfony\Component\Mime\Exception\RuntimeException; +use Symfony\Component\Mime\Message; + +/** + * @author Sebastiaan Stok + */ +final class SMimeSigner extends SMime +{ + private string $signCertificate; + private string|array $signPrivateKey; + private int $signOptions; + private ?string $extraCerts; + + /** + * @param string $certificate The path of the file containing the signing certificate (in PEM format) + * @param string $privateKey The path of the file containing the private key (in PEM format) + * @param string|null $privateKeyPassphrase A passphrase of the private key (if any) + * @param string|null $extraCerts The path of the file containing intermediate certificates (in PEM format) needed by the signing certificate + * @param int|null $signOptions Bitwise operator options for openssl_pkcs7_sign() (@see https://secure.php.net/manual/en/openssl.pkcs7.flags.php) + */ + public function __construct(string $certificate, string $privateKey, ?string $privateKeyPassphrase = null, ?string $extraCerts = null, ?int $signOptions = null) + { + if (!\extension_loaded('openssl')) { + throw new \LogicException('PHP extension "openssl" is required to use SMime.'); + } + + $this->signCertificate = $this->normalizeFilePath($certificate); + + if (null !== $privateKeyPassphrase) { + $this->signPrivateKey = [$this->normalizeFilePath($privateKey), $privateKeyPassphrase]; + } else { + $this->signPrivateKey = $this->normalizeFilePath($privateKey); + } + + $this->signOptions = $signOptions ?? \PKCS7_DETACHED; + $this->extraCerts = $extraCerts ? realpath($extraCerts) : null; + } + + public function sign(Message $message): Message + { + $bufferFile = tmpfile(); + $outputFile = tmpfile(); + + $this->iteratorToFile($message->getBody()->toIterable(), $bufferFile); + + if (!@openssl_pkcs7_sign(stream_get_meta_data($bufferFile)['uri'], stream_get_meta_data($outputFile)['uri'], $this->signCertificate, $this->signPrivateKey, [], $this->signOptions, $this->extraCerts)) { + throw new RuntimeException(\sprintf('Failed to sign S/Mime message. Error: "%s".', openssl_error_string())); + } + + return new Message($message->getHeaders(), $this->convertMessageToSMimePart($outputFile, 'multipart', 'signed')); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php b/lib/SymfonyMailer/vendor/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php new file mode 100644 index 0000000..897743f --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Registers custom mime types guessers. + * + * @author Fabien Potencier + */ +class AddMimeTypeGuesserPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container): void + { + if ($container->has('mime_types')) { + $definition = $container->findDefinition('mime_types'); + foreach ($container->findTaggedServiceIds('mime.mime_type_guesser', true) as $id => $attributes) { + $definition->addMethodCall('registerGuesser', [new Reference($id)]); + } + } + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/DraftEmail.php b/lib/SymfonyMailer/vendor/symfony/mime/DraftEmail.php new file mode 100644 index 0000000..82ce763 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/DraftEmail.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Header\Headers; +use Symfony\Component\Mime\Part\AbstractPart; + +/** + * @author Kevin Bond + */ +class DraftEmail extends Email +{ + public function __construct(?Headers $headers = null, ?AbstractPart $body = null) + { + parent::__construct($headers, $body); + + $this->getHeaders()->addTextHeader('X-Unsent', '1'); + } + + /** + * Override default behavior as draft emails do not require From/Sender/Date/Message-ID headers. + * These are added by the client that actually sends the email. + */ + public function getPreparedHeaders(): Headers + { + $headers = clone $this->getHeaders(); + + if (!$headers->has('MIME-Version')) { + $headers->addTextHeader('MIME-Version', '1.0'); + } + + $headers->remove('Bcc'); + + return $headers; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Email.php b/lib/SymfonyMailer/vendor/symfony/mime/Email.php new file mode 100644 index 0000000..e238ce3 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Email.php @@ -0,0 +1,576 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\LogicException; +use Symfony\Component\Mime\Part\AbstractPart; +use Symfony\Component\Mime\Part\DataPart; +use Symfony\Component\Mime\Part\File; +use Symfony\Component\Mime\Part\Multipart\AlternativePart; +use Symfony\Component\Mime\Part\Multipart\MixedPart; +use Symfony\Component\Mime\Part\Multipart\RelatedPart; +use Symfony\Component\Mime\Part\TextPart; + +/** + * @author Fabien Potencier + */ +class Email extends Message +{ + public const PRIORITY_HIGHEST = 1; + public const PRIORITY_HIGH = 2; + public const PRIORITY_NORMAL = 3; + public const PRIORITY_LOW = 4; + public const PRIORITY_LOWEST = 5; + + private const PRIORITY_MAP = [ + self::PRIORITY_HIGHEST => 'Highest', + self::PRIORITY_HIGH => 'High', + self::PRIORITY_NORMAL => 'Normal', + self::PRIORITY_LOW => 'Low', + self::PRIORITY_LOWEST => 'Lowest', + ]; + + /** + * @var resource|string|null + */ + private $text; + + private ?string $textCharset = null; + + /** + * @var resource|string|null + */ + private $html; + + private ?string $htmlCharset = null; + private array $attachments = []; + private ?AbstractPart $cachedBody = null; // Used to avoid wrong body hash in DKIM signatures with multiple parts (e.g. HTML + TEXT) due to multiple boundaries. + + /** + * @return $this + */ + public function subject(string $subject): static + { + return $this->setHeaderBody('Text', 'Subject', $subject); + } + + public function getSubject(): ?string + { + return $this->getHeaders()->getHeaderBody('Subject'); + } + + /** + * @return $this + */ + public function date(\DateTimeInterface $dateTime): static + { + return $this->setHeaderBody('Date', 'Date', $dateTime); + } + + public function getDate(): ?\DateTimeImmutable + { + return $this->getHeaders()->getHeaderBody('Date'); + } + + /** + * @return $this + */ + public function returnPath(Address|string $address): static + { + return $this->setHeaderBody('Path', 'Return-Path', Address::create($address)); + } + + public function getReturnPath(): ?Address + { + return $this->getHeaders()->getHeaderBody('Return-Path'); + } + + /** + * @return $this + */ + public function sender(Address|string $address): static + { + return $this->setHeaderBody('Mailbox', 'Sender', Address::create($address)); + } + + public function getSender(): ?Address + { + return $this->getHeaders()->getHeaderBody('Sender'); + } + + /** + * @return $this + */ + public function addFrom(Address|string ...$addresses): static + { + return $this->addListAddressHeaderBody('From', $addresses); + } + + /** + * @return $this + */ + public function from(Address|string ...$addresses): static + { + if (!$addresses) { + throw new LogicException('"from()" must be called with at least one address.'); + } + + return $this->setListAddressHeaderBody('From', $addresses); + } + + /** + * @return Address[] + */ + public function getFrom(): array + { + return $this->getHeaders()->getHeaderBody('From') ?: []; + } + + /** + * @return $this + */ + public function addReplyTo(Address|string ...$addresses): static + { + return $this->addListAddressHeaderBody('Reply-To', $addresses); + } + + /** + * @return $this + */ + public function replyTo(Address|string ...$addresses): static + { + return $this->setListAddressHeaderBody('Reply-To', $addresses); + } + + /** + * @return Address[] + */ + public function getReplyTo(): array + { + return $this->getHeaders()->getHeaderBody('Reply-To') ?: []; + } + + /** + * @return $this + */ + public function addTo(Address|string ...$addresses): static + { + return $this->addListAddressHeaderBody('To', $addresses); + } + + /** + * @return $this + */ + public function to(Address|string ...$addresses): static + { + return $this->setListAddressHeaderBody('To', $addresses); + } + + /** + * @return Address[] + */ + public function getTo(): array + { + return $this->getHeaders()->getHeaderBody('To') ?: []; + } + + /** + * @return $this + */ + public function addCc(Address|string ...$addresses): static + { + return $this->addListAddressHeaderBody('Cc', $addresses); + } + + /** + * @return $this + */ + public function cc(Address|string ...$addresses): static + { + return $this->setListAddressHeaderBody('Cc', $addresses); + } + + /** + * @return Address[] + */ + public function getCc(): array + { + return $this->getHeaders()->getHeaderBody('Cc') ?: []; + } + + /** + * @return $this + */ + public function addBcc(Address|string ...$addresses): static + { + return $this->addListAddressHeaderBody('Bcc', $addresses); + } + + /** + * @return $this + */ + public function bcc(Address|string ...$addresses): static + { + return $this->setListAddressHeaderBody('Bcc', $addresses); + } + + /** + * @return Address[] + */ + public function getBcc(): array + { + return $this->getHeaders()->getHeaderBody('Bcc') ?: []; + } + + /** + * Sets the priority of this message. + * + * The value is an integer where 1 is the highest priority and 5 is the lowest. + * + * @return $this + */ + public function priority(int $priority): static + { + if ($priority > 5) { + $priority = 5; + } elseif ($priority < 1) { + $priority = 1; + } + + return $this->setHeaderBody('Text', 'X-Priority', \sprintf('%d (%s)', $priority, self::PRIORITY_MAP[$priority])); + } + + /** + * Get the priority of this message. + * + * The returned value is an integer where 1 is the highest priority and 5 + * is the lowest. + */ + public function getPriority(): int + { + [$priority] = sscanf($this->getHeaders()->getHeaderBody('X-Priority') ?? '', '%[1-5]'); + + return $priority ?? 3; + } + + /** + * @param resource|string|null $body + * + * @return $this + */ + public function text($body, string $charset = 'utf-8'): static + { + if (null !== $body && !\is_string($body) && !\is_resource($body)) { + throw new \TypeError(\sprintf('The body must be a string, a resource or null (got "%s").', get_debug_type($body))); + } + + $this->cachedBody = null; + $this->text = $body; + $this->textCharset = $charset; + + return $this; + } + + /** + * @return resource|string|null + */ + public function getTextBody() + { + return $this->text; + } + + public function getTextCharset(): ?string + { + return $this->textCharset; + } + + /** + * @param resource|string|null $body + * + * @return $this + */ + public function html($body, string $charset = 'utf-8'): static + { + if (null !== $body && !\is_string($body) && !\is_resource($body)) { + throw new \TypeError(\sprintf('The body must be a string, a resource or null (got "%s").', get_debug_type($body))); + } + + $this->cachedBody = null; + $this->html = $body; + $this->htmlCharset = $charset; + + return $this; + } + + /** + * @return resource|string|null + */ + public function getHtmlBody() + { + return $this->html; + } + + public function getHtmlCharset(): ?string + { + return $this->htmlCharset; + } + + /** + * @param resource|string $body + * + * @return $this + */ + public function attach($body, ?string $name = null, ?string $contentType = null): static + { + return $this->addPart(new DataPart($body, $name, $contentType)); + } + + /** + * @return $this + */ + public function attachFromPath(string $path, ?string $name = null, ?string $contentType = null): static + { + return $this->addPart(new DataPart(new File($path), $name, $contentType)); + } + + /** + * @param resource|string $body + * + * @return $this + */ + public function embed($body, ?string $name = null, ?string $contentType = null): static + { + return $this->addPart((new DataPart($body, $name, $contentType))->asInline()); + } + + /** + * @return $this + */ + public function embedFromPath(string $path, ?string $name = null, ?string $contentType = null): static + { + return $this->addPart((new DataPart(new File($path), $name, $contentType))->asInline()); + } + + /** + * @return $this + */ + public function addPart(DataPart $part): static + { + $this->cachedBody = null; + $this->attachments[] = $part; + + return $this; + } + + /** + * @return DataPart[] + */ + public function getAttachments(): array + { + return $this->attachments; + } + + public function getBody(): AbstractPart + { + if (null !== $body = parent::getBody()) { + return $body; + } + + return $this->generateBody(); + } + + public function ensureValidity(): void + { + $this->ensureBodyValid(); + + if ('1' === $this->getHeaders()->getHeaderBody('X-Unsent')) { + throw new LogicException('Cannot send messages marked as "draft".'); + } + + parent::ensureValidity(); + } + + private function ensureBodyValid(): void + { + if (null === $this->text && null === $this->html && !$this->attachments && null === parent::getBody()) { + throw new LogicException('A message must have a text or an HTML part or attachments.'); + } + } + + /** + * Generates an AbstractPart based on the raw body of a message. + * + * The most "complex" part generated by this method is when there is text and HTML bodies + * with related images for the HTML part and some attachments: + * + * multipart/mixed + * | + * |------------> multipart/related + * | | + * | |------------> multipart/alternative + * | | | + * | | ------------> text/plain (with content) + * | | | + * | | ------------> text/html (with content) + * | | + * | ------------> image/png (with content) + * | + * ------------> application/pdf (with content) + */ + private function generateBody(): AbstractPart + { + if (null !== $this->cachedBody) { + return $this->cachedBody; + } + + $this->ensureBodyValid(); + + [$htmlPart, $otherParts, $relatedParts] = $this->prepareParts(); + + $part = null === $this->text ? null : new TextPart($this->text, $this->textCharset); + if (null !== $htmlPart) { + if (null !== $part) { + $part = new AlternativePart($part, $htmlPart); + } else { + $part = $htmlPart; + } + } + + if ($relatedParts) { + $part = new RelatedPart($part, ...$relatedParts); + } + + if ($otherParts) { + if ($part) { + $part = new MixedPart($part, ...$otherParts); + } else { + $part = new MixedPart(...$otherParts); + } + } + + return $this->cachedBody = $part; + } + + private function prepareParts(): ?array + { + $names = []; + $htmlPart = null; + $html = $this->html; + if (null !== $html) { + $htmlPart = new TextPart($html, $this->htmlCharset, 'html'); + $html = $htmlPart->getBody(); + + $regexes = [ + ']*src\s*=\s*(?:([\'"])cid:(.+?)\\1|cid:([^>\s]+))', + '<\w+\s+[^>]*background\s*=\s*(?:([\'"])cid:(.+?)\\1|cid:([^>\s]+))', + ]; + $tmpMatches = []; + foreach ($regexes as $regex) { + preg_match_all('/'.$regex.'/i', $html, $tmpMatches); + $names = array_merge($names, $tmpMatches[2], $tmpMatches[3]); + } + $names = array_filter(array_unique($names)); + } + + $otherParts = $relatedParts = []; + foreach ($this->attachments as $part) { + foreach ($names as $name) { + if ($name !== $part->getName() && (!$part->hasContentId() || $name !== $part->getContentId())) { + continue; + } + if (isset($relatedParts[$name])) { + continue 2; + } + + if ($name !== $part->getContentId()) { + $html = str_replace('cid:'.$name, 'cid:'.$part->getContentId(), $html, $count); + } + $relatedParts[$name] = $part; + $part->setName($part->getContentId())->asInline(); + + continue 2; + } + + $otherParts[] = $part; + } + if (null !== $htmlPart) { + $htmlPart = new TextPart($html, $this->htmlCharset, 'html'); + } + + return [$htmlPart, $otherParts, array_values($relatedParts)]; + } + + /** + * @return $this + */ + private function setHeaderBody(string $type, string $name, $body): static + { + $this->getHeaders()->setHeaderBody($type, $name, $body); + + return $this; + } + + /** + * @return $this + */ + private function addListAddressHeaderBody(string $name, array $addresses): static + { + if (!$header = $this->getHeaders()->get($name)) { + return $this->setListAddressHeaderBody($name, $addresses); + } + $header->addAddresses(Address::createArray($addresses)); + + return $this; + } + + /** + * @return $this + */ + private function setListAddressHeaderBody(string $name, array $addresses): static + { + $addresses = Address::createArray($addresses); + $headers = $this->getHeaders(); + if ($header = $headers->get($name)) { + $header->setAddresses($addresses); + } else { + $headers->addMailboxListHeader($name, $addresses); + } + + return $this; + } + + /** + * @internal + */ + public function __serialize(): array + { + if (\is_resource($this->text)) { + $this->text = (new TextPart($this->text))->getBody(); + } + + if (\is_resource($this->html)) { + $this->html = (new TextPart($this->html))->getBody(); + } + + return [$this->text, $this->textCharset, $this->html, $this->htmlCharset, $this->attachments, parent::__serialize()]; + } + + /** + * @internal + */ + public function __unserialize(array $data): void + { + [$this->text, $this->textCharset, $this->html, $this->htmlCharset, $this->attachments, $parentData] = $data; + + parent::__unserialize($parentData); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Encoder/AddressEncoderInterface.php b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/AddressEncoderInterface.php new file mode 100644 index 0000000..de477d8 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/AddressEncoderInterface.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +use Symfony\Component\Mime\Exception\AddressEncoderException; + +/** + * @author Christian Schmidt + */ +interface AddressEncoderInterface +{ + /** + * Encodes an email address. + * + * @throws AddressEncoderException if the email cannot be represented in + * the encoding implemented by this class + */ + public function encodeString(string $address): string; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Encoder/Base64ContentEncoder.php b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/Base64ContentEncoder.php new file mode 100644 index 0000000..07cbca3 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/Base64ContentEncoder.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +use Symfony\Component\Mime\Exception\RuntimeException; + +/** + * @author Fabien Potencier + */ +final class Base64ContentEncoder extends Base64Encoder implements ContentEncoderInterface +{ + public function encodeByteStream($stream, int $maxLineLength = 0): iterable + { + if (!\is_resource($stream)) { + throw new \TypeError(\sprintf('Method "%s" takes a stream as a first argument.', __METHOD__)); + } + + $filter = stream_filter_append($stream, 'convert.base64-encode', \STREAM_FILTER_READ, [ + 'line-length' => 0 >= $maxLineLength || 76 < $maxLineLength ? 76 : $maxLineLength, + 'line-break-chars' => "\r\n", + ]); + if (!\is_resource($filter)) { + throw new RuntimeException('Unable to set the base64 content encoder to the filter.'); + } + + while (!feof($stream)) { + yield fread($stream, 16372); + } + stream_filter_remove($filter); + } + + public function getName(): string + { + return 'base64'; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Encoder/Base64Encoder.php b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/Base64Encoder.php new file mode 100644 index 0000000..7106478 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/Base64Encoder.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Chris Corbyn + */ +class Base64Encoder implements EncoderInterface +{ + /** + * Takes an unencoded string and produces a Base64 encoded string from it. + * + * Base64 encoded strings have a maximum line length of 76 characters. + * If the first line needs to be shorter, indicate the difference with + * $firstLineOffset. + */ + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string + { + if (0 >= $maxLineLength || 76 < $maxLineLength) { + $maxLineLength = 76; + } + + $encodedString = base64_encode($string); + $firstLine = ''; + if (0 !== $firstLineOffset) { + $firstLine = substr($encodedString, 0, $maxLineLength - $firstLineOffset)."\r\n"; + $encodedString = substr($encodedString, $maxLineLength - $firstLineOffset); + } + + return $firstLine.trim(chunk_split($encodedString, $maxLineLength, "\r\n")); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Encoder/Base64MimeHeaderEncoder.php b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/Base64MimeHeaderEncoder.php new file mode 100644 index 0000000..5c06f6d --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/Base64MimeHeaderEncoder.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Chris Corbyn + */ +final class Base64MimeHeaderEncoder extends Base64Encoder implements MimeHeaderEncoderInterface +{ + public function getName(): string + { + return 'B'; + } + + /** + * Takes an unencoded string and produces a Base64 encoded string from it. + * + * If the charset is iso-2022-jp, it uses mb_encode_mimeheader instead of + * default encodeString, otherwise pass to the parent method. + */ + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string + { + if ('iso-2022-jp' === strtolower($charset)) { + $old = mb_internal_encoding(); + mb_internal_encoding('utf-8'); + $newstring = mb_encode_mimeheader($string, 'iso-2022-jp', $this->getName(), "\r\n"); + mb_internal_encoding($old); + + return $newstring; + } + + return parent::encodeString($string, $charset, $firstLineOffset, $maxLineLength); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Encoder/ContentEncoderInterface.php b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/ContentEncoderInterface.php new file mode 100644 index 0000000..a45ad04 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/ContentEncoderInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Chris Corbyn + */ +interface ContentEncoderInterface extends EncoderInterface +{ + /** + * Encodes the stream to a Generator. + * + * @param resource $stream + */ + public function encodeByteStream($stream, int $maxLineLength = 0): iterable; + + /** + * Gets the MIME name of this content encoding scheme. + */ + public function getName(): string; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Encoder/EightBitContentEncoder.php b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/EightBitContentEncoder.php new file mode 100644 index 0000000..8283120 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/EightBitContentEncoder.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Fabien Potencier + */ +final class EightBitContentEncoder implements ContentEncoderInterface +{ + public function encodeByteStream($stream, int $maxLineLength = 0): iterable + { + while (!feof($stream)) { + yield fread($stream, 16372); + } + } + + public function getName(): string + { + return '8bit'; + } + + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string + { + return $string; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Encoder/EncoderInterface.php b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/EncoderInterface.php new file mode 100644 index 0000000..bbf6d48 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/EncoderInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Chris Corbyn + */ +interface EncoderInterface +{ + /** + * Encode a given string to produce an encoded string. + * + * @param int $firstLineOffset if first line needs to be shorter + * @param int $maxLineLength - 0 indicates the default length for this encoding + */ + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Encoder/IdnAddressEncoder.php b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/IdnAddressEncoder.php new file mode 100644 index 0000000..07a32e9 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/IdnAddressEncoder.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * An IDN email address encoder. + * + * Encodes the domain part of an address using IDN. This is compatible will all + * SMTP servers. + * + * Note: It leaves the local part as is. In case there are non-ASCII characters + * in the local part then it depends on the SMTP Server if this is supported. + * + * @author Christian Schmidt + */ +final class IdnAddressEncoder implements AddressEncoderInterface +{ + /** + * Encodes the domain part of an address using IDN. + */ + public function encodeString(string $address): string + { + $i = strrpos($address, '@'); + if (false !== $i) { + $local = substr($address, 0, $i); + $domain = substr($address, $i + 1); + + if (preg_match('/[^\x00-\x7F]/', $domain)) { + $address = \sprintf('%s@%s', $local, idn_to_ascii($domain, \IDNA_DEFAULT | \IDNA_USE_STD3_RULES | \IDNA_CHECK_BIDI | \IDNA_CHECK_CONTEXTJ | \IDNA_NONTRANSITIONAL_TO_ASCII, \INTL_IDNA_VARIANT_UTS46)); + } + } + + return $address; + } +} diff --git a/lib/SwiftMailer/classes/Swift/Mime/HeaderEncoder.php b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/MimeHeaderEncoderInterface.php similarity index 52% rename from lib/SwiftMailer/classes/Swift/Mime/HeaderEncoder.php rename to lib/SymfonyMailer/vendor/symfony/mime/Encoder/MimeHeaderEncoderInterface.php index 08fd453..fff2c78 100644 --- a/lib/SwiftMailer/classes/Swift/Mime/HeaderEncoder.php +++ b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/MimeHeaderEncoderInterface.php @@ -1,24 +1,23 @@ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ +namespace Symfony\Component\Mime\Encoder; + /** - * Interface for all Header Encoding schemes. - * * @author Chris Corbyn */ -interface Swift_Mime_HeaderEncoder extends Swift_Encoder +interface MimeHeaderEncoderInterface { /** * Get the MIME name of this content encoding scheme. - * - * @return string */ - public function getName(); + public function getName(): string; } diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Encoder/QpContentEncoder.php b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/QpContentEncoder.php new file mode 100644 index 0000000..c425b67 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/QpContentEncoder.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Lars Strojny + */ +final class QpContentEncoder implements ContentEncoderInterface +{ + public function encodeByteStream($stream, int $maxLineLength = 0): iterable + { + if (!\is_resource($stream)) { + throw new \TypeError(\sprintf('Method "%s" takes a stream as a first argument.', __METHOD__)); + } + + // we don't use PHP stream filters here as the content should be small enough + yield $this->encodeString(stream_get_contents($stream), 'utf-8', 0, $maxLineLength); + } + + public function getName(): string + { + return 'quoted-printable'; + } + + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string + { + return $this->standardize(quoted_printable_encode($string)); + } + + /** + * Make sure CRLF is correct and HT/SPACE are in valid places. + */ + private function standardize(string $string): string + { + // transform CR or LF to CRLF + $string = preg_replace('~=0D(?!=0A)|(? substr_replace($string, '=09', -1), + "\x20" => substr_replace($string, '=20', -1), + default => $string, + }; + } +} diff --git a/lib/SwiftMailer/classes/Swift/Encoder/QpEncoder.php b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/QpEncoder.php similarity index 55% rename from lib/SwiftMailer/classes/Swift/Encoder/QpEncoder.php rename to lib/SymfonyMailer/vendor/symfony/mime/Encoder/QpEncoder.php index 8a81fe3..76ec445 100644 --- a/lib/SwiftMailer/classes/Swift/Encoder/QpEncoder.php +++ b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/QpEncoder.php @@ -1,42 +1,27 @@ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ +namespace Symfony\Component\Mime\Encoder; + +use Symfony\Component\Mime\CharacterStream; + /** - * Handles Quoted Printable (QP) Encoding in Swift Mailer. - * - * Possibly the most accurate RFC 2045 QP implementation found in PHP. - * * @author Chris Corbyn */ -class Swift_Encoder_QpEncoder implements Swift_Encoder +class QpEncoder implements EncoderInterface { - /** - * The CharacterStream used for reading characters (as opposed to bytes). - * - * @var Swift_CharacterStream - */ - protected $_charStream; - - /** - * A filter used if input should be canonicalized. - * - * @var Swift_StreamFilter - */ - protected $_filter; - /** * Pre-computed QP for HUGE optimization. - * - * @var string[] */ - protected static $_qpMap = array( + private const QP_MAP = [ 0 => '=00', 1 => '=01', 2 => '=02', 3 => '=03', 4 => '=04', 5 => '=05', 6 => '=06', 7 => '=07', 8 => '=08', 9 => '=09', 10 => '=0A', 11 => '=0B', 12 => '=0C', 13 => '=0D', 14 => '=0E', @@ -89,60 +74,34 @@ class Swift_Encoder_QpEncoder implements Swift_Encoder 245 => '=F5', 246 => '=F6', 247 => '=F7', 248 => '=F8', 249 => '=F9', 250 => '=FA', 251 => '=FB', 252 => '=FC', 253 => '=FD', 254 => '=FE', 255 => '=FF', - ); + ]; - protected static $_safeMapShare = array(); + private static array $safeMapShare = []; /** * A map of non-encoded ascii characters. * * @var string[] - */ - protected $_safeMap = array(); - - /** - * Creates a new QpEncoder for the given CharacterStream. * - * @param Swift_CharacterStream $charStream to use for reading characters - * @param Swift_StreamFilter $filter if input should be canonicalized + * @internal */ - public function __construct(Swift_CharacterStream $charStream, Swift_StreamFilter $filter = null) - { - $this->_charStream = $charStream; - if (!isset(self::$_safeMapShare[$this->getSafeMapShareId()])) { - $this->initSafeMap(); - self::$_safeMapShare[$this->getSafeMapShareId()] = $this->_safeMap; - } else { - $this->_safeMap = self::$_safeMapShare[$this->getSafeMapShareId()]; - } - $this->_filter = $filter; - } + protected array $safeMap = []; - public function __sleep() + public function __construct() { - return array('_charStream', '_filter'); - } - - public function __wakeup() - { - if (!isset(self::$_safeMapShare[$this->getSafeMapShareId()])) { + $id = static::class; + if (!isset(self::$safeMapShare[$id])) { $this->initSafeMap(); - self::$_safeMapShare[$this->getSafeMapShareId()] = $this->_safeMap; + self::$safeMapShare[$id] = $this->safeMap; } else { - $this->_safeMap = self::$_safeMapShare[$this->getSafeMapShareId()]; + $this->safeMap = self::$safeMapShare[$id]; } } - protected function getSafeMapShareId() + protected function initSafeMap(): void { - return get_class($this); - } - - protected function initSafeMap() - { - foreach (array_merge( - array(0x09, 0x20), range(0x21, 0x3C), range(0x3E, 0x7E)) as $byte) { - $this->_safeMap[$byte] = chr($byte); + foreach (array_merge([0x09, 0x20], range(0x21, 0x3C), range(0x3E, 0x7E)) as $byte) { + $this->safeMap[$byte] = \chr($byte); } } @@ -152,14 +111,8 @@ class Swift_Encoder_QpEncoder implements Swift_Encoder * QP encoded strings have a maximum line length of 76 characters. * If the first line needs to be shorter, indicate the difference with * $firstLineOffset. - * - * @param string $string to encode - * @param int $firstLineOffset, optional - * @param int $maxLineLength, optional 0 indicates the default of 76 chars - * - * @return string */ - public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string { if ($maxLineLength > 76 || $maxLineLength <= 0) { $maxLineLength = 76; @@ -167,40 +120,21 @@ class Swift_Encoder_QpEncoder implements Swift_Encoder $thisLineLength = $maxLineLength - $firstLineOffset; - $lines = array(); + $lines = []; $lNo = 0; $lines[$lNo] = ''; $currentLine = &$lines[$lNo++]; $size = $lineLen = 0; - - $this->_charStream->flushContents(); - $this->_charStream->importString($string); + $charStream = new CharacterStream($string, $charset); // Fetching more than 4 chars at one is slower, as is fetching fewer bytes // Conveniently 4 chars is the UTF-8 safe number since UTF-8 has up to 6 // bytes per char and (6 * 4 * 3 = 72 chars per line) * =NN is 3 bytes - while (false !== $bytes = $this->_nextSequence()) { - // If we're filtering the input - if (isset($this->_filter)) { - // If we can't filter because we need more bytes - while ($this->_filter->shouldBuffer($bytes)) { - // Then collect bytes into the buffer - if (false === $moreBytes = $this->_nextSequence(1)) { - break; - } - - foreach ($moreBytes as $b) { - $bytes[] = $b; - } - } - // And filter them - $bytes = $this->_filter->filter($bytes); - } - - $enc = $this->_encodeByteSequence($bytes, $size); + while (null !== $bytes = $charStream->readBytes(4)) { + $enc = $this->encodeByteSequence($bytes, $size); $i = strpos($enc, '=0D=0A'); - $newLineLength = $lineLen + ($i === false ? $size : $i); + $newLineLength = $lineLen + (false === $i ? $size : $i); if ($currentLine && $newLineLength >= $thisLineLength) { $lines[$lNo] = ''; @@ -211,7 +145,7 @@ class Swift_Encoder_QpEncoder implements Swift_Encoder $currentLine .= $enc; - if ($i === false) { + if (false === $i) { $lineLen += $size; } else { // 6 is the length of '=0D=0A'. @@ -219,37 +153,22 @@ class Swift_Encoder_QpEncoder implements Swift_Encoder } } - return $this->_standardize(implode("=\r\n", $lines)); - } - - /** - * Updates the charset used. - * - * @param string $charset - */ - public function charsetChanged($charset) - { - $this->_charStream->setCharacterSet($charset); + return $this->standardize(implode("=\r\n", $lines)); } /** * Encode the given byte array into a verbatim QP form. - * - * @param integer[] $bytes - * @param int $size - * - * @return string */ - protected function _encodeByteSequence(array $bytes, &$size) + private function encodeByteSequence(array $bytes, int &$size): string { $ret = ''; $size = 0; foreach ($bytes as $b) { - if (isset($this->_safeMap[$b])) { - $ret .= $this->_safeMap[$b]; + if (isset($this->safeMap[$b])) { + $ret .= $this->safeMap[$b]; ++$size; } else { - $ret .= self::$_qpMap[$b]; + $ret .= self::QP_MAP[$b]; $size += 3; } } @@ -257,44 +176,17 @@ class Swift_Encoder_QpEncoder implements Swift_Encoder return $ret; } - /** - * Get the next sequence of bytes to read from the char stream. - * - * @param int $size number of bytes to read - * - * @return integer[] - */ - protected function _nextSequence($size = 4) - { - return $this->_charStream->readBytes($size); - } - /** * Make sure CRLF is correct and HT/SPACE are in valid places. - * - * @param string $string - * - * @return string */ - protected function _standardize($string) + private function standardize(string $string): string { - $string = str_replace(array("\t=0D=0A", ' =0D=0A', '=0D=0A'), - array("=09\r\n", "=20\r\n", "\r\n"), $string - ); - switch ($end = ord(substr($string, -1))) { - case 0x09: - case 0x20: - $string = substr_replace($string, self::$_qpMap[$end], -1); - } + $string = str_replace(["\t=0D=0A", ' =0D=0A', '=0D=0A'], ["=09\r\n", "=20\r\n", "\r\n"], $string); - return $string; - } - - /** - * Make a deep copy of object. - */ - public function __clone() - { - $this->_charStream = clone $this->_charStream; + return match ($end = ($string[-1] ?? '')) { + "\x09", + "\x20" => substr_replace($string, self::QP_MAP[\ord($end)], -1), + default => $string, + }; } } diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Encoder/QpMimeHeaderEncoder.php b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/QpMimeHeaderEncoder.php new file mode 100644 index 0000000..d1d3837 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/QpMimeHeaderEncoder.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Chris Corbyn + */ +final class QpMimeHeaderEncoder extends QpEncoder implements MimeHeaderEncoderInterface +{ + protected function initSafeMap(): void + { + foreach (array_merge( + range(0x61, 0x7A), range(0x41, 0x5A), + range(0x30, 0x39), [0x20, 0x21, 0x2A, 0x2B, 0x2D, 0x2F] + ) as $byte) { + $this->safeMap[$byte] = \chr($byte); + } + } + + public function getName(): string + { + return 'Q'; + } + + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string + { + return str_replace([' ', '=20', "=\r\n"], ['_', '_', "\r\n"], + parent::encodeString($string, $charset, $firstLineOffset, $maxLineLength) + ); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Encoder/Rfc2231Encoder.php b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/Rfc2231Encoder.php new file mode 100644 index 0000000..4d93dc6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Encoder/Rfc2231Encoder.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +use Symfony\Component\Mime\CharacterStream; + +/** + * @author Chris Corbyn + */ +final class Rfc2231Encoder implements EncoderInterface +{ + /** + * Takes an unencoded string and produces a string encoded according to RFC 2231 from it. + */ + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string + { + $lines = []; + $lineCount = 0; + $lines[] = ''; + $currentLine = &$lines[$lineCount++]; + + if (0 >= $maxLineLength) { + $maxLineLength = 75; + } + + $charStream = new CharacterStream($string, $charset); + $thisLineLength = $maxLineLength - $firstLineOffset; + + while (null !== $char = $charStream->read(4)) { + $encodedChar = rawurlencode($char); + if ('' !== $currentLine && \strlen($currentLine.$encodedChar) > $thisLineLength) { + $lines[] = ''; + $currentLine = &$lines[$lineCount++]; + $thisLineLength = $maxLineLength; + } + $currentLine .= $encodedChar; + } + + return implode("\r\n", $lines); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Exception/AddressEncoderException.php b/lib/SymfonyMailer/vendor/symfony/mime/Exception/AddressEncoderException.php new file mode 100644 index 0000000..51ee2e0 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Exception/AddressEncoderException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Exception; + +/** + * @author Fabien Potencier + */ +class AddressEncoderException extends RfcComplianceException +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Exception/ExceptionInterface.php b/lib/SymfonyMailer/vendor/symfony/mime/Exception/ExceptionInterface.php new file mode 100644 index 0000000..1193390 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Exception/ExceptionInterface.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Exception; + +/** + * @author Fabien Potencier + */ +interface ExceptionInterface extends \Throwable +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Exception/InvalidArgumentException.php b/lib/SymfonyMailer/vendor/symfony/mime/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..e89ebae --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Exception/InvalidArgumentException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Exception; + +/** + * @author Fabien Potencier + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Exception/LogicException.php b/lib/SymfonyMailer/vendor/symfony/mime/Exception/LogicException.php new file mode 100644 index 0000000..0508ee7 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Exception/LogicException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Exception; + +/** + * @author Fabien Potencier + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Exception/RfcComplianceException.php b/lib/SymfonyMailer/vendor/symfony/mime/Exception/RfcComplianceException.php new file mode 100644 index 0000000..26e4a50 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Exception/RfcComplianceException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Exception; + +/** + * @author Fabien Potencier + */ +class RfcComplianceException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Exception/RuntimeException.php b/lib/SymfonyMailer/vendor/symfony/mime/Exception/RuntimeException.php new file mode 100644 index 0000000..fb018b0 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Exception/RuntimeException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Exception; + +/** + * @author Fabien Potencier + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/FileBinaryMimeTypeGuesser.php b/lib/SymfonyMailer/vendor/symfony/mime/FileBinaryMimeTypeGuesser.php new file mode 100644 index 0000000..9475954 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/FileBinaryMimeTypeGuesser.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Exception\LogicException; + +/** + * Guesses the MIME type with the binary "file" (only available on *nix). + * + * @author Bernhard Schussek + */ +class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface +{ + /** + * The $cmd pattern must contain a "%s" string that will be replaced + * with the file name to guess. + * + * The command output must start with the MIME type of the file. + * + * @param string $cmd The command to run to get the MIME type of a file + */ + public function __construct( + private string $cmd = 'file -b --mime -- %s 2>/dev/null', + ) { + } + + public function isGuesserSupported(): bool + { + static $supported = null; + + if (null !== $supported) { + return $supported; + } + + if ('\\' === \DIRECTORY_SEPARATOR || !\function_exists('passthru') || !\function_exists('escapeshellarg')) { + return $supported = false; + } + + ob_start(); + passthru('command -v file', $exitStatus); + $binPath = trim(ob_get_clean()); + + return $supported = 0 === $exitStatus && '' !== $binPath; + } + + public function guessMimeType(string $path): ?string + { + if (!is_file($path) || !is_readable($path)) { + throw new InvalidArgumentException(\sprintf('The "%s" file does not exist or is not readable.', $path)); + } + + if (!$this->isGuesserSupported()) { + throw new LogicException(\sprintf('The "%s" guesser is not supported.', __CLASS__)); + } + + ob_start(); + + // need to use --mime instead of -i. see #6641 + passthru(\sprintf($this->cmd, escapeshellarg((str_starts_with($path, '-') ? './' : '').$path)), $return); + if ($return > 0) { + ob_end_clean(); + + return null; + } + + $type = trim(ob_get_clean()); + + if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\+\.]+)#i', $type, $match)) { + // it's not a type, but an error message + return null; + } + + return $match[1]; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/FileinfoMimeTypeGuesser.php b/lib/SymfonyMailer/vendor/symfony/mime/FileinfoMimeTypeGuesser.php new file mode 100644 index 0000000..f0b8ee9 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/FileinfoMimeTypeGuesser.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Exception\LogicException; +use Symfony\Component\Mime\Exception\RuntimeException; + +/** + * Guesses the MIME type using the PECL extension FileInfo. + * + * @author Bernhard Schussek + */ +class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface +{ + /** + * @var array + */ + private static $finfoCache = []; + + /** + * @param string|null $magicFile A magic file to use with the finfo instance + * + * @see https://php.net/finfo-open + */ + public function __construct( + private ?string $magicFile = null, + ) { + } + + public function isGuesserSupported(): bool + { + return \function_exists('finfo_open'); + } + + public function guessMimeType(string $path): ?string + { + if (!is_file($path) || !is_readable($path)) { + throw new InvalidArgumentException(\sprintf('The "%s" file does not exist or is not readable.', $path)); + } + + if (!$this->isGuesserSupported()) { + throw new LogicException(\sprintf('The "%s" guesser is not supported.', __CLASS__)); + } + + try { + $finfo = self::$finfoCache[$this->magicFile ?? ''] ??= new \finfo(\FILEINFO_MIME_TYPE, $this->magicFile); + } catch (\Exception $e) { + throw new RuntimeException($e->getMessage()); + } + $mimeType = $finfo->file($path) ?: null; + + if ($mimeType && 0 === (\strlen($mimeType) % 2)) { + $mimeStart = substr($mimeType, 0, \strlen($mimeType) >> 1); + $mimeType = $mimeStart.$mimeStart === $mimeType ? $mimeStart : $mimeType; + } + + return $mimeType; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Header/AbstractHeader.php b/lib/SymfonyMailer/vendor/symfony/mime/Header/AbstractHeader.php new file mode 100644 index 0000000..556c0aa --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Header/AbstractHeader.php @@ -0,0 +1,294 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Encoder\QpMimeHeaderEncoder; + +/** + * An abstract base MIME Header. + * + * @author Chris Corbyn + */ +abstract class AbstractHeader implements HeaderInterface +{ + public const PHRASE_PATTERN = '(?:(?:(?:(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?[a-zA-Z0-9!#\$%&\'\*\+\-\/=\?\^_`\{\}\|~]+(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?)|(?:(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?"((?:(?:[ \t]*(?:\r\n))?[ \t])?(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21\x23-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])))*(?:(?:[ \t]*(?:\r\n))?[ \t])?"(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?))+?)'; + + private static QpMimeHeaderEncoder $encoder; + + private string $name; + private int $lineLength = 76; + private ?string $lang = null; + private string $charset = 'utf-8'; + + public function __construct(string $name) + { + $this->name = $name; + } + + public function setCharset(string $charset): void + { + $this->charset = $charset; + } + + public function getCharset(): ?string + { + return $this->charset; + } + + /** + * Set the language used in this Header. + * + * For example, for US English, 'en-us'. + */ + public function setLanguage(string $lang): void + { + $this->lang = $lang; + } + + public function getLanguage(): ?string + { + return $this->lang; + } + + public function getName(): string + { + return $this->name; + } + + public function setMaxLineLength(int $lineLength): void + { + $this->lineLength = $lineLength; + } + + public function getMaxLineLength(): int + { + return $this->lineLength; + } + + public function toString(): string + { + return $this->tokensToString($this->toTokens()); + } + + /** + * Produces a compliant, formatted RFC 2822 'phrase' based on the string given. + * + * @param string $string as displayed + * @param bool $shorten the first line to make remove for header name + */ + protected function createPhrase(HeaderInterface $header, string $string, string $charset, bool $shorten = false): string + { + // Treat token as exactly what was given + $phraseStr = $string; + + // If it's not valid + if (!preg_match('/^'.self::PHRASE_PATTERN.'$/D', $phraseStr)) { + // .. but it is just ascii text, try escaping some characters + // and make it a quoted-string + if (preg_match('/^[\x00-\x08\x0B\x0C\x0E-\x7F]*$/D', $phraseStr)) { + foreach (['\\', '"'] as $char) { + $phraseStr = str_replace($char, '\\'.$char, $phraseStr); + } + $phraseStr = '"'.$phraseStr.'"'; + } else { + // ... otherwise it needs encoding + // Determine space remaining on line if first line + if ($shorten) { + $usedLength = \strlen($header->getName().': '); + } else { + $usedLength = 0; + } + $phraseStr = $this->encodeWords($header, $string, $usedLength); + } + } elseif (str_contains($phraseStr, '(')) { + foreach (['\\', '"'] as $char) { + $phraseStr = str_replace($char, '\\'.$char, $phraseStr); + } + $phraseStr = '"'.$phraseStr.'"'; + } + + return $phraseStr; + } + + /** + * Encode needed word tokens within a string of input. + */ + protected function encodeWords(HeaderInterface $header, string $input, int $usedLength = -1): string + { + $value = ''; + $tokens = $this->getEncodableWordTokens($input); + foreach ($tokens as $token) { + // See RFC 2822, Sect 2.2 (really 2.2 ??) + if ($this->tokenNeedsEncoding($token)) { + // Don't encode starting WSP + $firstChar = substr($token, 0, 1); + switch ($firstChar) { + case ' ': + case "\t": + $value .= $firstChar; + $token = substr($token, 1); + } + + if (-1 == $usedLength) { + $usedLength = \strlen($header->getName().': ') + \strlen($value); + } + $value .= $this->getTokenAsEncodedWord($token, $usedLength); + } else { + $value .= $token; + } + } + + return $value; + } + + protected function tokenNeedsEncoding(string $token): bool + { + return (bool) preg_match('~[\x00-\x08\x10-\x19\x7F-\xFF\r\n]~', $token); + } + + /** + * Splits a string into tokens in blocks of words which can be encoded quickly. + * + * @return string[] + */ + protected function getEncodableWordTokens(string $string): array + { + $tokens = []; + $encodedToken = ''; + // Split at all whitespace boundaries + foreach (preg_split('~(?=[\t ])~', $string) as $token) { + if ($this->tokenNeedsEncoding($token)) { + $encodedToken .= $token; + } else { + if ('' !== $encodedToken) { + $tokens[] = $encodedToken; + $encodedToken = ''; + } + $tokens[] = $token; + } + } + if ('' !== $encodedToken) { + $tokens[] = $encodedToken; + } + + foreach ($tokens as $i => $token) { + // whitespace(s) between 2 encoded tokens + if ( + 0 < $i + && isset($tokens[$i + 1]) + && preg_match('~^[\t ]+$~', $token) + && $this->tokenNeedsEncoding($tokens[$i - 1]) + && $this->tokenNeedsEncoding($tokens[$i + 1]) + ) { + $tokens[$i - 1] .= $token.$tokens[$i + 1]; + array_splice($tokens, $i, 2); + } + } + + return $tokens; + } + + /** + * Get a token as an encoded word for safe insertion into headers. + */ + protected function getTokenAsEncodedWord(string $token, int $firstLineOffset = 0): string + { + self::$encoder ??= new QpMimeHeaderEncoder(); + + // Adjust $firstLineOffset to account for space needed for syntax + $charsetDecl = $this->charset; + if (null !== $this->lang) { + $charsetDecl .= '*'.$this->lang; + } + $encodingWrapperLength = \strlen('=?'.$charsetDecl.'?'.self::$encoder->getName().'??='); + + if ($firstLineOffset >= 75) { + // Does this logic need to be here? + $firstLineOffset = 0; + } + + $encodedTextLines = explode("\r\n", + self::$encoder->encodeString($token, $this->charset, $firstLineOffset, 75 - $encodingWrapperLength) + ); + + if ('iso-2022-jp' !== strtolower($this->charset)) { + // special encoding for iso-2022-jp using mb_encode_mimeheader + foreach ($encodedTextLines as $lineNum => $line) { + $encodedTextLines[$lineNum] = '=?'.$charsetDecl.'?'.self::$encoder->getName().'?'.$line.'?='; + } + } + + return implode("\r\n ", $encodedTextLines); + } + + /** + * Generates tokens from the given string which include CRLF as individual tokens. + * + * @return string[] + */ + protected function generateTokenLines(string $token): array + { + return preg_split('~(\r\n)~', $token, -1, \PREG_SPLIT_DELIM_CAPTURE); + } + + /** + * Generate a list of all tokens in the final header. + */ + protected function toTokens(?string $string = null): array + { + $string ??= $this->getBodyAsString(); + + $tokens = []; + // Generate atoms; split at all invisible boundaries followed by WSP + foreach (preg_split('~(?=[ \t])~', $string) as $token) { + $newTokens = $this->generateTokenLines($token); + foreach ($newTokens as $newToken) { + $tokens[] = $newToken; + } + } + + return $tokens; + } + + /** + * Takes an array of tokens which appear in the header and turns them into + * an RFC 2822 compliant string, adding FWSP where needed. + * + * @param string[] $tokens + */ + private function tokensToString(array $tokens): string + { + $lineCount = 0; + $headerLines = []; + $headerLines[] = $this->name.': '; + $currentLine = &$headerLines[$lineCount++]; + + // Build all tokens back into compliant header + foreach ($tokens as $i => $token) { + // Line longer than specified maximum or token was just a new line + if (("\r\n" === $token) + || ($i > 0 && \strlen($currentLine.$token) > $this->lineLength) + && '' !== $currentLine) { + $headerLines[] = ''; + $currentLine = &$headerLines[$lineCount++]; + } + + // Append token to the line + if ("\r\n" !== $token) { + $currentLine .= $token; + } + } + + // Implode with FWS (RFC 2822, 2.2.3) + return implode("\r\n", $headerLines); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Header/DateHeader.php b/lib/SymfonyMailer/vendor/symfony/mime/Header/DateHeader.php new file mode 100644 index 0000000..2b36180 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Header/DateHeader.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +/** + * A Date MIME Header. + * + * @author Chris Corbyn + */ +final class DateHeader extends AbstractHeader +{ + private \DateTimeImmutable $dateTime; + + public function __construct(string $name, \DateTimeInterface $date) + { + parent::__construct($name); + + $this->setDateTime($date); + } + + /** + * @param \DateTimeInterface $body + */ + public function setBody(mixed $body): void + { + $this->setDateTime($body); + } + + public function getBody(): \DateTimeImmutable + { + return $this->getDateTime(); + } + + public function getDateTime(): \DateTimeImmutable + { + return $this->dateTime; + } + + /** + * Set the date-time of the Date in this Header. + * + * If a DateTime instance is provided, it is converted to DateTimeImmutable. + */ + public function setDateTime(\DateTimeInterface $dateTime): void + { + $this->dateTime = \DateTimeImmutable::createFromInterface($dateTime); + } + + public function getBodyAsString(): string + { + return $this->dateTime->format(\DateTimeInterface::RFC2822); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Header/HeaderInterface.php b/lib/SymfonyMailer/vendor/symfony/mime/Header/HeaderInterface.php new file mode 100644 index 0000000..6bb1d5d --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Header/HeaderInterface.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +/** + * A MIME Header. + * + * @author Chris Corbyn + */ +interface HeaderInterface +{ + /** + * Sets the body. + * + * The type depends on the Header concrete class. + */ + public function setBody(mixed $body): void; + + /** + * Gets the body. + * + * The return type depends on the Header concrete class. + */ + public function getBody(): mixed; + + public function setCharset(string $charset): void; + + public function getCharset(): ?string; + + public function setLanguage(string $lang): void; + + public function getLanguage(): ?string; + + public function getName(): string; + + public function setMaxLineLength(int $lineLength): void; + + public function getMaxLineLength(): int; + + /** + * Gets this Header rendered as a compliant string. + */ + public function toString(): string; + + /** + * Gets the header's body, prepared for folding into a final header value. + * + * This is not necessarily RFC 2822 compliant since folding white space is + * not added at this stage (see {@link toString()} for that). + */ + public function getBodyAsString(): string; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Header/Headers.php b/lib/SymfonyMailer/vendor/symfony/mime/Header/Headers.php new file mode 100644 index 0000000..789d15d --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Header/Headers.php @@ -0,0 +1,316 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Exception\LogicException; + +/** + * A collection of headers. + * + * @author Fabien Potencier + */ +final class Headers +{ + private const UNIQUE_HEADERS = [ + 'date', 'from', 'sender', 'reply-to', 'to', 'cc', 'bcc', + 'message-id', 'in-reply-to', 'references', 'subject', + ]; + private const HEADER_CLASS_MAP = [ + 'date' => DateHeader::class, + 'from' => MailboxListHeader::class, + 'sender' => MailboxHeader::class, + 'reply-to' => MailboxListHeader::class, + 'to' => MailboxListHeader::class, + 'cc' => MailboxListHeader::class, + 'bcc' => MailboxListHeader::class, + 'message-id' => IdentificationHeader::class, + 'in-reply-to' => [UnstructuredHeader::class, IdentificationHeader::class], // `In-Reply-To` and `References` are less strict than RFC 2822 (3.6.4) to allow users entering the original email's ... + 'references' => [UnstructuredHeader::class, IdentificationHeader::class], // ... `Message-ID`, even if that is no valid `msg-id` + 'return-path' => PathHeader::class, + ]; + + /** + * @var HeaderInterface[][] + */ + private array $headers = []; + private int $lineLength = 76; + + public function __construct(HeaderInterface ...$headers) + { + foreach ($headers as $header) { + $this->add($header); + } + } + + public function __clone() + { + foreach ($this->headers as $name => $collection) { + foreach ($collection as $i => $header) { + $this->headers[$name][$i] = clone $header; + } + } + } + + public function setMaxLineLength(int $lineLength): void + { + $this->lineLength = $lineLength; + foreach ($this->all() as $header) { + $header->setMaxLineLength($lineLength); + } + } + + public function getMaxLineLength(): int + { + return $this->lineLength; + } + + /** + * @param array $addresses + * + * @return $this + */ + public function addMailboxListHeader(string $name, array $addresses): static + { + return $this->add(new MailboxListHeader($name, Address::createArray($addresses))); + } + + /** + * @return $this + */ + public function addMailboxHeader(string $name, Address|string $address): static + { + return $this->add(new MailboxHeader($name, Address::create($address))); + } + + /** + * @return $this + */ + public function addIdHeader(string $name, string|array $ids): static + { + return $this->add(new IdentificationHeader($name, $ids)); + } + + /** + * @return $this + */ + public function addPathHeader(string $name, Address|string $path): static + { + return $this->add(new PathHeader($name, $path instanceof Address ? $path : new Address($path))); + } + + /** + * @return $this + */ + public function addDateHeader(string $name, \DateTimeInterface $dateTime): static + { + return $this->add(new DateHeader($name, $dateTime)); + } + + /** + * @return $this + */ + public function addTextHeader(string $name, string $value): static + { + return $this->add(new UnstructuredHeader($name, $value)); + } + + /** + * @return $this + */ + public function addParameterizedHeader(string $name, string $value, array $params = []): static + { + return $this->add(new ParameterizedHeader($name, $value, $params)); + } + + /** + * @return $this + */ + public function addHeader(string $name, mixed $argument, array $more = []): static + { + $headerClass = self::HEADER_CLASS_MAP[strtolower($name)] ?? UnstructuredHeader::class; + if (\is_array($headerClass)) { + $headerClass = $headerClass[0]; + } + $parts = explode('\\', $headerClass); + $method = 'add'.ucfirst(array_pop($parts)); + if ('addUnstructuredHeader' === $method) { + $method = 'addTextHeader'; + } elseif ('addIdentificationHeader' === $method) { + $method = 'addIdHeader'; + } elseif ('addMailboxListHeader' === $method && !\is_array($argument)) { + $argument = [$argument]; + } + + return $this->$method($name, $argument, $more); + } + + public function has(string $name): bool + { + return isset($this->headers[strtolower($name)]); + } + + /** + * @return $this + */ + public function add(HeaderInterface $header): static + { + self::checkHeaderClass($header); + + $header->setMaxLineLength($this->lineLength); + $name = strtolower($header->getName()); + + if (\in_array($name, self::UNIQUE_HEADERS, true) && isset($this->headers[$name]) && \count($this->headers[$name]) > 0) { + throw new LogicException(\sprintf('Impossible to set header "%s" as it\'s already defined and must be unique.', $header->getName())); + } + + $this->headers[$name][] = $header; + + return $this; + } + + public function get(string $name): ?HeaderInterface + { + $name = strtolower($name); + if (!isset($this->headers[$name])) { + return null; + } + + $values = array_values($this->headers[$name]); + + return array_shift($values); + } + + public function all(?string $name = null): iterable + { + if (null === $name) { + foreach ($this->headers as $name => $collection) { + foreach ($collection as $header) { + yield $name => $header; + } + } + } elseif (isset($this->headers[strtolower($name)])) { + foreach ($this->headers[strtolower($name)] as $header) { + yield $header; + } + } + } + + public function getNames(): array + { + return array_keys($this->headers); + } + + public function remove(string $name): void + { + unset($this->headers[strtolower($name)]); + } + + public static function isUniqueHeader(string $name): bool + { + return \in_array(strtolower($name), self::UNIQUE_HEADERS, true); + } + + /** + * @throws LogicException if the header name and class are not compatible + */ + public static function checkHeaderClass(HeaderInterface $header): void + { + $name = strtolower($header->getName()); + $headerClasses = self::HEADER_CLASS_MAP[$name] ?? []; + if (!\is_array($headerClasses)) { + $headerClasses = [$headerClasses]; + } + + if (!$headerClasses) { + return; + } + + foreach ($headerClasses as $c) { + if ($header instanceof $c) { + return; + } + } + + throw new LogicException(\sprintf('The "%s" header must be an instance of "%s" (got "%s").', $header->getName(), implode('" or "', $headerClasses), get_debug_type($header))); + } + + public function toString(): string + { + $string = ''; + foreach ($this->toArray() as $str) { + $string .= $str."\r\n"; + } + + return $string; + } + + public function toArray(): array + { + $arr = []; + foreach ($this->all() as $header) { + if ('' !== $header->getBodyAsString()) { + $arr[] = $header->toString(); + } + } + + return $arr; + } + + public function getHeaderBody(string $name): mixed + { + return $this->has($name) ? $this->get($name)->getBody() : null; + } + + /** + * @internal + */ + public function setHeaderBody(string $type, string $name, mixed $body): void + { + if ($this->has($name)) { + $this->get($name)->setBody($body); + } else { + $this->{'add'.$type.'Header'}($name, $body); + } + } + + public function getHeaderParameter(string $name, string $parameter): ?string + { + if (!$this->has($name)) { + return null; + } + + $header = $this->get($name); + if (!$header instanceof ParameterizedHeader) { + throw new LogicException(\sprintf('Unable to get parameter "%s" on header "%s" as the header is not of class "%s".', $parameter, $name, ParameterizedHeader::class)); + } + + return $header->getParameter($parameter); + } + + /** + * @internal + */ + public function setHeaderParameter(string $name, string $parameter, ?string $value): void + { + if (!$this->has($name)) { + throw new LogicException(\sprintf('Unable to set parameter "%s" on header "%s" as the header is not defined.', $parameter, $name)); + } + + $header = $this->get($name); + if (!$header instanceof ParameterizedHeader) { + throw new LogicException(\sprintf('Unable to set parameter "%s" on header "%s" as the header is not of class "%s".', $parameter, $name, ParameterizedHeader::class)); + } + + $header->setParameter($parameter, $value); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Header/IdentificationHeader.php b/lib/SymfonyMailer/vendor/symfony/mime/Header/IdentificationHeader.php new file mode 100644 index 0000000..14e18bf --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Header/IdentificationHeader.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Exception\RfcComplianceException; + +/** + * An ID MIME Header for something like Message-ID or Content-ID (one or more addresses). + * + * @author Chris Corbyn + */ +final class IdentificationHeader extends AbstractHeader +{ + private array $ids = []; + private array $idsAsAddresses = []; + + public function __construct(string $name, string|array $ids) + { + parent::__construct($name); + + $this->setId($ids); + } + + /** + * @param string|string[] $body a string ID or an array of IDs + * + * @throws RfcComplianceException + */ + public function setBody(mixed $body): void + { + $this->setId($body); + } + + public function getBody(): array + { + return $this->getIds(); + } + + /** + * Set the ID used in the value of this header. + * + * @param string|string[] $id + * + * @throws RfcComplianceException + */ + public function setId(string|array $id): void + { + $this->setIds(\is_array($id) ? $id : [$id]); + } + + /** + * Get the ID used in the value of this Header. + * + * If multiple IDs are set only the first is returned. + */ + public function getId(): ?string + { + return $this->ids[0] ?? null; + } + + /** + * Set a collection of IDs to use in the value of this Header. + * + * @param string[] $ids + * + * @throws RfcComplianceException + */ + public function setIds(array $ids): void + { + $this->ids = []; + $this->idsAsAddresses = []; + foreach ($ids as $id) { + $this->idsAsAddresses[] = new Address($id); + $this->ids[] = $id; + } + } + + /** + * Get the list of IDs used in this Header. + * + * @return string[] + */ + public function getIds(): array + { + return $this->ids; + } + + public function getBodyAsString(): string + { + $addrs = []; + foreach ($this->idsAsAddresses as $address) { + $addrs[] = '<'.$address->toString().'>'; + } + + return implode(' ', $addrs); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Header/MailboxHeader.php b/lib/SymfonyMailer/vendor/symfony/mime/Header/MailboxHeader.php new file mode 100644 index 0000000..8ba964b --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Header/MailboxHeader.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Exception\RfcComplianceException; + +/** + * A Mailbox MIME Header for something like Sender (one named address). + * + * @author Fabien Potencier + */ +final class MailboxHeader extends AbstractHeader +{ + private Address $address; + + public function __construct(string $name, Address $address) + { + parent::__construct($name); + + $this->setAddress($address); + } + + /** + * @param Address $body + * + * @throws RfcComplianceException + */ + public function setBody(mixed $body): void + { + $this->setAddress($body); + } + + /** + * @throws RfcComplianceException + */ + public function getBody(): Address + { + return $this->getAddress(); + } + + /** + * @throws RfcComplianceException + */ + public function setAddress(Address $address): void + { + $this->address = $address; + } + + public function getAddress(): Address + { + return $this->address; + } + + public function getBodyAsString(): string + { + $str = $this->address->getEncodedAddress(); + if ($name = $this->address->getName()) { + $str = $this->createPhrase($this, $name, $this->getCharset(), true).' <'.$str.'>'; + } + + return $str; + } + + /** + * Redefine the encoding requirements for an address. + * + * All "specials" must be encoded as the full header value will not be quoted + * + * @see RFC 2822 3.2.1 + */ + protected function tokenNeedsEncoding(string $token): bool + { + return preg_match('/[()<>\[\]:;@\,."]/', $token) || parent::tokenNeedsEncoding($token); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Header/MailboxListHeader.php b/lib/SymfonyMailer/vendor/symfony/mime/Header/MailboxListHeader.php new file mode 100644 index 0000000..8d902fb --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Header/MailboxListHeader.php @@ -0,0 +1,136 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Exception\RfcComplianceException; + +/** + * A Mailbox list MIME Header for something like From, To, Cc, and Bcc (one or more named addresses). + * + * @author Chris Corbyn + */ +final class MailboxListHeader extends AbstractHeader +{ + private array $addresses = []; + + /** + * @param Address[] $addresses + */ + public function __construct(string $name, array $addresses) + { + parent::__construct($name); + + $this->setAddresses($addresses); + } + + /** + * @param Address[] $body + * + * @throws RfcComplianceException + */ + public function setBody(mixed $body): void + { + $this->setAddresses($body); + } + + /** + * @return Address[] + * + * @throws RfcComplianceException + */ + public function getBody(): array + { + return $this->getAddresses(); + } + + /** + * Sets a list of addresses to be shown in this Header. + * + * @param Address[] $addresses + * + * @throws RfcComplianceException + */ + public function setAddresses(array $addresses): void + { + $this->addresses = []; + $this->addAddresses($addresses); + } + + /** + * Sets a list of addresses to be shown in this Header. + * + * @param Address[] $addresses + * + * @throws RfcComplianceException + */ + public function addAddresses(array $addresses): void + { + foreach ($addresses as $address) { + $this->addAddress($address); + } + } + + /** + * @throws RfcComplianceException + */ + public function addAddress(Address $address): void + { + $this->addresses[] = $address; + } + + /** + * @return Address[] + */ + public function getAddresses(): array + { + return $this->addresses; + } + + /** + * Gets the full mailbox list of this Header as an array of valid RFC 2822 strings. + * + * @return string[] + * + * @throws RfcComplianceException + */ + public function getAddressStrings(): array + { + $strings = []; + foreach ($this->addresses as $address) { + $str = $address->getEncodedAddress(); + if ($name = $address->getName()) { + $str = $this->createPhrase($this, $name, $this->getCharset(), !$strings).' <'.$str.'>'; + } + $strings[] = $str; + } + + return $strings; + } + + public function getBodyAsString(): string + { + return implode(', ', $this->getAddressStrings()); + } + + /** + * Redefine the encoding requirements for addresses. + * + * All "specials" must be encoded as the full header value will not be quoted + * + * @see RFC 2822 3.2.1 + */ + protected function tokenNeedsEncoding(string $token): bool + { + return preg_match('/[()<>\[\]:;@\,."]/', $token) || parent::tokenNeedsEncoding($token); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Header/ParameterizedHeader.php b/lib/SymfonyMailer/vendor/symfony/mime/Header/ParameterizedHeader.php new file mode 100644 index 0000000..585eced --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Header/ParameterizedHeader.php @@ -0,0 +1,191 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Encoder\Rfc2231Encoder; + +/** + * @author Chris Corbyn + */ +final class ParameterizedHeader extends UnstructuredHeader +{ + /** + * RFC 2231's definition of a token. + * + * @var string + */ + public const TOKEN_REGEX = '(?:[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+)'; + + private ?Rfc2231Encoder $encoder = null; + private array $parameters = []; + + public function __construct(string $name, string $value, array $parameters = []) + { + parent::__construct($name, $value); + + foreach ($parameters as $k => $v) { + $this->setParameter($k, $v); + } + + if ('content-type' !== strtolower($name)) { + $this->encoder = new Rfc2231Encoder(); + } + } + + public function setParameter(string $parameter, ?string $value): void + { + $this->setParameters(array_merge($this->getParameters(), [$parameter => $value])); + } + + public function getParameter(string $parameter): string + { + return $this->getParameters()[$parameter] ?? ''; + } + + /** + * @param string[] $parameters + */ + public function setParameters(array $parameters): void + { + $this->parameters = $parameters; + } + + /** + * @return string[] + */ + public function getParameters(): array + { + return $this->parameters; + } + + public function getBodyAsString(): string + { + $body = parent::getBodyAsString(); + foreach ($this->parameters as $name => $value) { + if (null !== $value) { + $body .= '; '.$this->createParameter($name, $value); + } + } + + return $body; + } + + /** + * Generate a list of all tokens in the final header. + * + * This doesn't need to be overridden in theory, but it is for implementation + * reasons to prevent potential breakage of attributes. + */ + protected function toTokens(?string $string = null): array + { + $tokens = parent::toTokens(parent::getBodyAsString()); + + // Try creating any parameters + foreach ($this->parameters as $name => $value) { + if (null !== $value) { + // Add the semi-colon separator + $tokens[\count($tokens) - 1] .= ';'; + $tokens = array_merge($tokens, $this->generateTokenLines(' '.$this->createParameter($name, $value))); + } + } + + return $tokens; + } + + /** + * Render an RFC 2047 compliant header parameter from the $name and $value. + */ + private function createParameter(string $name, string $value): string + { + $origValue = $value; + + $encoded = false; + // Allow room for parameter name, indices, "=" and DQUOTEs + $maxValueLength = $this->getMaxLineLength() - \strlen($name.'=*N"";') - 1; + $firstLineOffset = 0; + + // If it's not already a valid parameter value... + if (!preg_match('/^'.self::TOKEN_REGEX.'$/D', $value)) { + // TODO: text, or something else?? + // ... and it's not ascii + if (!preg_match('/^[\x00-\x08\x0B\x0C\x0E-\x7F]*$/D', $value)) { + $encoded = true; + // Allow space for the indices, charset and language + $maxValueLength = $this->getMaxLineLength() - \strlen($name.'*N*="";') - 1; + $firstLineOffset = \strlen($this->getCharset()."'".$this->getLanguage()."'"); + } + + if (\in_array($name, ['name', 'filename'], true) && 'form-data' === $this->getValue() && 'content-disposition' === strtolower($this->getName()) && preg_match('//u', $value)) { + // WHATWG HTML living standard 4.10.21.8 2 specifies: + // For field names and filenames for file fields, the result of the + // encoding in the previous bullet point must be escaped by replacing + // any 0x0A (LF) bytes with the byte sequence `%0A`, 0x0D (CR) with `%0D` + // and 0x22 (") with `%22`. + // The user agent must not perform any other escapes. + $value = str_replace(['"', "\r", "\n"], ['%22', '%0D', '%0A'], $value); + + if (\strlen($value) <= $maxValueLength) { + return $name.'="'.$value.'"'; + } + + $value = $origValue; + } + } + + // Encode if we need to + if ($encoded || \strlen($value) > $maxValueLength) { + if (null !== $this->encoder) { + $value = $this->encoder->encodeString($origValue, $this->getCharset(), $firstLineOffset, $maxValueLength); + } else { + // We have to go against RFC 2183/2231 in some areas for interoperability + $value = $this->getTokenAsEncodedWord($origValue); + $encoded = false; + } + } + + $valueLines = $this->encoder ? explode("\r\n", $value) : [$value]; + + // Need to add indices + if (\count($valueLines) > 1) { + $paramLines = []; + foreach ($valueLines as $i => $line) { + $paramLines[] = $name.'*'.$i.$this->getEndOfParameterValue($line, true, 0 === $i); + } + + return implode(";\r\n ", $paramLines); + } + + return $name.$this->getEndOfParameterValue($valueLines[0], $encoded, true); + } + + /** + * Returns the parameter value from the "=" and beyond. + * + * @param string $value to append + */ + private function getEndOfParameterValue(string $value, bool $encoded = false, bool $firstLine = false): string + { + $forceHttpQuoting = 'form-data' === $this->getValue() && 'content-disposition' === strtolower($this->getName()); + if ($forceHttpQuoting || !preg_match('/^'.self::TOKEN_REGEX.'$/D', $value)) { + $value = '"'.$value.'"'; + } + $prepend = '='; + if ($encoded) { + $prepend = '*='; + if ($firstLine) { + $prepend = '*='.$this->getCharset()."'".$this->getLanguage()."'"; + } + } + + return $prepend.$value; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Header/PathHeader.php b/lib/SymfonyMailer/vendor/symfony/mime/Header/PathHeader.php new file mode 100644 index 0000000..4b0b7d3 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Header/PathHeader.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Exception\RfcComplianceException; + +/** + * A Path Header, such a Return-Path (one address). + * + * @author Chris Corbyn + */ +final class PathHeader extends AbstractHeader +{ + private Address $address; + + public function __construct(string $name, Address $address) + { + parent::__construct($name); + + $this->setAddress($address); + } + + /** + * @param Address $body + * + * @throws RfcComplianceException + */ + public function setBody(mixed $body): void + { + $this->setAddress($body); + } + + public function getBody(): Address + { + return $this->getAddress(); + } + + public function setAddress(Address $address): void + { + $this->address = $address; + } + + public function getAddress(): Address + { + return $this->address; + } + + public function getBodyAsString(): string + { + return '<'.$this->address->getEncodedAddress().'>'; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Header/UnstructuredHeader.php b/lib/SymfonyMailer/vendor/symfony/mime/Header/UnstructuredHeader.php new file mode 100644 index 0000000..88ed466 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Header/UnstructuredHeader.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +/** + * A Simple MIME Header. + * + * @author Chris Corbyn + */ +class UnstructuredHeader extends AbstractHeader +{ + private string $value; + + public function __construct(string $name, string $value) + { + parent::__construct($name); + + $this->setValue($value); + } + + /** + * @param string $body + */ + public function setBody(mixed $body): void + { + $this->setValue($body); + } + + public function getBody(): string + { + return $this->getValue(); + } + + /** + * Get the (unencoded) value of this header. + */ + public function getValue(): string + { + return $this->value; + } + + /** + * Set the (unencoded) value of this header. + */ + public function setValue(string $value): void + { + $this->value = $value; + } + + /** + * Get the value of this header prepared for rendering. + */ + public function getBodyAsString(): string + { + return $this->encodeWords($this, $this->value); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/HtmlToTextConverter/DefaultHtmlToTextConverter.php b/lib/SymfonyMailer/vendor/symfony/mime/HtmlToTextConverter/DefaultHtmlToTextConverter.php new file mode 100644 index 0000000..2aaf8e6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/HtmlToTextConverter/DefaultHtmlToTextConverter.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\HtmlToTextConverter; + +/** + * @author Fabien Potencier + */ +class DefaultHtmlToTextConverter implements HtmlToTextConverterInterface +{ + public function convert(string $html, string $charset): string + { + return strip_tags(preg_replace('{<(head|style)\b.*?}is', '', $html)); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/HtmlToTextConverter/HtmlToTextConverterInterface.php b/lib/SymfonyMailer/vendor/symfony/mime/HtmlToTextConverter/HtmlToTextConverterInterface.php new file mode 100644 index 0000000..696f37c --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/HtmlToTextConverter/HtmlToTextConverterInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\HtmlToTextConverter; + +/** + * @author Fabien Potencier + */ +interface HtmlToTextConverterInterface +{ + /** + * Converts an HTML representation of a Message to a text representation. + * + * The output must use the same charset as the HTML one. + */ + public function convert(string $html, string $charset): string; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/HtmlToTextConverter/LeagueHtmlToMarkdownConverter.php b/lib/SymfonyMailer/vendor/symfony/mime/HtmlToTextConverter/LeagueHtmlToMarkdownConverter.php new file mode 100644 index 0000000..253a7b1 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/HtmlToTextConverter/LeagueHtmlToMarkdownConverter.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\HtmlToTextConverter; + +use League\HTMLToMarkdown\HtmlConverter; +use League\HTMLToMarkdown\HtmlConverterInterface; + +/** + * @author Fabien Potencier + */ +class LeagueHtmlToMarkdownConverter implements HtmlToTextConverterInterface +{ + public function __construct( + private HtmlConverterInterface $converter = new HtmlConverter([ + 'hard_break' => true, + 'strip_tags' => true, + 'remove_nodes' => 'head style', + ]), + ) { + } + + public function convert(string $html, string $charset): string + { + return $this->converter->convert($html); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/LICENSE b/lib/SymfonyMailer/vendor/symfony/mime/LICENSE new file mode 100644 index 0000000..4dd83ce --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Message.php b/lib/SymfonyMailer/vendor/symfony/mime/Message.php new file mode 100644 index 0000000..0374ae7 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Message.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\LogicException; +use Symfony\Component\Mime\Header\Headers; +use Symfony\Component\Mime\Part\AbstractPart; +use Symfony\Component\Mime\Part\TextPart; + +/** + * @author Fabien Potencier + */ +class Message extends RawMessage +{ + private Headers $headers; + + public function __construct( + ?Headers $headers = null, + private ?AbstractPart $body = null, + ) { + $this->headers = $headers ? clone $headers : new Headers(); + } + + public function __clone() + { + $this->headers = clone $this->headers; + + if (null !== $this->body) { + $this->body = clone $this->body; + } + } + + /** + * @return $this + */ + public function setBody(?AbstractPart $body): static + { + $this->body = $body; + + return $this; + } + + public function getBody(): ?AbstractPart + { + return $this->body; + } + + /** + * @return $this + */ + public function setHeaders(Headers $headers): static + { + $this->headers = $headers; + + return $this; + } + + public function getHeaders(): Headers + { + return $this->headers; + } + + public function getPreparedHeaders(): Headers + { + $headers = clone $this->headers; + + if (!$headers->has('From')) { + if (!$headers->has('Sender')) { + throw new LogicException('An email must have a "From" or a "Sender" header.'); + } + $headers->addMailboxListHeader('From', [$headers->get('Sender')->getAddress()]); + } + + if (!$headers->has('MIME-Version')) { + $headers->addTextHeader('MIME-Version', '1.0'); + } + + if (!$headers->has('Date')) { + $headers->addDateHeader('Date', new \DateTimeImmutable()); + } + + // determine the "real" sender + if (!$headers->has('Sender') && \count($froms = $headers->get('From')->getAddresses()) > 1) { + $headers->addMailboxHeader('Sender', $froms[0]); + } + + if (!$headers->has('Message-ID')) { + $headers->addIdHeader('Message-ID', $this->generateMessageId()); + } + + // remove the Bcc field which should NOT be part of the sent message + $headers->remove('Bcc'); + + return $headers; + } + + public function toString(): string + { + if (null === $body = $this->getBody()) { + $body = new TextPart(''); + } + + return $this->getPreparedHeaders()->toString().$body->toString(); + } + + public function toIterable(): iterable + { + if (null === $body = $this->getBody()) { + $body = new TextPart(''); + } + + yield $this->getPreparedHeaders()->toString(); + yield from $body->toIterable(); + } + + public function ensureValidity(): void + { + if (!$this->headers->get('To')?->getBody() && !$this->headers->get('Cc')?->getBody() && !$this->headers->get('Bcc')?->getBody()) { + throw new LogicException('An email must have a "To", "Cc", or "Bcc" header.'); + } + + if (!$this->headers->get('From')?->getBody() && !$this->headers->get('Sender')?->getBody()) { + throw new LogicException('An email must have a "From" or a "Sender" header.'); + } + + parent::ensureValidity(); + } + + public function generateMessageId(): string + { + if ($this->headers->has('Sender')) { + $sender = $this->headers->get('Sender')->getAddress(); + } elseif ($this->headers->has('From')) { + if (!$froms = $this->headers->get('From')->getAddresses()) { + throw new LogicException('A "From" header must have at least one email address.'); + } + $sender = $froms[0]; + } else { + throw new LogicException('An email must have a "From" or a "Sender" header.'); + } + + return bin2hex(random_bytes(16)).strstr($sender->getAddress(), '@'); + } + + public function __serialize(): array + { + return [$this->headers, $this->body]; + } + + public function __unserialize(array $data): void + { + [$this->headers, $this->body] = $data; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/MessageConverter.php b/lib/SymfonyMailer/vendor/symfony/mime/MessageConverter.php new file mode 100644 index 0000000..a07dd87 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/MessageConverter.php @@ -0,0 +1,122 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\RuntimeException; +use Symfony\Component\Mime\Part\DataPart; +use Symfony\Component\Mime\Part\Multipart\AlternativePart; +use Symfony\Component\Mime\Part\Multipart\MixedPart; +use Symfony\Component\Mime\Part\Multipart\RelatedPart; +use Symfony\Component\Mime\Part\TextPart; + +/** + * @author Fabien Potencier + */ +final class MessageConverter +{ + /** + * @throws RuntimeException when unable to convert the message to an email + */ + public static function toEmail(Message $message): Email + { + if ($message instanceof Email) { + return $message; + } + + // try to convert to a "simple" Email instance + $body = $message->getBody(); + if ($body instanceof TextPart) { + return self::createEmailFromTextPart($message, $body); + } + + if ($body instanceof AlternativePart) { + return self::createEmailFromAlternativePart($message, $body); + } + + if ($body instanceof RelatedPart) { + return self::createEmailFromRelatedPart($message, $body); + } + + if ($body instanceof MixedPart) { + $parts = $body->getParts(); + if ($parts[0] instanceof RelatedPart) { + $email = self::createEmailFromRelatedPart($message, $parts[0]); + } elseif ($parts[0] instanceof AlternativePart) { + $email = self::createEmailFromAlternativePart($message, $parts[0]); + } elseif ($parts[0] instanceof TextPart) { + $email = self::createEmailFromTextPart($message, $parts[0]); + } else { + throw new RuntimeException(\sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message))); + } + + return self::addParts($email, \array_slice($parts, 1)); + } + + throw new RuntimeException(\sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message))); + } + + private static function createEmailFromTextPart(Message $message, TextPart $part): Email + { + if ('text' === $part->getMediaType() && 'plain' === $part->getMediaSubtype()) { + return (new Email(clone $message->getHeaders()))->text($part->getBody(), $part->getPreparedHeaders()->getHeaderParameter('Content-Type', 'charset') ?: 'utf-8'); + } + if ('text' === $part->getMediaType() && 'html' === $part->getMediaSubtype()) { + return (new Email(clone $message->getHeaders()))->html($part->getBody(), $part->getPreparedHeaders()->getHeaderParameter('Content-Type', 'charset') ?: 'utf-8'); + } + + throw new RuntimeException(\sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message))); + } + + private static function createEmailFromAlternativePart(Message $message, AlternativePart $part): Email + { + $parts = $part->getParts(); + if ( + 2 === \count($parts) + && $parts[0] instanceof TextPart && 'text' === $parts[0]->getMediaType() && 'plain' === $parts[0]->getMediaSubtype() + && $parts[1] instanceof TextPart && 'text' === $parts[1]->getMediaType() && 'html' === $parts[1]->getMediaSubtype() + ) { + return (new Email(clone $message->getHeaders())) + ->text($parts[0]->getBody(), $parts[0]->getPreparedHeaders()->getHeaderParameter('Content-Type', 'charset') ?: 'utf-8') + ->html($parts[1]->getBody(), $parts[1]->getPreparedHeaders()->getHeaderParameter('Content-Type', 'charset') ?: 'utf-8') + ; + } + + throw new RuntimeException(\sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message))); + } + + private static function createEmailFromRelatedPart(Message $message, RelatedPart $part): Email + { + $parts = $part->getParts(); + if ($parts[0] instanceof AlternativePart) { + $email = self::createEmailFromAlternativePart($message, $parts[0]); + } elseif ($parts[0] instanceof TextPart) { + $email = self::createEmailFromTextPart($message, $parts[0]); + } else { + throw new RuntimeException(\sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message))); + } + + return self::addParts($email, \array_slice($parts, 1)); + } + + private static function addParts(Email $email, array $parts): Email + { + foreach ($parts as $part) { + if (!$part instanceof DataPart) { + throw new RuntimeException(\sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($email))); + } + + $email->addPart($part); + } + + return $email; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/MimeTypeGuesserInterface.php b/lib/SymfonyMailer/vendor/symfony/mime/MimeTypeGuesserInterface.php new file mode 100644 index 0000000..30ee3b6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/MimeTypeGuesserInterface.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +/** + * Guesses the MIME type of a file. + * + * @author Fabien Potencier + */ +interface MimeTypeGuesserInterface +{ + /** + * Returns true if this guesser is supported. + */ + public function isGuesserSupported(): bool; + + /** + * Guesses the MIME type of the file with the given path. + * + * @throws \LogicException If the guesser is not supported + * @throws \InvalidArgumentException If the file does not exist or is not readable + */ + public function guessMimeType(string $path): ?string; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/MimeTypes.php b/lib/SymfonyMailer/vendor/symfony/mime/MimeTypes.php new file mode 100644 index 0000000..a24b60f --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/MimeTypes.php @@ -0,0 +1,3789 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\LogicException; + +/** + * Manages MIME types and file extensions. + * + * For MIME type guessing, you can register custom guessers + * by calling the registerGuesser() method. + * Custom guessers are always called before any default ones: + * + * $guesser = new MimeTypes(); + * $guesser->registerGuesser(new MyCustomMimeTypeGuesser()); + * + * If you want to change the order of the default guessers, just re-register your + * preferred one as a custom one. The last registered guesser is preferred over + * previously registered ones. + * + * Re-registering a built-in guesser also allows you to configure it: + * + * $guesser = new MimeTypes(); + * $guesser->registerGuesser(new FileinfoMimeTypeGuesser('/path/to/magic/file')); + * + * @author Fabien Potencier + */ +final class MimeTypes implements MimeTypesInterface +{ + private array $extensions = []; + private array $mimeTypes = []; + + /** + * @var MimeTypeGuesserInterface[] + */ + private array $guessers = []; + private static MimeTypes $default; + + public function __construct(array $map = []) + { + foreach ($map as $mimeType => $extensions) { + $this->extensions[$mimeType] = $extensions; + + foreach ($extensions as $extension) { + $this->mimeTypes[$extension][] = $mimeType; + } + } + $this->registerGuesser(new FileBinaryMimeTypeGuesser()); + $this->registerGuesser(new FileinfoMimeTypeGuesser()); + } + + public static function setDefault(self $default): void + { + self::$default = $default; + } + + public static function getDefault(): self + { + return self::$default ??= new self(); + } + + /** + * Registers a MIME type guesser. + * + * The last registered guesser has precedence over the other ones. + */ + public function registerGuesser(MimeTypeGuesserInterface $guesser): void + { + array_unshift($this->guessers, $guesser); + } + + public function getExtensions(string $mimeType): array + { + if ($this->extensions) { + $extensions = $this->extensions[$mimeType] ?? $this->extensions[$lcMimeType = strtolower($mimeType)] ?? null; + } + + return $extensions ?? self::MAP[$mimeType] ?? self::MAP[$lcMimeType ?? strtolower($mimeType)] ?? []; + } + + public function getMimeTypes(string $ext): array + { + if ($this->mimeTypes) { + $mimeTypes = $this->mimeTypes[$ext] ?? $this->mimeTypes[$lcExt = strtolower($ext)] ?? null; + } + + return $mimeTypes ?? self::REVERSE_MAP[$ext] ?? self::REVERSE_MAP[$lcExt ?? strtolower($ext)] ?? []; + } + + public function isGuesserSupported(): bool + { + foreach ($this->guessers as $guesser) { + if ($guesser->isGuesserSupported()) { + return true; + } + } + + return false; + } + + /** + * The file is passed to each registered MIME type guesser in reverse order + * of their registration (last registered is queried first). Once a guesser + * returns a value that is not null, this method terminates and returns the + * value. + */ + public function guessMimeType(string $path): ?string + { + foreach ($this->guessers as $guesser) { + if (!$guesser->isGuesserSupported()) { + continue; + } + + if (null !== $mimeType = $guesser->guessMimeType($path)) { + return $mimeType; + } + } + + if (!$this->isGuesserSupported()) { + throw new LogicException('Unable to guess the MIME type as no guessers are available (have you enabled the php_fileinfo extension?).'); + } + + return null; + } + + /** + * A map of MIME types and their default extensions. + * + * Updated from upstream on 2024-11-09. + * + * @see Resources/bin/update_mime_types.php + */ + private const MAP = [ + 'application/acrobat' => ['pdf'], + 'application/andrew-inset' => ['ez'], + 'application/annodex' => ['anx'], + 'application/appinstaller' => ['appinstaller'], + 'application/applixware' => ['aw'], + 'application/appx' => ['appx'], + 'application/appxbundle' => ['appxbundle'], + 'application/atom+xml' => ['atom'], + 'application/atomcat+xml' => ['atomcat'], + 'application/atomdeleted+xml' => ['atomdeleted'], + 'application/atomsvc+xml' => ['atomsvc'], + 'application/atsc-dwd+xml' => ['dwd'], + 'application/atsc-held+xml' => ['held'], + 'application/atsc-rsat+xml' => ['rsat'], + 'application/automationml-aml+xml' => ['aml'], + 'application/automationml-amlx+zip' => ['amlx'], + 'application/bat' => ['bat'], + 'application/bdoc' => ['bdoc'], + 'application/bzip2' => ['bz2', 'bz'], + 'application/calendar+xml' => ['xcs'], + 'application/cbor' => ['cbor'], + 'application/ccxml+xml' => ['ccxml'], + 'application/cdfx+xml' => ['cdfx'], + 'application/cdmi-capability' => ['cdmia'], + 'application/cdmi-container' => ['cdmic'], + 'application/cdmi-domain' => ['cdmid'], + 'application/cdmi-object' => ['cdmio'], + 'application/cdmi-queue' => ['cdmiq'], + 'application/cdr' => ['cdr'], + 'application/coreldraw' => ['cdr'], + 'application/cpl+xml' => ['cpl'], + 'application/csv' => ['csv'], + 'application/cu-seeme' => ['cu'], + 'application/cwl' => ['cwl'], + 'application/dash+xml' => ['mpd'], + 'application/dash-patch+xml' => ['mpp'], + 'application/davmount+xml' => ['davmount'], + 'application/dbase' => ['dbf'], + 'application/dbf' => ['dbf'], + 'application/dicom' => ['dcm'], + 'application/docbook+xml' => ['dbk', 'docbook'], + 'application/dssc+der' => ['dssc'], + 'application/dssc+xml' => ['xdssc'], + 'application/ecmascript' => ['ecma', 'es'], + 'application/emf' => ['emf'], + 'application/emma+xml' => ['emma'], + 'application/emotionml+xml' => ['emotionml'], + 'application/epub+zip' => ['epub'], + 'application/exi' => ['exi'], + 'application/express' => ['exp'], + 'application/fdf' => ['fdf'], + 'application/fdt+xml' => ['fdt'], + 'application/fits' => ['fits', 'fit', 'fts'], + 'application/font-tdpfr' => ['pfr'], + 'application/font-woff' => ['woff'], + 'application/futuresplash' => ['swf', 'spl'], + 'application/geo+json' => ['geojson', 'geo.json'], + 'application/gml+xml' => ['gml'], + 'application/gnunet-directory' => ['gnd'], + 'application/gpx' => ['gpx'], + 'application/gpx+xml' => ['gpx'], + 'application/gxf' => ['gxf'], + 'application/gzip' => ['gz'], + 'application/hjson' => ['hjson'], + 'application/hta' => ['hta'], + 'application/hyperstudio' => ['stk'], + 'application/ico' => ['ico'], + 'application/ics' => ['vcs', 'ics', 'ifb', 'icalendar'], + 'application/illustrator' => ['ai'], + 'application/inkml+xml' => ['ink', 'inkml'], + 'application/ipfix' => ['ipfix'], + 'application/its+xml' => ['its'], + 'application/java' => ['class'], + 'application/java-archive' => ['jar', 'war', 'ear'], + 'application/java-byte-code' => ['class'], + 'application/java-serialized-object' => ['ser'], + 'application/java-vm' => ['class'], + 'application/javascript' => ['js', 'jsm', 'mjs'], + 'application/jrd+json' => ['jrd'], + 'application/json' => ['json', 'map'], + 'application/json-patch+json' => ['json-patch'], + 'application/json5' => ['json5'], + 'application/jsonml+json' => ['jsonml'], + 'application/ld+json' => ['jsonld'], + 'application/lgr+xml' => ['lgr'], + 'application/lost+xml' => ['lostxml'], + 'application/lotus123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'], + 'application/m3u' => ['m3u', 'm3u8', 'vlc'], + 'application/mac-binhex40' => ['hqx'], + 'application/mac-compactpro' => ['cpt'], + 'application/mads+xml' => ['mads'], + 'application/manifest+json' => ['webmanifest'], + 'application/marc' => ['mrc'], + 'application/marcxml+xml' => ['mrcx'], + 'application/mathematica' => ['ma', 'nb', 'mb'], + 'application/mathml+xml' => ['mathml', 'mml'], + 'application/mbox' => ['mbox'], + 'application/mdb' => ['mdb'], + 'application/media-policy-dataset+xml' => ['mpf'], + 'application/mediaservercontrol+xml' => ['mscml'], + 'application/metalink+xml' => ['metalink'], + 'application/metalink4+xml' => ['meta4'], + 'application/mets+xml' => ['mets'], + 'application/microsoftpatch' => ['msp'], + 'application/microsoftupdate' => ['msu'], + 'application/mmt-aei+xml' => ['maei'], + 'application/mmt-usd+xml' => ['musd'], + 'application/mods+xml' => ['mods'], + 'application/mp21' => ['m21', 'mp21'], + 'application/mp4' => ['mp4', 'mpg4', 'mp4s', 'm4p'], + 'application/mrb-consumer+xml' => ['xdf'], + 'application/mrb-publish+xml' => ['xdf'], + 'application/ms-tnef' => ['tnef', 'tnf'], + 'application/msaccess' => ['mdb'], + 'application/msexcel' => ['xls', 'xlc', 'xll', 'xlm', 'xlw', 'xla', 'xlt', 'xld'], + 'application/msix' => ['msix'], + 'application/msixbundle' => ['msixbundle'], + 'application/mspowerpoint' => ['ppz', 'ppt', 'pps', 'pot'], + 'application/msword' => ['doc', 'dot'], + 'application/msword-template' => ['dot'], + 'application/mxf' => ['mxf'], + 'application/n-quads' => ['nq'], + 'application/n-triples' => ['nt'], + 'application/nappdf' => ['pdf'], + 'application/node' => ['cjs'], + 'application/octet-stream' => ['bin', 'dms', 'lrf', 'mar', 'so', 'dist', 'distz', 'pkg', 'bpk', 'dump', 'elc', 'deploy', 'exe', 'dll', 'deb', 'dmg', 'iso', 'img', 'msi', 'msp', 'msm', 'buffer'], + 'application/oda' => ['oda'], + 'application/oebps-package+xml' => ['opf'], + 'application/ogg' => ['ogx'], + 'application/omdoc+xml' => ['omdoc'], + 'application/onenote' => ['onetoc', 'onetoc2', 'onetmp', 'onepkg'], + 'application/ovf' => ['ova'], + 'application/owl+xml' => ['owx'], + 'application/oxps' => ['oxps'], + 'application/p2p-overlay+xml' => ['relo'], + 'application/patch-ops-error+xml' => ['xer'], + 'application/pcap' => ['pcap', 'cap', 'dmp'], + 'application/pdf' => ['pdf'], + 'application/pgp' => ['pgp', 'gpg', 'asc'], + 'application/pgp-encrypted' => ['pgp', 'gpg', 'asc'], + 'application/pgp-keys' => ['asc', 'skr', 'pkr', 'pgp', 'gpg', 'key'], + 'application/pgp-signature' => ['sig', 'asc', 'pgp', 'gpg'], + 'application/photoshop' => ['psd'], + 'application/pics-rules' => ['prf'], + 'application/pkcs10' => ['p10'], + 'application/pkcs12' => ['p12', 'pfx'], + 'application/pkcs7-mime' => ['p7m', 'p7c'], + 'application/pkcs7-signature' => ['p7s'], + 'application/pkcs8' => ['p8'], + 'application/pkcs8-encrypted' => ['p8e'], + 'application/pkix-attr-cert' => ['ac'], + 'application/pkix-cert' => ['cer'], + 'application/pkix-crl' => ['crl'], + 'application/pkix-pkipath' => ['pkipath'], + 'application/pkixcmp' => ['pki'], + 'application/pls' => ['pls'], + 'application/pls+xml' => ['pls'], + 'application/postscript' => ['ai', 'eps', 'ps'], + 'application/powerpoint' => ['ppz', 'ppt', 'pps', 'pot'], + 'application/provenance+xml' => ['provx'], + 'application/prs.cww' => ['cww'], + 'application/prs.wavefront-obj' => ['obj'], + 'application/prs.xsf+xml' => ['xsf'], + 'application/pskc+xml' => ['pskcxml'], + 'application/ram' => ['ram'], + 'application/raml+yaml' => ['raml'], + 'application/rdf+xml' => ['rdf', 'owl', 'rdfs'], + 'application/reginfo+xml' => ['rif'], + 'application/relax-ng-compact-syntax' => ['rnc'], + 'application/resource-lists+xml' => ['rl'], + 'application/resource-lists-diff+xml' => ['rld'], + 'application/rls-services+xml' => ['rs'], + 'application/route-apd+xml' => ['rapd'], + 'application/route-s-tsid+xml' => ['sls'], + 'application/route-usd+xml' => ['rusd'], + 'application/rpki-ghostbusters' => ['gbr'], + 'application/rpki-manifest' => ['mft'], + 'application/rpki-roa' => ['roa'], + 'application/rsd+xml' => ['rsd'], + 'application/rss+xml' => ['rss'], + 'application/rtf' => ['rtf'], + 'application/sbml+xml' => ['sbml'], + 'application/schema+json' => ['json'], + 'application/scvp-cv-request' => ['scq'], + 'application/scvp-cv-response' => ['scs'], + 'application/scvp-vp-request' => ['spq'], + 'application/scvp-vp-response' => ['spp'], + 'application/sdp' => ['sdp'], + 'application/senml+xml' => ['senmlx'], + 'application/sensml+xml' => ['sensmlx'], + 'application/set-payment-initiation' => ['setpay'], + 'application/set-registration-initiation' => ['setreg'], + 'application/shf+xml' => ['shf'], + 'application/sieve' => ['siv', 'sieve'], + 'application/smil' => ['smil', 'smi', 'sml', 'kino'], + 'application/smil+xml' => ['smi', 'smil', 'sml', 'kino'], + 'application/sparql-query' => ['rq', 'qs'], + 'application/sparql-results+xml' => ['srx'], + 'application/sql' => ['sql'], + 'application/srgs' => ['gram'], + 'application/srgs+xml' => ['grxml'], + 'application/sru+xml' => ['sru'], + 'application/ssdl+xml' => ['ssdl'], + 'application/ssml+xml' => ['ssml'], + 'application/stuffit' => ['sit', 'hqx'], + 'application/swid+xml' => ['swidtag'], + 'application/tei+xml' => ['tei', 'teicorpus'], + 'application/tga' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'application/thraud+xml' => ['tfi'], + 'application/timestamped-data' => ['tsd'], + 'application/toml' => ['toml'], + 'application/trig' => ['trig'], + 'application/ttml+xml' => ['ttml'], + 'application/ubjson' => ['ubj'], + 'application/urc-ressheet+xml' => ['rsheet'], + 'application/urc-targetdesc+xml' => ['td'], + 'application/vnd.1000minds.decision-model+xml' => ['1km'], + 'application/vnd.3gpp.pic-bw-large' => ['plb'], + 'application/vnd.3gpp.pic-bw-small' => ['psb'], + 'application/vnd.3gpp.pic-bw-var' => ['pvb'], + 'application/vnd.3gpp2.tcap' => ['tcap'], + 'application/vnd.3m.post-it-notes' => ['pwn'], + 'application/vnd.accpac.simply.aso' => ['aso'], + 'application/vnd.accpac.simply.imp' => ['imp'], + 'application/vnd.acucobol' => ['acu'], + 'application/vnd.acucorp' => ['atc', 'acutc'], + 'application/vnd.adobe.air-application-installer-package+zip' => ['air'], + 'application/vnd.adobe.flash.movie' => ['swf', 'spl'], + 'application/vnd.adobe.formscentral.fcdt' => ['fcdt'], + 'application/vnd.adobe.fxp' => ['fxp', 'fxpl'], + 'application/vnd.adobe.illustrator' => ['ai'], + 'application/vnd.adobe.xdp+xml' => ['xdp'], + 'application/vnd.adobe.xfdf' => ['xfdf'], + 'application/vnd.age' => ['age'], + 'application/vnd.ahead.space' => ['ahead'], + 'application/vnd.airzip.filesecure.azf' => ['azf'], + 'application/vnd.airzip.filesecure.azs' => ['azs'], + 'application/vnd.amazon.ebook' => ['azw'], + 'application/vnd.amazon.mobi8-ebook' => ['azw3', 'kfx'], + 'application/vnd.americandynamics.acc' => ['acc'], + 'application/vnd.amiga.ami' => ['ami'], + 'application/vnd.android.package-archive' => ['apk'], + 'application/vnd.anser-web-certificate-issue-initiation' => ['cii'], + 'application/vnd.anser-web-funds-transfer-initiation' => ['fti'], + 'application/vnd.antix.game-component' => ['atx'], + 'application/vnd.apache.parquet' => ['parquet'], + 'application/vnd.appimage' => ['appimage'], + 'application/vnd.apple.installer+xml' => ['mpkg'], + 'application/vnd.apple.keynote' => ['key', 'keynote'], + 'application/vnd.apple.mpegurl' => ['m3u8', 'm3u'], + 'application/vnd.apple.numbers' => ['numbers'], + 'application/vnd.apple.pages' => ['pages'], + 'application/vnd.apple.pkpass' => ['pkpass'], + 'application/vnd.aristanetworks.swi' => ['swi'], + 'application/vnd.astraea-software.iota' => ['iota'], + 'application/vnd.audiograph' => ['aep'], + 'application/vnd.balsamiq.bmml+xml' => ['bmml'], + 'application/vnd.blueice.multipass' => ['mpm'], + 'application/vnd.bmi' => ['bmi'], + 'application/vnd.businessobjects' => ['rep'], + 'application/vnd.chemdraw+xml' => ['cdxml'], + 'application/vnd.chess-pgn' => ['pgn'], + 'application/vnd.chipnuts.karaoke-mmd' => ['mmd'], + 'application/vnd.cinderella' => ['cdy'], + 'application/vnd.citationstyles.style+xml' => ['csl'], + 'application/vnd.claymore' => ['cla'], + 'application/vnd.cloanto.rp9' => ['rp9'], + 'application/vnd.clonk.c4group' => ['c4g', 'c4d', 'c4f', 'c4p', 'c4u'], + 'application/vnd.cluetrust.cartomobile-config' => ['c11amc'], + 'application/vnd.cluetrust.cartomobile-config-pkg' => ['c11amz'], + 'application/vnd.coffeescript' => ['coffee'], + 'application/vnd.comicbook+zip' => ['cbz'], + 'application/vnd.comicbook-rar' => ['cbr'], + 'application/vnd.commonspace' => ['csp'], + 'application/vnd.contact.cmsg' => ['cdbcmsg'], + 'application/vnd.corel-draw' => ['cdr'], + 'application/vnd.cosmocaller' => ['cmc'], + 'application/vnd.crick.clicker' => ['clkx'], + 'application/vnd.crick.clicker.keyboard' => ['clkk'], + 'application/vnd.crick.clicker.palette' => ['clkp'], + 'application/vnd.crick.clicker.template' => ['clkt'], + 'application/vnd.crick.clicker.wordbank' => ['clkw'], + 'application/vnd.criticaltools.wbs+xml' => ['wbs'], + 'application/vnd.ctc-posml' => ['pml'], + 'application/vnd.cups-ppd' => ['ppd'], + 'application/vnd.curl.car' => ['car'], + 'application/vnd.curl.pcurl' => ['pcurl'], + 'application/vnd.dart' => ['dart'], + 'application/vnd.data-vision.rdz' => ['rdz'], + 'application/vnd.dbf' => ['dbf'], + 'application/vnd.debian.binary-package' => ['deb', 'udeb'], + 'application/vnd.dece.data' => ['uvf', 'uvvf', 'uvd', 'uvvd'], + 'application/vnd.dece.ttml+xml' => ['uvt', 'uvvt'], + 'application/vnd.dece.unspecified' => ['uvx', 'uvvx'], + 'application/vnd.dece.zip' => ['uvz', 'uvvz'], + 'application/vnd.denovo.fcselayout-link' => ['fe_launch'], + 'application/vnd.dna' => ['dna'], + 'application/vnd.dolby.mlp' => ['mlp'], + 'application/vnd.dpgraph' => ['dpg'], + 'application/vnd.dreamfactory' => ['dfac'], + 'application/vnd.ds-keypoint' => ['kpxx'], + 'application/vnd.dvb.ait' => ['ait'], + 'application/vnd.dvb.service' => ['svc'], + 'application/vnd.dynageo' => ['geo'], + 'application/vnd.ecowin.chart' => ['mag'], + 'application/vnd.efi.img' => ['raw-disk-image', 'img'], + 'application/vnd.efi.iso' => ['iso', 'iso9660'], + 'application/vnd.emusic-emusic_package' => ['emp'], + 'application/vnd.enliven' => ['nml'], + 'application/vnd.epson.esf' => ['esf'], + 'application/vnd.epson.msf' => ['msf'], + 'application/vnd.epson.quickanime' => ['qam'], + 'application/vnd.epson.salt' => ['slt'], + 'application/vnd.epson.ssf' => ['ssf'], + 'application/vnd.eszigno3+xml' => ['es3', 'et3'], + 'application/vnd.etsi.asic-e+zip' => ['asice'], + 'application/vnd.ezpix-album' => ['ez2'], + 'application/vnd.ezpix-package' => ['ez3'], + 'application/vnd.fdf' => ['fdf'], + 'application/vnd.fdsn.mseed' => ['mseed'], + 'application/vnd.fdsn.seed' => ['seed', 'dataless'], + 'application/vnd.flatpak' => ['flatpak', 'xdgapp'], + 'application/vnd.flatpak.ref' => ['flatpakref'], + 'application/vnd.flatpak.repo' => ['flatpakrepo'], + 'application/vnd.flographit' => ['gph'], + 'application/vnd.fluxtime.clip' => ['ftc'], + 'application/vnd.framemaker' => ['fm', 'frame', 'maker', 'book'], + 'application/vnd.frogans.fnc' => ['fnc'], + 'application/vnd.frogans.ltf' => ['ltf'], + 'application/vnd.fsc.weblaunch' => ['fsc'], + 'application/vnd.fujitsu.oasys' => ['oas'], + 'application/vnd.fujitsu.oasys2' => ['oa2'], + 'application/vnd.fujitsu.oasys3' => ['oa3'], + 'application/vnd.fujitsu.oasysgp' => ['fg5'], + 'application/vnd.fujitsu.oasysprs' => ['bh2'], + 'application/vnd.fujixerox.ddd' => ['ddd'], + 'application/vnd.fujixerox.docuworks' => ['xdw'], + 'application/vnd.fujixerox.docuworks.binder' => ['xbd'], + 'application/vnd.fuzzysheet' => ['fzs'], + 'application/vnd.genomatix.tuxedo' => ['txd'], + 'application/vnd.geo+json' => ['geojson', 'geo.json'], + 'application/vnd.geogebra.file' => ['ggb'], + 'application/vnd.geogebra.slides' => ['ggs'], + 'application/vnd.geogebra.tool' => ['ggt'], + 'application/vnd.geometry-explorer' => ['gex', 'gre'], + 'application/vnd.geonext' => ['gxt'], + 'application/vnd.geoplan' => ['g2w'], + 'application/vnd.geospace' => ['g3w'], + 'application/vnd.gerber' => ['gbr'], + 'application/vnd.gmx' => ['gmx'], + 'application/vnd.google-apps.document' => ['gdoc'], + 'application/vnd.google-apps.presentation' => ['gslides'], + 'application/vnd.google-apps.spreadsheet' => ['gsheet'], + 'application/vnd.google-earth.kml+xml' => ['kml'], + 'application/vnd.google-earth.kmz' => ['kmz'], + 'application/vnd.gov.sk.xmldatacontainer+xml' => ['xdcf'], + 'application/vnd.grafeq' => ['gqf', 'gqs'], + 'application/vnd.groove-account' => ['gac'], + 'application/vnd.groove-help' => ['ghf'], + 'application/vnd.groove-identity-message' => ['gim'], + 'application/vnd.groove-injector' => ['grv'], + 'application/vnd.groove-tool-message' => ['gtm'], + 'application/vnd.groove-tool-template' => ['tpl'], + 'application/vnd.groove-vcard' => ['vcg'], + 'application/vnd.haansoft-hwp' => ['hwp'], + 'application/vnd.haansoft-hwt' => ['hwt'], + 'application/vnd.hal+xml' => ['hal'], + 'application/vnd.handheld-entertainment+xml' => ['zmm'], + 'application/vnd.hbci' => ['hbci'], + 'application/vnd.hhe.lesson-player' => ['les'], + 'application/vnd.hp-hpgl' => ['hpgl'], + 'application/vnd.hp-hpid' => ['hpid'], + 'application/vnd.hp-hps' => ['hps'], + 'application/vnd.hp-jlyt' => ['jlt'], + 'application/vnd.hp-pcl' => ['pcl'], + 'application/vnd.hp-pclxl' => ['pclxl'], + 'application/vnd.hydrostatix.sof-data' => ['sfd-hdstx'], + 'application/vnd.ibm.minipay' => ['mpy'], + 'application/vnd.ibm.modcap' => ['afp', 'listafp', 'list3820'], + 'application/vnd.ibm.rights-management' => ['irm'], + 'application/vnd.ibm.secure-container' => ['sc'], + 'application/vnd.iccprofile' => ['icc', 'icm'], + 'application/vnd.igloader' => ['igl'], + 'application/vnd.immervision-ivp' => ['ivp'], + 'application/vnd.immervision-ivu' => ['ivu'], + 'application/vnd.insors.igm' => ['igm'], + 'application/vnd.intercon.formnet' => ['xpw', 'xpx'], + 'application/vnd.intergeo' => ['i2g'], + 'application/vnd.intu.qbo' => ['qbo'], + 'application/vnd.intu.qfx' => ['qfx'], + 'application/vnd.ipunplugged.rcprofile' => ['rcprofile'], + 'application/vnd.irepository.package+xml' => ['irp'], + 'application/vnd.is-xpr' => ['xpr'], + 'application/vnd.isac.fcs' => ['fcs'], + 'application/vnd.jam' => ['jam'], + 'application/vnd.jcp.javame.midlet-rms' => ['rms'], + 'application/vnd.jisp' => ['jisp'], + 'application/vnd.joost.joda-archive' => ['joda'], + 'application/vnd.kahootz' => ['ktz', 'ktr'], + 'application/vnd.kde.karbon' => ['karbon'], + 'application/vnd.kde.kchart' => ['chrt'], + 'application/vnd.kde.kformula' => ['kfo'], + 'application/vnd.kde.kivio' => ['flw'], + 'application/vnd.kde.kontour' => ['kon'], + 'application/vnd.kde.kpresenter' => ['kpr', 'kpt'], + 'application/vnd.kde.kspread' => ['ksp'], + 'application/vnd.kde.kword' => ['kwd', 'kwt'], + 'application/vnd.kenameaapp' => ['htke'], + 'application/vnd.kidspiration' => ['kia'], + 'application/vnd.kinar' => ['kne', 'knp'], + 'application/vnd.koan' => ['skp', 'skd', 'skt', 'skm'], + 'application/vnd.kodak-descriptor' => ['sse'], + 'application/vnd.las.las+xml' => ['lasxml'], + 'application/vnd.llamagraphics.life-balance.desktop' => ['lbd'], + 'application/vnd.llamagraphics.life-balance.exchange+xml' => ['lbe'], + 'application/vnd.lotus-1-2-3' => ['123', 'wk1', 'wk3', 'wk4', 'wks'], + 'application/vnd.lotus-approach' => ['apr'], + 'application/vnd.lotus-freelance' => ['pre'], + 'application/vnd.lotus-notes' => ['nsf'], + 'application/vnd.lotus-organizer' => ['org'], + 'application/vnd.lotus-screencam' => ['scm'], + 'application/vnd.lotus-wordpro' => ['lwp'], + 'application/vnd.macports.portpkg' => ['portpkg'], + 'application/vnd.mapbox-vector-tile' => ['mvt'], + 'application/vnd.mcd' => ['mcd'], + 'application/vnd.medcalcdata' => ['mc1'], + 'application/vnd.mediastation.cdkey' => ['cdkey'], + 'application/vnd.mfer' => ['mwf'], + 'application/vnd.mfmp' => ['mfm'], + 'application/vnd.micrografx.flo' => ['flo'], + 'application/vnd.micrografx.igx' => ['igx'], + 'application/vnd.microsoft.portable-executable' => ['exe', 'dll', 'cpl', 'drv', 'scr', 'efi', 'ocx', 'sys', 'lib'], + 'application/vnd.mif' => ['mif'], + 'application/vnd.mobius.daf' => ['daf'], + 'application/vnd.mobius.dis' => ['dis'], + 'application/vnd.mobius.mbk' => ['mbk'], + 'application/vnd.mobius.mqy' => ['mqy'], + 'application/vnd.mobius.msl' => ['msl'], + 'application/vnd.mobius.plc' => ['plc'], + 'application/vnd.mobius.txf' => ['txf'], + 'application/vnd.mophun.application' => ['mpn'], + 'application/vnd.mophun.certificate' => ['mpc'], + 'application/vnd.mozilla.xul+xml' => ['xul'], + 'application/vnd.ms-3mfdocument' => ['3mf'], + 'application/vnd.ms-access' => ['mdb'], + 'application/vnd.ms-artgalry' => ['cil'], + 'application/vnd.ms-asf' => ['asf'], + 'application/vnd.ms-cab-compressed' => ['cab'], + 'application/vnd.ms-excel' => ['xls', 'xlm', 'xla', 'xlc', 'xlt', 'xlw', 'xll', 'xld'], + 'application/vnd.ms-excel.addin.macroenabled.12' => ['xlam'], + 'application/vnd.ms-excel.sheet.binary.macroenabled.12' => ['xlsb'], + 'application/vnd.ms-excel.sheet.macroenabled.12' => ['xlsm'], + 'application/vnd.ms-excel.template.macroenabled.12' => ['xltm'], + 'application/vnd.ms-fontobject' => ['eot'], + 'application/vnd.ms-htmlhelp' => ['chm'], + 'application/vnd.ms-ims' => ['ims'], + 'application/vnd.ms-lrm' => ['lrm'], + 'application/vnd.ms-officetheme' => ['thmx'], + 'application/vnd.ms-outlook' => ['msg'], + 'application/vnd.ms-pki.seccat' => ['cat'], + 'application/vnd.ms-pki.stl' => ['stl'], + 'application/vnd.ms-powerpoint' => ['ppt', 'pps', 'pot', 'ppz'], + 'application/vnd.ms-powerpoint.addin.macroenabled.12' => ['ppam'], + 'application/vnd.ms-powerpoint.presentation.macroenabled.12' => ['pptm'], + 'application/vnd.ms-powerpoint.slide.macroenabled.12' => ['sldm'], + 'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => ['ppsm'], + 'application/vnd.ms-powerpoint.template.macroenabled.12' => ['potm'], + 'application/vnd.ms-project' => ['mpp', 'mpt'], + 'application/vnd.ms-publisher' => ['pub'], + 'application/vnd.ms-tnef' => ['tnef', 'tnf'], + 'application/vnd.ms-visio.drawing.macroenabled.main+xml' => ['vsdm'], + 'application/vnd.ms-visio.drawing.main+xml' => ['vsdx'], + 'application/vnd.ms-visio.stencil.macroenabled.main+xml' => ['vssm'], + 'application/vnd.ms-visio.stencil.main+xml' => ['vssx'], + 'application/vnd.ms-visio.template.macroenabled.main+xml' => ['vstm'], + 'application/vnd.ms-visio.template.main+xml' => ['vstx'], + 'application/vnd.ms-word' => ['doc'], + 'application/vnd.ms-word.document.macroenabled.12' => ['docm'], + 'application/vnd.ms-word.template.macroenabled.12' => ['dotm'], + 'application/vnd.ms-works' => ['wps', 'wks', 'wcm', 'wdb', 'xlr'], + 'application/vnd.ms-wpl' => ['wpl'], + 'application/vnd.ms-xpsdocument' => ['xps'], + 'application/vnd.msaccess' => ['mdb'], + 'application/vnd.mseq' => ['mseq'], + 'application/vnd.musician' => ['mus'], + 'application/vnd.muvee.style' => ['msty'], + 'application/vnd.mynfc' => ['taglet'], + 'application/vnd.nato.bindingdataobject+xml' => ['bdo'], + 'application/vnd.neurolanguage.nlu' => ['nlu'], + 'application/vnd.nintendo.snes.rom' => ['sfc', 'smc'], + 'application/vnd.nitf' => ['ntf', 'nitf'], + 'application/vnd.noblenet-directory' => ['nnd'], + 'application/vnd.noblenet-sealer' => ['nns'], + 'application/vnd.noblenet-web' => ['nnw'], + 'application/vnd.nokia.n-gage.ac+xml' => ['ac'], + 'application/vnd.nokia.n-gage.data' => ['ngdat'], + 'application/vnd.nokia.n-gage.symbian.install' => ['n-gage'], + 'application/vnd.nokia.radio-preset' => ['rpst'], + 'application/vnd.nokia.radio-presets' => ['rpss'], + 'application/vnd.novadigm.edm' => ['edm'], + 'application/vnd.novadigm.edx' => ['edx'], + 'application/vnd.novadigm.ext' => ['ext'], + 'application/vnd.oasis.docbook+xml' => ['dbk', 'docbook'], + 'application/vnd.oasis.opendocument.base' => ['odb'], + 'application/vnd.oasis.opendocument.chart' => ['odc'], + 'application/vnd.oasis.opendocument.chart-template' => ['otc'], + 'application/vnd.oasis.opendocument.database' => ['odb'], + 'application/vnd.oasis.opendocument.formula' => ['odf'], + 'application/vnd.oasis.opendocument.formula-template' => ['odft', 'otf'], + 'application/vnd.oasis.opendocument.graphics' => ['odg'], + 'application/vnd.oasis.opendocument.graphics-flat-xml' => ['fodg'], + 'application/vnd.oasis.opendocument.graphics-template' => ['otg'], + 'application/vnd.oasis.opendocument.image' => ['odi'], + 'application/vnd.oasis.opendocument.image-template' => ['oti'], + 'application/vnd.oasis.opendocument.presentation' => ['odp'], + 'application/vnd.oasis.opendocument.presentation-flat-xml' => ['fodp'], + 'application/vnd.oasis.opendocument.presentation-template' => ['otp'], + 'application/vnd.oasis.opendocument.spreadsheet' => ['ods'], + 'application/vnd.oasis.opendocument.spreadsheet-flat-xml' => ['fods'], + 'application/vnd.oasis.opendocument.spreadsheet-template' => ['ots'], + 'application/vnd.oasis.opendocument.text' => ['odt'], + 'application/vnd.oasis.opendocument.text-flat-xml' => ['fodt'], + 'application/vnd.oasis.opendocument.text-master' => ['odm'], + 'application/vnd.oasis.opendocument.text-master-template' => ['otm'], + 'application/vnd.oasis.opendocument.text-template' => ['ott'], + 'application/vnd.oasis.opendocument.text-web' => ['oth'], + 'application/vnd.olpc-sugar' => ['xo'], + 'application/vnd.oma.dd2+xml' => ['dd2'], + 'application/vnd.openblox.game+xml' => ['obgx'], + 'application/vnd.openofficeorg.extension' => ['oxt'], + 'application/vnd.openstreetmap.data+xml' => ['osm'], + 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => ['pptx'], + 'application/vnd.openxmlformats-officedocument.presentationml.slide' => ['sldx'], + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => ['ppsx'], + 'application/vnd.openxmlformats-officedocument.presentationml.template' => ['potx'], + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => ['xlsx'], + 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => ['xltx'], + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => ['docx'], + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => ['dotx'], + 'application/vnd.osgeo.mapguide.package' => ['mgp'], + 'application/vnd.osgi.dp' => ['dp'], + 'application/vnd.osgi.subsystem' => ['esa'], + 'application/vnd.palm' => ['pdb', 'pqa', 'oprc', 'prc'], + 'application/vnd.pawaafile' => ['paw'], + 'application/vnd.pg.format' => ['str'], + 'application/vnd.pg.osasli' => ['ei6'], + 'application/vnd.picsel' => ['efif'], + 'application/vnd.pmi.widget' => ['wg'], + 'application/vnd.pocketlearn' => ['plf'], + 'application/vnd.powerbuilder6' => ['pbd'], + 'application/vnd.previewsystems.box' => ['box'], + 'application/vnd.proteus.magazine' => ['mgz'], + 'application/vnd.publishare-delta-tree' => ['qps'], + 'application/vnd.pvi.ptid1' => ['ptid'], + 'application/vnd.pwg-xhtml-print+xml' => ['xhtm'], + 'application/vnd.quark.quarkxpress' => ['qxd', 'qxt', 'qwd', 'qwt', 'qxl', 'qxb', 'qxp'], + 'application/vnd.rar' => ['rar'], + 'application/vnd.realvnc.bed' => ['bed'], + 'application/vnd.recordare.musicxml' => ['mxl'], + 'application/vnd.recordare.musicxml+xml' => ['musicxml'], + 'application/vnd.rig.cryptonote' => ['cryptonote'], + 'application/vnd.rim.cod' => ['cod'], + 'application/vnd.rn-realmedia' => ['rm', 'rmj', 'rmm', 'rms', 'rmx', 'rmvb'], + 'application/vnd.rn-realmedia-vbr' => ['rmvb', 'rm', 'rmj', 'rmm', 'rms', 'rmx'], + 'application/vnd.route66.link66+xml' => ['link66'], + 'application/vnd.sailingtracker.track' => ['st'], + 'application/vnd.sdp' => ['sdp'], + 'application/vnd.seemail' => ['see'], + 'application/vnd.sema' => ['sema'], + 'application/vnd.semd' => ['semd'], + 'application/vnd.semf' => ['semf'], + 'application/vnd.shana.informed.formdata' => ['ifm'], + 'application/vnd.shana.informed.formtemplate' => ['itp'], + 'application/vnd.shana.informed.interchange' => ['iif'], + 'application/vnd.shana.informed.package' => ['ipk'], + 'application/vnd.simtech-mindmapper' => ['twd', 'twds'], + 'application/vnd.smaf' => ['mmf', 'smaf'], + 'application/vnd.smart.teacher' => ['teacher'], + 'application/vnd.snap' => ['snap'], + 'application/vnd.software602.filler.form+xml' => ['fo'], + 'application/vnd.solent.sdkm+xml' => ['sdkm', 'sdkd'], + 'application/vnd.spotfire.dxp' => ['dxp'], + 'application/vnd.spotfire.sfs' => ['sfs'], + 'application/vnd.sqlite3' => ['sqlite3'], + 'application/vnd.squashfs' => ['sfs', 'sqfs', 'sqsh', 'squashfs'], + 'application/vnd.stardivision.calc' => ['sdc'], + 'application/vnd.stardivision.chart' => ['sds'], + 'application/vnd.stardivision.draw' => ['sda'], + 'application/vnd.stardivision.impress' => ['sdd'], + 'application/vnd.stardivision.impress-packed' => ['sdp'], + 'application/vnd.stardivision.mail' => ['sdm'], + 'application/vnd.stardivision.math' => ['smf'], + 'application/vnd.stardivision.writer' => ['sdw', 'vor'], + 'application/vnd.stardivision.writer-global' => ['sgl'], + 'application/vnd.stepmania.package' => ['smzip'], + 'application/vnd.stepmania.stepchart' => ['sm'], + 'application/vnd.sun.wadl+xml' => ['wadl'], + 'application/vnd.sun.xml.base' => ['odb'], + 'application/vnd.sun.xml.calc' => ['sxc'], + 'application/vnd.sun.xml.calc.template' => ['stc'], + 'application/vnd.sun.xml.draw' => ['sxd'], + 'application/vnd.sun.xml.draw.template' => ['std'], + 'application/vnd.sun.xml.impress' => ['sxi'], + 'application/vnd.sun.xml.impress.template' => ['sti'], + 'application/vnd.sun.xml.math' => ['sxm'], + 'application/vnd.sun.xml.writer' => ['sxw'], + 'application/vnd.sun.xml.writer.global' => ['sxg'], + 'application/vnd.sun.xml.writer.template' => ['stw'], + 'application/vnd.sus-calendar' => ['sus', 'susp'], + 'application/vnd.svd' => ['svd'], + 'application/vnd.symbian.install' => ['sis', 'sisx'], + 'application/vnd.syncml+xml' => ['xsm'], + 'application/vnd.syncml.dm+wbxml' => ['bdm'], + 'application/vnd.syncml.dm+xml' => ['xdm'], + 'application/vnd.syncml.dmddf+xml' => ['ddf'], + 'application/vnd.tao.intent-module-archive' => ['tao'], + 'application/vnd.tcpdump.pcap' => ['pcap', 'cap', 'dmp'], + 'application/vnd.tmobile-livetv' => ['tmo'], + 'application/vnd.trid.tpt' => ['tpt'], + 'application/vnd.triscape.mxs' => ['mxs'], + 'application/vnd.trueapp' => ['tra'], + 'application/vnd.truedoc' => ['pfr'], + 'application/vnd.ufdl' => ['ufd', 'ufdl'], + 'application/vnd.uiq.theme' => ['utz'], + 'application/vnd.umajin' => ['umj'], + 'application/vnd.unity' => ['unityweb'], + 'application/vnd.uoml+xml' => ['uoml', 'uo'], + 'application/vnd.vcx' => ['vcx'], + 'application/vnd.visio' => ['vsd', 'vst', 'vss', 'vsw'], + 'application/vnd.visionary' => ['vis'], + 'application/vnd.vsf' => ['vsf'], + 'application/vnd.wap.wbxml' => ['wbxml'], + 'application/vnd.wap.wmlc' => ['wmlc'], + 'application/vnd.wap.wmlscriptc' => ['wmlsc'], + 'application/vnd.webturbo' => ['wtb'], + 'application/vnd.wolfram.player' => ['nbp'], + 'application/vnd.wordperfect' => ['wpd', 'wp', 'wp4', 'wp5', 'wp6', 'wpp'], + 'application/vnd.wqd' => ['wqd'], + 'application/vnd.wt.stf' => ['stf'], + 'application/vnd.xara' => ['xar'], + 'application/vnd.xdgapp' => ['flatpak', 'xdgapp'], + 'application/vnd.xfdl' => ['xfdl'], + 'application/vnd.yamaha.hv-dic' => ['hvd'], + 'application/vnd.yamaha.hv-script' => ['hvs'], + 'application/vnd.yamaha.hv-voice' => ['hvp'], + 'application/vnd.yamaha.openscoreformat' => ['osf'], + 'application/vnd.yamaha.openscoreformat.osfpvg+xml' => ['osfpvg'], + 'application/vnd.yamaha.smaf-audio' => ['saf'], + 'application/vnd.yamaha.smaf-phrase' => ['spf'], + 'application/vnd.yellowriver-custom-menu' => ['cmp'], + 'application/vnd.youtube.yt' => ['yt'], + 'application/vnd.zul' => ['zir', 'zirz'], + 'application/vnd.zzazz.deck+xml' => ['zaz'], + 'application/voicexml+xml' => ['vxml'], + 'application/wasm' => ['wasm'], + 'application/watcherinfo+xml' => ['wif'], + 'application/widget' => ['wgt'], + 'application/winhlp' => ['hlp'], + 'application/wk1' => ['123', 'wk1', 'wk3', 'wk4', 'wks'], + 'application/wmf' => ['wmf'], + 'application/wordperfect' => ['wp', 'wp4', 'wp5', 'wp6', 'wpd', 'wpp'], + 'application/wsdl+xml' => ['wsdl'], + 'application/wspolicy+xml' => ['wspolicy'], + 'application/wwf' => ['wwf'], + 'application/x-123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'], + 'application/x-7z-compressed' => ['7z', '7z.001'], + 'application/x-abiword' => ['abw', 'abw.CRASHED', 'abw.gz', 'zabw'], + 'application/x-ace' => ['ace'], + 'application/x-ace-compressed' => ['ace'], + 'application/x-alz' => ['alz'], + 'application/x-amiga-disk-format' => ['adf'], + 'application/x-amipro' => ['sam'], + 'application/x-annodex' => ['anx'], + 'application/x-aportisdoc' => ['pdb', 'pdc'], + 'application/x-apple-diskimage' => ['dmg'], + 'application/x-apple-systemprofiler+xml' => ['spx'], + 'application/x-appleworks-document' => ['cwk'], + 'application/x-applix-spreadsheet' => ['as'], + 'application/x-applix-word' => ['aw'], + 'application/x-archive' => ['a', 'ar', 'lib'], + 'application/x-arj' => ['arj'], + 'application/x-asar' => ['asar'], + 'application/x-asp' => ['asp'], + 'application/x-atari-2600-rom' => ['a26'], + 'application/x-atari-7800-rom' => ['a78'], + 'application/x-atari-lynx-rom' => ['lnx'], + 'application/x-authorware-bin' => ['aab', 'x32', 'u32', 'vox'], + 'application/x-authorware-map' => ['aam'], + 'application/x-authorware-seg' => ['aas'], + 'application/x-awk' => ['awk'], + 'application/x-bat' => ['bat'], + 'application/x-bcpio' => ['bcpio'], + 'application/x-bdoc' => ['bdoc'], + 'application/x-bittorrent' => ['torrent'], + 'application/x-blender' => ['blend', 'blender'], + 'application/x-blorb' => ['blb', 'blorb'], + 'application/x-bps-patch' => ['bps'], + 'application/x-bsdiff' => ['bsdiff'], + 'application/x-bz2' => ['bz2'], + 'application/x-bzdvi' => ['dvi.bz2'], + 'application/x-bzip' => ['bz', 'bz2'], + 'application/x-bzip-compressed-tar' => ['tar.bz2', 'tbz2', 'tb2'], + 'application/x-bzip1' => ['bz'], + 'application/x-bzip1-compressed-tar' => ['tar.bz', 'tbz'], + 'application/x-bzip2' => ['bz2', 'boz'], + 'application/x-bzip2-compressed-tar' => ['tar.bz2', 'tbz2', 'tb2'], + 'application/x-bzip3' => ['bz3'], + 'application/x-bzip3-compressed-tar' => ['tar.bz3', 'tbz3'], + 'application/x-bzpdf' => ['pdf.bz2'], + 'application/x-bzpostscript' => ['ps.bz2'], + 'application/x-cb7' => ['cb7'], + 'application/x-cbr' => ['cbr', 'cba', 'cbt', 'cbz', 'cb7'], + 'application/x-cbt' => ['cbt'], + 'application/x-cbz' => ['cbz'], + 'application/x-ccmx' => ['ccmx'], + 'application/x-cd-image' => ['iso', 'iso9660'], + 'application/x-cdlink' => ['vcd'], + 'application/x-cdr' => ['cdr'], + 'application/x-cdrdao-toc' => ['toc'], + 'application/x-cfs-compressed' => ['cfs'], + 'application/x-chat' => ['chat'], + 'application/x-chess-pgn' => ['pgn'], + 'application/x-chm' => ['chm'], + 'application/x-chrome-extension' => ['crx'], + 'application/x-cisco-vpn-settings' => ['pcf'], + 'application/x-cocoa' => ['cco'], + 'application/x-compress' => ['Z'], + 'application/x-compressed-iso' => ['cso'], + 'application/x-compressed-tar' => ['tar.gz', 'tgz'], + 'application/x-conference' => ['nsc'], + 'application/x-coreldraw' => ['cdr'], + 'application/x-cpio' => ['cpio'], + 'application/x-cpio-compressed' => ['cpio.gz'], + 'application/x-csh' => ['csh'], + 'application/x-cue' => ['cue'], + 'application/x-dar' => ['dar'], + 'application/x-dbase' => ['dbf'], + 'application/x-dbf' => ['dbf'], + 'application/x-dc-rom' => ['dc'], + 'application/x-deb' => ['deb', 'udeb'], + 'application/x-debian-package' => ['deb', 'udeb'], + 'application/x-designer' => ['ui'], + 'application/x-desktop' => ['desktop', 'kdelnk'], + 'application/x-dgc-compressed' => ['dgc'], + 'application/x-dia-diagram' => ['dia'], + 'application/x-dia-shape' => ['shape'], + 'application/x-director' => ['dir', 'dcr', 'dxr', 'cst', 'cct', 'cxt', 'w3d', 'fgd', 'swa'], + 'application/x-discjuggler-cd-image' => ['cdi'], + 'application/x-docbook+xml' => ['dbk', 'docbook'], + 'application/x-doom' => ['wad'], + 'application/x-doom-wad' => ['wad'], + 'application/x-dosexec' => ['exe'], + 'application/x-dreamcast-rom' => ['iso'], + 'application/x-dtbncx+xml' => ['ncx'], + 'application/x-dtbook+xml' => ['dtb'], + 'application/x-dtbresource+xml' => ['res'], + 'application/x-dvi' => ['dvi'], + 'application/x-e-theme' => ['etheme'], + 'application/x-egon' => ['egon'], + 'application/x-emf' => ['emf'], + 'application/x-envoy' => ['evy'], + 'application/x-eris-link+cbor' => ['eris'], + 'application/x-eva' => ['eva'], + 'application/x-excellon' => ['drl'], + 'application/x-fd-file' => ['fd', 'qd'], + 'application/x-fds-disk' => ['fds'], + 'application/x-fictionbook' => ['fb2'], + 'application/x-fictionbook+xml' => ['fb2'], + 'application/x-fishscript' => ['fish'], + 'application/x-flash-video' => ['flv'], + 'application/x-fluid' => ['fl'], + 'application/x-font-afm' => ['afm'], + 'application/x-font-bdf' => ['bdf'], + 'application/x-font-ghostscript' => ['gsf'], + 'application/x-font-linux-psf' => ['psf'], + 'application/x-font-otf' => ['otf'], + 'application/x-font-pcf' => ['pcf', 'pcf.Z', 'pcf.gz'], + 'application/x-font-snf' => ['snf'], + 'application/x-font-speedo' => ['spd'], + 'application/x-font-truetype' => ['ttf'], + 'application/x-font-ttf' => ['ttf'], + 'application/x-font-ttx' => ['ttx'], + 'application/x-font-type1' => ['pfa', 'pfb', 'pfm', 'afm', 'gsf'], + 'application/x-font-woff' => ['woff'], + 'application/x-frame' => ['fm'], + 'application/x-freearc' => ['arc'], + 'application/x-futuresplash' => ['spl'], + 'application/x-gameboy-color-rom' => ['gbc', 'cgb'], + 'application/x-gameboy-rom' => ['gb', 'sgb'], + 'application/x-gamecube-iso-image' => ['iso'], + 'application/x-gamecube-rom' => ['iso'], + 'application/x-gamegear-rom' => ['gg'], + 'application/x-gba-rom' => ['gba', 'agb'], + 'application/x-gca-compressed' => ['gca'], + 'application/x-gd-rom-cue' => ['gdi'], + 'application/x-gdscript' => ['gd'], + 'application/x-gedcom' => ['ged', 'gedcom'], + 'application/x-genesis-32x-rom' => ['32x', 'mdx'], + 'application/x-genesis-rom' => ['gen', 'smd', 'md', 'sgd'], + 'application/x-gerber' => ['gbr'], + 'application/x-gerber-job' => ['gbrjob'], + 'application/x-gettext' => ['po'], + 'application/x-gettext-translation' => ['gmo', 'mo'], + 'application/x-glade' => ['glade'], + 'application/x-glulx' => ['ulx'], + 'application/x-gnome-app-info' => ['desktop', 'kdelnk'], + 'application/x-gnucash' => ['gnucash', 'gnc', 'xac'], + 'application/x-gnumeric' => ['gnumeric'], + 'application/x-gnuplot' => ['gp', 'gplt', 'gnuplot'], + 'application/x-go-sgf' => ['sgf'], + 'application/x-godot-resource' => ['res', 'tres'], + 'application/x-godot-scene' => ['scn', 'tscn', 'escn'], + 'application/x-godot-shader' => ['gdshader'], + 'application/x-gpx' => ['gpx'], + 'application/x-gpx+xml' => ['gpx'], + 'application/x-gramps-xml' => ['gramps'], + 'application/x-graphite' => ['gra'], + 'application/x-gtar' => ['gtar', 'tar', 'gem'], + 'application/x-gtk-builder' => ['ui'], + 'application/x-gz-font-linux-psf' => ['psf.gz'], + 'application/x-gzdvi' => ['dvi.gz'], + 'application/x-gzip' => ['gz'], + 'application/x-gzpdf' => ['pdf.gz'], + 'application/x-gzpostscript' => ['ps.gz'], + 'application/x-hdf' => ['hdf', 'hdf4', 'h4', 'hdf5', 'h5'], + 'application/x-hfe-file' => ['hfe'], + 'application/x-hfe-floppy-image' => ['hfe'], + 'application/x-httpd-php' => ['php'], + 'application/x-hwp' => ['hwp'], + 'application/x-hwt' => ['hwt'], + 'application/x-ica' => ['ica'], + 'application/x-install-instructions' => ['install'], + 'application/x-ips-patch' => ['ips'], + 'application/x-ipynb+json' => ['ipynb'], + 'application/x-iso9660-appimage' => ['appimage'], + 'application/x-iso9660-image' => ['iso', 'iso9660'], + 'application/x-it87' => ['it87'], + 'application/x-iwork-keynote-sffkey' => ['key'], + 'application/x-iwork-numbers-sffnumbers' => ['numbers'], + 'application/x-iwork-pages-sffpages' => ['pages'], + 'application/x-jar' => ['jar'], + 'application/x-java' => ['class'], + 'application/x-java-archive' => ['jar'], + 'application/x-java-archive-diff' => ['jardiff'], + 'application/x-java-class' => ['class'], + 'application/x-java-jce-keystore' => ['jceks'], + 'application/x-java-jnlp-file' => ['jnlp'], + 'application/x-java-keystore' => ['jks', 'ks'], + 'application/x-java-pack200' => ['pack'], + 'application/x-java-vm' => ['class'], + 'application/x-javascript' => ['js', 'jsm', 'mjs'], + 'application/x-jbuilder-project' => ['jpr', 'jpx'], + 'application/x-karbon' => ['karbon'], + 'application/x-kchart' => ['chrt'], + 'application/x-keepass2' => ['kdbx'], + 'application/x-kexi-connectiondata' => ['kexic'], + 'application/x-kexiproject-shortcut' => ['kexis'], + 'application/x-kexiproject-sqlite' => ['kexi'], + 'application/x-kexiproject-sqlite2' => ['kexi'], + 'application/x-kexiproject-sqlite3' => ['kexi'], + 'application/x-kformula' => ['kfo'], + 'application/x-killustrator' => ['kil'], + 'application/x-kivio' => ['flw'], + 'application/x-kontour' => ['kon'], + 'application/x-kpovmodeler' => ['kpm'], + 'application/x-kpresenter' => ['kpr', 'kpt'], + 'application/x-krita' => ['kra', 'krz'], + 'application/x-kspread' => ['ksp'], + 'application/x-kugar' => ['kud'], + 'application/x-kword' => ['kwd', 'kwt'], + 'application/x-latex' => ['latex'], + 'application/x-lha' => ['lha', 'lzh'], + 'application/x-lhz' => ['lhz'], + 'application/x-linguist' => ['ts'], + 'application/x-lmdb' => ['mdb', 'lmdb'], + 'application/x-lotus123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'], + 'application/x-lrzip' => ['lrz'], + 'application/x-lrzip-compressed-tar' => ['tar.lrz', 'tlrz'], + 'application/x-lua-bytecode' => ['luac'], + 'application/x-lyx' => ['lyx'], + 'application/x-lz4' => ['lz4'], + 'application/x-lz4-compressed-tar' => ['tar.lz4'], + 'application/x-lzh-compressed' => ['lzh', 'lha'], + 'application/x-lzip' => ['lz'], + 'application/x-lzip-compressed-tar' => ['tar.lz'], + 'application/x-lzma' => ['lzma'], + 'application/x-lzma-compressed-tar' => ['tar.lzma', 'tlz'], + 'application/x-lzop' => ['lzo'], + 'application/x-lzpdf' => ['pdf.lz'], + 'application/x-m4' => ['m4'], + 'application/x-magicpoint' => ['mgp'], + 'application/x-makeself' => ['run'], + 'application/x-mame-chd' => ['chd'], + 'application/x-markaby' => ['mab'], + 'application/x-mathematica' => ['nb'], + 'application/x-mdb' => ['mdb'], + 'application/x-mie' => ['mie'], + 'application/x-mif' => ['mif'], + 'application/x-mimearchive' => ['mhtml', 'mht'], + 'application/x-mobi8-ebook' => ['azw3', 'kfx'], + 'application/x-mobipocket-ebook' => ['prc', 'mobi'], + 'application/x-modrinth-modpack+zip' => ['mrpack'], + 'application/x-ms-application' => ['application'], + 'application/x-ms-asx' => ['asx', 'wax', 'wvx', 'wmx'], + 'application/x-ms-dos-executable' => ['exe', 'dll', 'cpl', 'drv', 'scr'], + 'application/x-ms-ne-executable' => ['exe', 'dll', 'cpl', 'drv', 'scr'], + 'application/x-ms-pdb' => ['pdb'], + 'application/x-ms-shortcut' => ['lnk'], + 'application/x-ms-wim' => ['wim', 'swm'], + 'application/x-ms-wmd' => ['wmd'], + 'application/x-ms-wmz' => ['wmz'], + 'application/x-ms-xbap' => ['xbap'], + 'application/x-msaccess' => ['mdb'], + 'application/x-msbinder' => ['obd'], + 'application/x-mscardfile' => ['crd'], + 'application/x-msclip' => ['clp'], + 'application/x-msdos-program' => ['exe'], + 'application/x-msdownload' => ['exe', 'dll', 'com', 'bat', 'msi', 'cpl', 'drv', 'scr'], + 'application/x-msexcel' => ['xls', 'xlc', 'xll', 'xlm', 'xlw', 'xla', 'xlt', 'xld'], + 'application/x-msi' => ['msi'], + 'application/x-msmediaview' => ['mvb', 'm13', 'm14'], + 'application/x-msmetafile' => ['wmf', 'wmz', 'emf', 'emz'], + 'application/x-msmoney' => ['mny'], + 'application/x-mspowerpoint' => ['ppz', 'ppt', 'pps', 'pot'], + 'application/x-mspublisher' => ['pub'], + 'application/x-msschedule' => ['scd'], + 'application/x-msterminal' => ['trm'], + 'application/x-mswinurl' => ['url'], + 'application/x-msword' => ['doc'], + 'application/x-mswrite' => ['wri'], + 'application/x-msx-rom' => ['msx'], + 'application/x-n64-rom' => ['n64', 'z64', 'v64'], + 'application/x-navi-animation' => ['ani'], + 'application/x-neo-geo-pocket-color-rom' => ['ngc'], + 'application/x-neo-geo-pocket-rom' => ['ngp'], + 'application/x-nes-rom' => ['nes', 'nez', 'unf', 'unif'], + 'application/x-netcdf' => ['nc', 'cdf'], + 'application/x-netshow-channel' => ['nsc'], + 'application/x-nintendo-3ds-executable' => ['3dsx'], + 'application/x-nintendo-3ds-rom' => ['3ds', 'cci'], + 'application/x-nintendo-ds-rom' => ['nds'], + 'application/x-nintendo-switch-xci' => ['xci'], + 'application/x-ns-proxy-autoconfig' => ['pac'], + 'application/x-nuscript' => ['nu'], + 'application/x-nx-xci' => ['xci'], + 'application/x-nzb' => ['nzb'], + 'application/x-object' => ['o', 'mod'], + 'application/x-ogg' => ['ogx'], + 'application/x-oleo' => ['oleo'], + 'application/x-openvpn-profile' => ['openvpn', 'ovpn'], + 'application/x-openzim' => ['zim'], + 'application/x-pagemaker' => ['p65', 'pm', 'pm6', 'pmd'], + 'application/x-pak' => ['pak'], + 'application/x-palm-database' => ['prc', 'pdb', 'pqa', 'oprc'], + 'application/x-par2' => ['PAR2', 'par2'], + 'application/x-parquet' => ['parquet'], + 'application/x-partial-download' => ['wkdownload', 'crdownload', 'part'], + 'application/x-pc-engine-rom' => ['pce'], + 'application/x-pcap' => ['pcap', 'cap', 'dmp'], + 'application/x-pcapng' => ['pcapng', 'ntar'], + 'application/x-pdf' => ['pdf'], + 'application/x-perl' => ['pl', 'pm', 'PL', 'al', 'perl', 'pod', 't'], + 'application/x-photoshop' => ['psd'], + 'application/x-php' => ['php', 'php3', 'php4', 'php5', 'phps'], + 'application/x-pilot' => ['prc', 'pdb'], + 'application/x-pkcs12' => ['p12', 'pfx'], + 'application/x-pkcs7-certificates' => ['p7b', 'spc'], + 'application/x-pkcs7-certreqresp' => ['p7r'], + 'application/x-planperfect' => ['pln'], + 'application/x-pocket-word' => ['psw'], + 'application/x-powershell' => ['ps1'], + 'application/x-pw' => ['pw'], + 'application/x-pyspread-bz-spreadsheet' => ['pys'], + 'application/x-pyspread-spreadsheet' => ['pysu'], + 'application/x-python-bytecode' => ['pyc', 'pyo'], + 'application/x-qbrew' => ['qbrew'], + 'application/x-qed-disk' => ['qed'], + 'application/x-qemu-disk' => ['qcow2', 'qcow'], + 'application/x-qpress' => ['qp'], + 'application/x-qtiplot' => ['qti', 'qti.gz'], + 'application/x-quattropro' => ['wb1', 'wb2', 'wb3', 'qpw'], + 'application/x-quicktime-media-link' => ['qtl'], + 'application/x-quicktimeplayer' => ['qtl'], + 'application/x-qw' => ['qif'], + 'application/x-rar' => ['rar'], + 'application/x-rar-compressed' => ['rar'], + 'application/x-raw-disk-image' => ['raw-disk-image', 'img'], + 'application/x-raw-disk-image-xz-compressed' => ['raw-disk-image.xz', 'img.xz'], + 'application/x-raw-floppy-disk-image' => ['fd', 'qd'], + 'application/x-redhat-package-manager' => ['rpm'], + 'application/x-reject' => ['rej'], + 'application/x-research-info-systems' => ['ris'], + 'application/x-rnc' => ['rnc'], + 'application/x-rpm' => ['rpm'], + 'application/x-ruby' => ['rb'], + 'application/x-rzip' => ['rz'], + 'application/x-rzip-compressed-tar' => ['tar.rz', 'trz'], + 'application/x-sami' => ['smi', 'sami'], + 'application/x-sap-file' => ['sap'], + 'application/x-saturn-rom' => ['iso'], + 'application/x-sdp' => ['sdp'], + 'application/x-sea' => ['sea'], + 'application/x-sega-cd-rom' => ['iso'], + 'application/x-sega-pico-rom' => ['iso'], + 'application/x-sg1000-rom' => ['sg'], + 'application/x-sh' => ['sh'], + 'application/x-shar' => ['shar'], + 'application/x-shared-library-la' => ['la'], + 'application/x-sharedlib' => ['so'], + 'application/x-shellscript' => ['sh'], + 'application/x-shockwave-flash' => ['swf', 'spl'], + 'application/x-shorten' => ['shn'], + 'application/x-siag' => ['siag'], + 'application/x-silverlight-app' => ['xap'], + 'application/x-sit' => ['sit'], + 'application/x-sitx' => ['sitx'], + 'application/x-smaf' => ['mmf', 'smaf'], + 'application/x-sms-rom' => ['sms'], + 'application/x-snes-rom' => ['sfc', 'smc'], + 'application/x-sony-bbeb' => ['lrf'], + 'application/x-source-rpm' => ['src.rpm', 'spm'], + 'application/x-spss-por' => ['por'], + 'application/x-spss-sav' => ['sav', 'zsav'], + 'application/x-spss-savefile' => ['sav', 'zsav'], + 'application/x-sql' => ['sql'], + 'application/x-sqlite2' => ['sqlite2'], + 'application/x-sqlite3' => ['sqlite3'], + 'application/x-srt' => ['srt'], + 'application/x-starcalc' => ['sdc'], + 'application/x-starchart' => ['sds'], + 'application/x-stardraw' => ['sda'], + 'application/x-starimpress' => ['sdd'], + 'application/x-starmail' => ['smd'], + 'application/x-starmath' => ['smf'], + 'application/x-starwriter' => ['sdw', 'vor'], + 'application/x-starwriter-global' => ['sgl'], + 'application/x-stuffit' => ['sit'], + 'application/x-stuffitx' => ['sitx'], + 'application/x-subrip' => ['srt'], + 'application/x-sv4cpio' => ['sv4cpio'], + 'application/x-sv4crc' => ['sv4crc'], + 'application/x-sylk' => ['sylk', 'slk'], + 'application/x-t3vm-image' => ['t3'], + 'application/x-t602' => ['602'], + 'application/x-tads' => ['gam'], + 'application/x-tar' => ['tar', 'gtar', 'gem'], + 'application/x-targa' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'application/x-tarz' => ['tar.Z', 'taz'], + 'application/x-tcl' => ['tcl', 'tk'], + 'application/x-tex' => ['tex', 'ltx', 'sty', 'cls', 'dtx', 'ins', 'latex'], + 'application/x-tex-gf' => ['gf'], + 'application/x-tex-pk' => ['pk'], + 'application/x-tex-tfm' => ['tfm'], + 'application/x-texinfo' => ['texinfo', 'texi'], + 'application/x-tga' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'application/x-tgif' => ['obj'], + 'application/x-theme' => ['theme'], + 'application/x-thomson-cartridge-memo7' => ['m7'], + 'application/x-thomson-cassette' => ['k7'], + 'application/x-thomson-sap-image' => ['sap'], + 'application/x-tiled-tmx' => ['tmx'], + 'application/x-tiled-tsx' => ['tsx'], + 'application/x-trash' => ['bak', 'old', 'sik'], + 'application/x-trig' => ['trig'], + 'application/x-troff' => ['tr', 'roff', 't'], + 'application/x-troff-man' => ['man'], + 'application/x-tzo' => ['tar.lzo', 'tzo'], + 'application/x-ufraw' => ['ufraw'], + 'application/x-ustar' => ['ustar'], + 'application/x-vdi-disk' => ['vdi'], + 'application/x-vhd-disk' => ['vhd', 'vpc'], + 'application/x-vhdx-disk' => ['vhdx'], + 'application/x-virtual-boy-rom' => ['vb'], + 'application/x-virtualbox-hdd' => ['hdd'], + 'application/x-virtualbox-ova' => ['ova'], + 'application/x-virtualbox-ovf' => ['ovf'], + 'application/x-virtualbox-vbox' => ['vbox'], + 'application/x-virtualbox-vbox-extpack' => ['vbox-extpack'], + 'application/x-virtualbox-vdi' => ['vdi'], + 'application/x-virtualbox-vhd' => ['vhd', 'vpc'], + 'application/x-virtualbox-vhdx' => ['vhdx'], + 'application/x-virtualbox-vmdk' => ['vmdk'], + 'application/x-vmdk-disk' => ['vmdk'], + 'application/x-vnd.kde.kexi' => ['kexi'], + 'application/x-wais-source' => ['src'], + 'application/x-wbfs' => ['iso'], + 'application/x-web-app-manifest+json' => ['webapp'], + 'application/x-wia' => ['iso'], + 'application/x-wii-iso-image' => ['iso'], + 'application/x-wii-rom' => ['iso'], + 'application/x-wii-wad' => ['wad'], + 'application/x-win-lnk' => ['lnk'], + 'application/x-windows-themepack' => ['themepack'], + 'application/x-wmf' => ['wmf'], + 'application/x-wonderswan-color-rom' => ['wsc'], + 'application/x-wonderswan-rom' => ['ws'], + 'application/x-wordperfect' => ['wp', 'wp4', 'wp5', 'wp6', 'wpd', 'wpp'], + 'application/x-wpg' => ['wpg'], + 'application/x-wwf' => ['wwf'], + 'application/x-x509-ca-cert' => ['der', 'crt', 'pem', 'cert'], + 'application/x-xar' => ['xar', 'pkg'], + 'application/x-xbel' => ['xbel'], + 'application/x-xfig' => ['fig'], + 'application/x-xliff' => ['xlf', 'xliff'], + 'application/x-xliff+xml' => ['xlf'], + 'application/x-xpinstall' => ['xpi'], + 'application/x-xspf+xml' => ['xspf'], + 'application/x-xz' => ['xz'], + 'application/x-xz-compressed-tar' => ['tar.xz', 'txz'], + 'application/x-xzpdf' => ['pdf.xz'], + 'application/x-yaml' => ['yaml', 'yml'], + 'application/x-zip' => ['zip', 'zipx'], + 'application/x-zip-compressed' => ['zip', 'zipx'], + 'application/x-zip-compressed-fb2' => ['fb2.zip'], + 'application/x-zmachine' => ['z1', 'z2', 'z3', 'z4', 'z5', 'z6', 'z7', 'z8'], + 'application/x-zoo' => ['zoo'], + 'application/x-zpaq' => ['zpaq'], + 'application/x-zstd-compressed-tar' => ['tar.zst', 'tzst'], + 'application/xaml+xml' => ['xaml'], + 'application/xcap-att+xml' => ['xav'], + 'application/xcap-caps+xml' => ['xca'], + 'application/xcap-diff+xml' => ['xdf'], + 'application/xcap-el+xml' => ['xel'], + 'application/xcap-error+xml' => ['xer'], + 'application/xcap-ns+xml' => ['xns'], + 'application/xenc+xml' => ['xenc'], + 'application/xfdf' => ['xfdf'], + 'application/xhtml+xml' => ['xhtml', 'xht', 'html', 'htm'], + 'application/xliff+xml' => ['xlf', 'xliff'], + 'application/xml' => ['xml', 'xsl', 'xsd', 'rng', 'xbl'], + 'application/xml-dtd' => ['dtd'], + 'application/xml-external-parsed-entity' => ['ent'], + 'application/xop+xml' => ['xop'], + 'application/xproc+xml' => ['xpl'], + 'application/xps' => ['xps'], + 'application/xslt+xml' => ['xsl', 'xslt'], + 'application/xspf+xml' => ['xspf'], + 'application/xv+xml' => ['mxml', 'xhvml', 'xvml', 'xvm'], + 'application/yaml' => ['yaml', 'yml'], + 'application/yang' => ['yang'], + 'application/yin+xml' => ['yin'], + 'application/zip' => ['zip', 'zipx'], + 'application/zlib' => ['zz'], + 'application/zstd' => ['zst'], + 'audio/3gpp' => ['3gpp', '3gp', '3ga'], + 'audio/3gpp-encrypted' => ['3gp', '3gpp', '3ga'], + 'audio/3gpp2' => ['3g2', '3gp2', '3gpp2'], + 'audio/aac' => ['aac', 'adts', 'ass'], + 'audio/ac3' => ['ac3'], + 'audio/adpcm' => ['adp'], + 'audio/amr' => ['amr'], + 'audio/amr-encrypted' => ['amr'], + 'audio/amr-wb' => ['awb'], + 'audio/amr-wb-encrypted' => ['awb'], + 'audio/annodex' => ['axa'], + 'audio/basic' => ['au', 'snd'], + 'audio/dff' => ['dff'], + 'audio/dsd' => ['dsf'], + 'audio/dsf' => ['dsf'], + 'audio/flac' => ['flac'], + 'audio/imelody' => ['imy', 'ime'], + 'audio/m3u' => ['m3u', 'm3u8', 'vlc'], + 'audio/m4a' => ['m4a', 'f4a'], + 'audio/midi' => ['mid', 'midi', 'kar', 'rmi'], + 'audio/mobile-xmf' => ['mxmf'], + 'audio/mp2' => ['mp2'], + 'audio/mp3' => ['mp3', 'mpga'], + 'audio/mp4' => ['m4a', 'mp4a', 'f4a'], + 'audio/mpeg' => ['mp3', 'mpga', 'mp2', 'mp2a', 'm2a', 'm3a'], + 'audio/mpegurl' => ['m3u', 'm3u8', 'vlc'], + 'audio/ogg' => ['ogg', 'oga', 'spx', 'opus'], + 'audio/prs.sid' => ['sid', 'psid'], + 'audio/s3m' => ['s3m'], + 'audio/scpls' => ['pls'], + 'audio/silk' => ['sil'], + 'audio/tta' => ['tta'], + 'audio/usac' => ['loas', 'xhe'], + 'audio/vnd.audible' => ['aa', 'aax'], + 'audio/vnd.audible.aax' => ['aax'], + 'audio/vnd.audible.aaxc' => ['aaxc'], + 'audio/vnd.dece.audio' => ['uva', 'uvva'], + 'audio/vnd.digital-winds' => ['eol'], + 'audio/vnd.dra' => ['dra'], + 'audio/vnd.dts' => ['dts'], + 'audio/vnd.dts.hd' => ['dtshd'], + 'audio/vnd.lucent.voice' => ['lvp'], + 'audio/vnd.m-realaudio' => ['ra', 'rax'], + 'audio/vnd.ms-playready.media.pya' => ['pya'], + 'audio/vnd.nokia.mobile-xmf' => ['mxmf'], + 'audio/vnd.nuera.ecelp4800' => ['ecelp4800'], + 'audio/vnd.nuera.ecelp7470' => ['ecelp7470'], + 'audio/vnd.nuera.ecelp9600' => ['ecelp9600'], + 'audio/vnd.rip' => ['rip'], + 'audio/vnd.rn-realaudio' => ['ra', 'rax'], + 'audio/vnd.wave' => ['wav'], + 'audio/vorbis' => ['oga', 'ogg'], + 'audio/wav' => ['wav'], + 'audio/wave' => ['wav'], + 'audio/webm' => ['weba'], + 'audio/wma' => ['wma'], + 'audio/x-aac' => ['aac', 'adts', 'ass'], + 'audio/x-aifc' => ['aifc', 'aiffc'], + 'audio/x-aiff' => ['aif', 'aiff', 'aifc'], + 'audio/x-aiffc' => ['aifc', 'aiffc'], + 'audio/x-amzxml' => ['amz'], + 'audio/x-annodex' => ['axa'], + 'audio/x-ape' => ['ape'], + 'audio/x-caf' => ['caf'], + 'audio/x-dff' => ['dff'], + 'audio/x-dsd' => ['dsf'], + 'audio/x-dsf' => ['dsf'], + 'audio/x-dts' => ['dts'], + 'audio/x-dtshd' => ['dtshd'], + 'audio/x-flac' => ['flac'], + 'audio/x-flac+ogg' => ['oga', 'ogg'], + 'audio/x-gsm' => ['gsm'], + 'audio/x-hx-aac-adts' => ['aac', 'adts', 'ass'], + 'audio/x-imelody' => ['imy', 'ime'], + 'audio/x-iriver-pla' => ['pla'], + 'audio/x-it' => ['it'], + 'audio/x-m3u' => ['m3u', 'm3u8', 'vlc'], + 'audio/x-m4a' => ['m4a', 'f4a'], + 'audio/x-m4b' => ['m4b', 'f4b'], + 'audio/x-m4r' => ['m4r'], + 'audio/x-matroska' => ['mka'], + 'audio/x-midi' => ['mid', 'midi', 'kar'], + 'audio/x-minipsf' => ['minipsf'], + 'audio/x-mo3' => ['mo3'], + 'audio/x-mod' => ['mod', 'ult', 'uni', 'm15', 'mtm', '669', 'med'], + 'audio/x-mp2' => ['mp2'], + 'audio/x-mp3' => ['mp3', 'mpga'], + 'audio/x-mp3-playlist' => ['m3u', 'm3u8', 'vlc'], + 'audio/x-mpeg' => ['mp3', 'mpga'], + 'audio/x-mpegurl' => ['m3u', 'm3u8', 'vlc'], + 'audio/x-mpg' => ['mp3', 'mpga'], + 'audio/x-ms-asx' => ['asx', 'wax', 'wvx', 'wmx'], + 'audio/x-ms-wax' => ['wax'], + 'audio/x-ms-wma' => ['wma'], + 'audio/x-ms-wmv' => ['wmv'], + 'audio/x-musepack' => ['mpc', 'mpp', 'mp+'], + 'audio/x-ogg' => ['oga', 'ogg', 'opus'], + 'audio/x-oggflac' => ['oga', 'ogg'], + 'audio/x-opus+ogg' => ['opus'], + 'audio/x-pn-audibleaudio' => ['aa', 'aax'], + 'audio/x-pn-realaudio' => ['ram', 'ra', 'rax'], + 'audio/x-pn-realaudio-plugin' => ['rmp'], + 'audio/x-psf' => ['psf'], + 'audio/x-psflib' => ['psflib'], + 'audio/x-realaudio' => ['ra'], + 'audio/x-rn-3gpp-amr' => ['3gp', '3gpp', '3ga'], + 'audio/x-rn-3gpp-amr-encrypted' => ['3gp', '3gpp', '3ga'], + 'audio/x-rn-3gpp-amr-wb' => ['3gp', '3gpp', '3ga'], + 'audio/x-rn-3gpp-amr-wb-encrypted' => ['3gp', '3gpp', '3ga'], + 'audio/x-s3m' => ['s3m'], + 'audio/x-scpls' => ['pls'], + 'audio/x-shorten' => ['shn'], + 'audio/x-speex' => ['spx'], + 'audio/x-speex+ogg' => ['oga', 'ogg', 'spx'], + 'audio/x-stm' => ['stm'], + 'audio/x-tak' => ['tak'], + 'audio/x-tta' => ['tta'], + 'audio/x-voc' => ['voc'], + 'audio/x-vorbis' => ['oga', 'ogg'], + 'audio/x-vorbis+ogg' => ['oga', 'ogg'], + 'audio/x-wav' => ['wav'], + 'audio/x-wavpack' => ['wv', 'wvp'], + 'audio/x-wavpack-correction' => ['wvc'], + 'audio/x-xi' => ['xi'], + 'audio/x-xm' => ['xm'], + 'audio/x-xmf' => ['xmf'], + 'audio/xm' => ['xm'], + 'audio/xmf' => ['xmf'], + 'chemical/x-cdx' => ['cdx'], + 'chemical/x-cif' => ['cif'], + 'chemical/x-cmdf' => ['cmdf'], + 'chemical/x-cml' => ['cml'], + 'chemical/x-csml' => ['csml'], + 'chemical/x-pdb' => ['pdb', 'brk'], + 'chemical/x-xyz' => ['xyz'], + 'flv-application/octet-stream' => ['flv'], + 'font/collection' => ['ttc'], + 'font/otf' => ['otf'], + 'font/ttf' => ['ttf'], + 'font/woff' => ['woff'], + 'font/woff2' => ['woff2'], + 'image/aces' => ['exr'], + 'image/apng' => ['apng', 'png'], + 'image/astc' => ['astc'], + 'image/avci' => ['avci'], + 'image/avcs' => ['avcs'], + 'image/avif' => ['avif', 'avifs'], + 'image/avif-sequence' => ['avif', 'avifs'], + 'image/bmp' => ['bmp', 'dib'], + 'image/cdr' => ['cdr'], + 'image/cgm' => ['cgm'], + 'image/dicom-rle' => ['drle'], + 'image/dpx' => ['dpx'], + 'image/emf' => ['emf'], + 'image/fax-g3' => ['g3'], + 'image/fits' => ['fits', 'fit', 'fts'], + 'image/g3fax' => ['g3'], + 'image/gif' => ['gif'], + 'image/heic' => ['heic', 'heif', 'hif'], + 'image/heic-sequence' => ['heics', 'heic', 'heif', 'hif'], + 'image/heif' => ['heif', 'heic', 'hif'], + 'image/heif-sequence' => ['heifs', 'heic', 'heif', 'hif'], + 'image/hej2k' => ['hej2'], + 'image/hsj2' => ['hsj2'], + 'image/ico' => ['ico'], + 'image/icon' => ['ico'], + 'image/ief' => ['ief'], + 'image/jls' => ['jls'], + 'image/jp2' => ['jp2', 'jpg2'], + 'image/jpeg' => ['jpg', 'jpeg', 'jpe', 'jfif'], + 'image/jpeg2000' => ['jp2', 'jpg2'], + 'image/jpeg2000-image' => ['jp2', 'jpg2'], + 'image/jph' => ['jph'], + 'image/jphc' => ['jhc'], + 'image/jpm' => ['jpm', 'jpgm'], + 'image/jpx' => ['jpx', 'jpf'], + 'image/jxl' => ['jxl'], + 'image/jxr' => ['jxr', 'hdp', 'wdp'], + 'image/jxra' => ['jxra'], + 'image/jxrs' => ['jxrs'], + 'image/jxs' => ['jxs'], + 'image/jxsc' => ['jxsc'], + 'image/jxsi' => ['jxsi'], + 'image/jxss' => ['jxss'], + 'image/ktx' => ['ktx'], + 'image/ktx2' => ['ktx2'], + 'image/openraster' => ['ora'], + 'image/pdf' => ['pdf'], + 'image/photoshop' => ['psd'], + 'image/pjpeg' => ['jpg', 'jpeg', 'jpe', 'jfif'], + 'image/png' => ['png'], + 'image/prs.btif' => ['btif', 'btf'], + 'image/prs.pti' => ['pti'], + 'image/psd' => ['psd'], + 'image/qoi' => ['qoi'], + 'image/rle' => ['rle'], + 'image/sgi' => ['sgi'], + 'image/svg' => ['svg'], + 'image/svg+xml' => ['svg', 'svgz'], + 'image/svg+xml-compressed' => ['svgz', 'svg.gz'], + 'image/t38' => ['t38'], + 'image/targa' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'image/tga' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'image/tiff' => ['tif', 'tiff'], + 'image/tiff-fx' => ['tfx'], + 'image/vnd.adobe.photoshop' => ['psd'], + 'image/vnd.airzip.accelerator.azv' => ['azv'], + 'image/vnd.dece.graphic' => ['uvi', 'uvvi', 'uvg', 'uvvg'], + 'image/vnd.djvu' => ['djvu', 'djv'], + 'image/vnd.djvu+multipage' => ['djvu', 'djv'], + 'image/vnd.dvb.subtitle' => ['sub'], + 'image/vnd.dwg' => ['dwg'], + 'image/vnd.dxf' => ['dxf'], + 'image/vnd.fastbidsheet' => ['fbs'], + 'image/vnd.fpx' => ['fpx'], + 'image/vnd.fst' => ['fst'], + 'image/vnd.fujixerox.edmics-mmr' => ['mmr'], + 'image/vnd.fujixerox.edmics-rlc' => ['rlc'], + 'image/vnd.microsoft.icon' => ['ico'], + 'image/vnd.mozilla.apng' => ['apng', 'png'], + 'image/vnd.ms-dds' => ['dds'], + 'image/vnd.ms-modi' => ['mdi'], + 'image/vnd.ms-photo' => ['wdp', 'jxr', 'hdp'], + 'image/vnd.net-fpx' => ['npx'], + 'image/vnd.pco.b16' => ['b16'], + 'image/vnd.rn-realpix' => ['rp'], + 'image/vnd.tencent.tap' => ['tap'], + 'image/vnd.valve.source.texture' => ['vtf'], + 'image/vnd.wap.wbmp' => ['wbmp'], + 'image/vnd.xiff' => ['xif'], + 'image/vnd.zbrush.pcx' => ['pcx'], + 'image/webp' => ['webp'], + 'image/wmf' => ['wmf'], + 'image/x-3ds' => ['3ds'], + 'image/x-adobe-dng' => ['dng'], + 'image/x-applix-graphics' => ['ag'], + 'image/x-bmp' => ['bmp', 'dib'], + 'image/x-bzeps' => ['eps.bz2', 'epsi.bz2', 'epsf.bz2'], + 'image/x-canon-cr2' => ['cr2'], + 'image/x-canon-cr3' => ['cr3'], + 'image/x-canon-crw' => ['crw'], + 'image/x-cdr' => ['cdr'], + 'image/x-cmu-raster' => ['ras'], + 'image/x-cmx' => ['cmx'], + 'image/x-compressed-xcf' => ['xcf.gz', 'xcf.bz2'], + 'image/x-dds' => ['dds'], + 'image/x-djvu' => ['djvu', 'djv'], + 'image/x-emf' => ['emf'], + 'image/x-eps' => ['eps', 'epsi', 'epsf'], + 'image/x-exr' => ['exr'], + 'image/x-fits' => ['fits', 'fit', 'fts'], + 'image/x-fpx' => ['fpx'], + 'image/x-freehand' => ['fh', 'fhc', 'fh4', 'fh5', 'fh7'], + 'image/x-fuji-raf' => ['raf'], + 'image/x-gimp-gbr' => ['gbr'], + 'image/x-gimp-gih' => ['gih'], + 'image/x-gimp-pat' => ['pat'], + 'image/x-gzeps' => ['eps.gz', 'epsi.gz', 'epsf.gz'], + 'image/x-icb' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'image/x-icns' => ['icns'], + 'image/x-ico' => ['ico'], + 'image/x-icon' => ['ico'], + 'image/x-iff' => ['iff', 'ilbm', 'lbm'], + 'image/x-ilbm' => ['iff', 'ilbm', 'lbm'], + 'image/x-jng' => ['jng'], + 'image/x-jp2-codestream' => ['j2c', 'j2k', 'jpc'], + 'image/x-jpeg2000-image' => ['jp2', 'jpg2'], + 'image/x-kiss-cel' => ['cel', 'kcf'], + 'image/x-kodak-dcr' => ['dcr'], + 'image/x-kodak-k25' => ['k25'], + 'image/x-kodak-kdc' => ['kdc'], + 'image/x-lwo' => ['lwo', 'lwob'], + 'image/x-lws' => ['lws'], + 'image/x-macpaint' => ['pntg'], + 'image/x-minolta-mrw' => ['mrw'], + 'image/x-mrsid-image' => ['sid'], + 'image/x-ms-bmp' => ['bmp', 'dib'], + 'image/x-msod' => ['msod'], + 'image/x-nikon-nef' => ['nef'], + 'image/x-nikon-nrw' => ['nrw'], + 'image/x-olympus-orf' => ['orf'], + 'image/x-panasonic-raw' => ['raw'], + 'image/x-panasonic-raw2' => ['rw2'], + 'image/x-panasonic-rw' => ['raw'], + 'image/x-panasonic-rw2' => ['rw2'], + 'image/x-pcx' => ['pcx'], + 'image/x-pentax-pef' => ['pef'], + 'image/x-pfm' => ['pfm'], + 'image/x-photo-cd' => ['pcd'], + 'image/x-photoshop' => ['psd'], + 'image/x-pict' => ['pic', 'pct', 'pict', 'pict1', 'pict2'], + 'image/x-portable-anymap' => ['pnm'], + 'image/x-portable-bitmap' => ['pbm'], + 'image/x-portable-graymap' => ['pgm'], + 'image/x-portable-pixmap' => ['ppm'], + 'image/x-psd' => ['psd'], + 'image/x-pxr' => ['pxr'], + 'image/x-quicktime' => ['qtif', 'qif'], + 'image/x-rgb' => ['rgb'], + 'image/x-sct' => ['sct'], + 'image/x-sgi' => ['sgi'], + 'image/x-sigma-x3f' => ['x3f'], + 'image/x-skencil' => ['sk', 'sk1'], + 'image/x-sony-arw' => ['arw'], + 'image/x-sony-sr2' => ['sr2'], + 'image/x-sony-srf' => ['srf'], + 'image/x-sun-raster' => ['sun'], + 'image/x-targa' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'image/x-tga' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'image/x-win-bitmap' => ['cur'], + 'image/x-win-metafile' => ['wmf'], + 'image/x-wmf' => ['wmf'], + 'image/x-xbitmap' => ['xbm'], + 'image/x-xcf' => ['xcf'], + 'image/x-xfig' => ['fig'], + 'image/x-xpixmap' => ['xpm'], + 'image/x-xpm' => ['xpm'], + 'image/x-xwindowdump' => ['xwd'], + 'image/x.djvu' => ['djvu', 'djv'], + 'message/disposition-notification' => ['disposition-notification'], + 'message/global' => ['u8msg'], + 'message/global-delivery-status' => ['u8dsn'], + 'message/global-disposition-notification' => ['u8mdn'], + 'message/global-headers' => ['u8hdr'], + 'message/rfc822' => ['eml', 'mime'], + 'message/vnd.wfa.wsc' => ['wsc'], + 'model/3mf' => ['3mf'], + 'model/gltf+json' => ['gltf'], + 'model/gltf-binary' => ['glb'], + 'model/iges' => ['igs', 'iges'], + 'model/jt' => ['jt'], + 'model/mesh' => ['msh', 'mesh', 'silo'], + 'model/mtl' => ['mtl'], + 'model/obj' => ['obj'], + 'model/prc' => ['prc'], + 'model/step' => ['step', 'stp'], + 'model/step+xml' => ['stpx'], + 'model/step+zip' => ['stpz'], + 'model/step-xml+zip' => ['stpxz'], + 'model/stl' => ['stl'], + 'model/u3d' => ['u3d'], + 'model/vnd.bary' => ['bary'], + 'model/vnd.cld' => ['cld'], + 'model/vnd.collada+xml' => ['dae'], + 'model/vnd.dwf' => ['dwf'], + 'model/vnd.gdl' => ['gdl'], + 'model/vnd.gtw' => ['gtw'], + 'model/vnd.mts' => ['mts'], + 'model/vnd.opengex' => ['ogex'], + 'model/vnd.parasolid.transmit.binary' => ['x_b'], + 'model/vnd.parasolid.transmit.text' => ['x_t'], + 'model/vnd.pytha.pyox' => ['pyo', 'pyox'], + 'model/vnd.sap.vds' => ['vds'], + 'model/vnd.usda' => ['usda'], + 'model/vnd.usdz+zip' => ['usdz'], + 'model/vnd.valve.source.compiled-map' => ['bsp'], + 'model/vnd.vtu' => ['vtu'], + 'model/vrml' => ['wrl', 'vrml', 'vrm'], + 'model/x.stl-ascii' => ['stl'], + 'model/x.stl-binary' => ['stl'], + 'model/x3d+binary' => ['x3db', 'x3dbz'], + 'model/x3d+fastinfoset' => ['x3db'], + 'model/x3d+vrml' => ['x3dv', 'x3dvz'], + 'model/x3d+xml' => ['x3d', 'x3dz'], + 'model/x3d-vrml' => ['x3dv'], + 'text/cache-manifest' => ['appcache', 'manifest'], + 'text/calendar' => ['ics', 'ifb', 'vcs', 'icalendar'], + 'text/coffeescript' => ['coffee', 'litcoffee'], + 'text/crystal' => ['cr'], + 'text/css' => ['css'], + 'text/csv' => ['csv'], + 'text/csv-schema' => ['csvs'], + 'text/directory' => ['vcard', 'vcf', 'vct', 'gcrd'], + 'text/ecmascript' => ['es'], + 'text/gedcom' => ['ged', 'gedcom'], + 'text/google-video-pointer' => ['gvp'], + 'text/html' => ['html', 'htm', 'shtml'], + 'text/ico' => ['ico'], + 'text/jade' => ['jade'], + 'text/javascript' => ['js', 'mjs', 'jsm'], + 'text/jscript' => ['js', 'jsm', 'mjs'], + 'text/jscript.encode' => ['jse'], + 'text/jsx' => ['jsx'], + 'text/julia' => ['jl'], + 'text/less' => ['less'], + 'text/markdown' => ['md', 'markdown', 'mkd'], + 'text/mathml' => ['mml'], + 'text/mdx' => ['mdx'], + 'text/n3' => ['n3'], + 'text/org' => ['org'], + 'text/plain' => ['txt', 'text', 'conf', 'def', 'list', 'log', 'in', 'ini', 'asc'], + 'text/prs.lines.tag' => ['dsc'], + 'text/rdf' => ['rdf', 'rdfs', 'owl'], + 'text/richtext' => ['rtx'], + 'text/rss' => ['rss'], + 'text/rtf' => ['rtf'], + 'text/rust' => ['rs'], + 'text/sgml' => ['sgml', 'sgm'], + 'text/shex' => ['shex'], + 'text/slim' => ['slim', 'slm'], + 'text/spdx' => ['spdx'], + 'text/spreadsheet' => ['sylk', 'slk'], + 'text/stylus' => ['stylus', 'styl'], + 'text/tab-separated-values' => ['tsv'], + 'text/tcl' => ['tcl', 'tk'], + 'text/troff' => ['t', 'tr', 'roff', 'man', 'me', 'ms'], + 'text/turtle' => ['ttl'], + 'text/uri-list' => ['uri', 'uris', 'urls'], + 'text/vbs' => ['vbs'], + 'text/vbscript' => ['vbs'], + 'text/vbscript.encode' => ['vbe'], + 'text/vcard' => ['vcard', 'vcf', 'vct', 'gcrd'], + 'text/vnd.curl' => ['curl'], + 'text/vnd.curl.dcurl' => ['dcurl'], + 'text/vnd.curl.mcurl' => ['mcurl'], + 'text/vnd.curl.scurl' => ['scurl'], + 'text/vnd.dvb.subtitle' => ['sub'], + 'text/vnd.familysearch.gedcom' => ['ged', 'gedcom'], + 'text/vnd.fly' => ['fly'], + 'text/vnd.fmi.flexstor' => ['flx'], + 'text/vnd.graphviz' => ['gv', 'dot'], + 'text/vnd.in3d.3dml' => ['3dml'], + 'text/vnd.in3d.spot' => ['spot'], + 'text/vnd.qt.linguist' => ['ts'], + 'text/vnd.rn-realtext' => ['rt'], + 'text/vnd.senx.warpscript' => ['mc2'], + 'text/vnd.sun.j2me.app-descriptor' => ['jad'], + 'text/vnd.trolltech.linguist' => ['ts'], + 'text/vnd.wap.wml' => ['wml'], + 'text/vnd.wap.wmlscript' => ['wmls'], + 'text/vtt' => ['vtt'], + 'text/wgsl' => ['wgsl'], + 'text/x-adasrc' => ['adb', 'ads'], + 'text/x-asm' => ['s', 'asm'], + 'text/x-basic' => ['bas'], + 'text/x-bibtex' => ['bib'], + 'text/x-blueprint' => ['blp'], + 'text/x-c' => ['c', 'cc', 'cxx', 'cpp', 'h', 'hh', 'dic'], + 'text/x-c++hdr' => ['hh', 'hp', 'hpp', 'h++', 'hxx'], + 'text/x-c++src' => ['cpp', 'cxx', 'cc', 'C', 'c++'], + 'text/x-chdr' => ['h'], + 'text/x-cmake' => ['cmake'], + 'text/x-cobol' => ['cbl', 'cob'], + 'text/x-comma-separated-values' => ['csv'], + 'text/x-common-lisp' => ['asd', 'fasl', 'lisp', 'ros'], + 'text/x-component' => ['htc'], + 'text/x-crystal' => ['cr'], + 'text/x-csharp' => ['cs'], + 'text/x-csrc' => ['c'], + 'text/x-csv' => ['csv'], + 'text/x-cython' => ['pxd', 'pxi', 'pyx'], + 'text/x-dart' => ['dart'], + 'text/x-dbus-service' => ['service'], + 'text/x-dcl' => ['dcl'], + 'text/x-devicetree-binary' => ['dtb'], + 'text/x-devicetree-source' => ['dts', 'dtsi'], + 'text/x-diff' => ['diff', 'patch'], + 'text/x-dsl' => ['dsl'], + 'text/x-dsrc' => ['d', 'di'], + 'text/x-dtd' => ['dtd'], + 'text/x-eiffel' => ['e', 'eif'], + 'text/x-elixir' => ['ex', 'exs'], + 'text/x-emacs-lisp' => ['el'], + 'text/x-erlang' => ['erl'], + 'text/x-fish' => ['fish'], + 'text/x-fortran' => ['f', 'for', 'f77', 'f90', 'f95'], + 'text/x-gcode-gx' => ['gx'], + 'text/x-genie' => ['gs'], + 'text/x-gettext-translation' => ['po'], + 'text/x-gettext-translation-template' => ['pot'], + 'text/x-gherkin' => ['feature'], + 'text/x-go' => ['go'], + 'text/x-google-video-pointer' => ['gvp'], + 'text/x-gradle' => ['gradle'], + 'text/x-groovy' => ['groovy', 'gvy', 'gy', 'gsh'], + 'text/x-handlebars-template' => ['hbs'], + 'text/x-haskell' => ['hs'], + 'text/x-idl' => ['idl'], + 'text/x-imelody' => ['imy', 'ime'], + 'text/x-iptables' => ['iptables'], + 'text/x-java' => ['java'], + 'text/x-java-source' => ['java'], + 'text/x-kaitai-struct' => ['ksy'], + 'text/x-kotlin' => ['kt'], + 'text/x-ldif' => ['ldif'], + 'text/x-lilypond' => ['ly'], + 'text/x-literate-haskell' => ['lhs'], + 'text/x-log' => ['log'], + 'text/x-lua' => ['lua'], + 'text/x-lyx' => ['lyx'], + 'text/x-makefile' => ['mk', 'mak'], + 'text/x-markdown' => ['md', 'mkd', 'markdown'], + 'text/x-matlab' => ['m'], + 'text/x-microdvd' => ['sub'], + 'text/x-moc' => ['moc'], + 'text/x-modelica' => ['mo'], + 'text/x-mof' => ['mof'], + 'text/x-mpl2' => ['mpl'], + 'text/x-mpsub' => ['sub'], + 'text/x-mrml' => ['mrml', 'mrl'], + 'text/x-ms-regedit' => ['reg'], + 'text/x-mup' => ['mup', 'not'], + 'text/x-nfo' => ['nfo'], + 'text/x-nim' => ['nim'], + 'text/x-nimscript' => ['nims', 'nimble'], + 'text/x-nix' => ['nix'], + 'text/x-nu' => ['nu'], + 'text/x-objc++src' => ['mm'], + 'text/x-objcsrc' => ['m'], + 'text/x-ocaml' => ['ml', 'mli'], + 'text/x-ocl' => ['ocl'], + 'text/x-octave' => ['m'], + 'text/x-ooc' => ['ooc'], + 'text/x-opencl-src' => ['cl'], + 'text/x-opml' => ['opml'], + 'text/x-opml+xml' => ['opml'], + 'text/x-org' => ['org'], + 'text/x-pascal' => ['p', 'pas'], + 'text/x-patch' => ['diff', 'patch'], + 'text/x-perl' => ['pl', 'PL', 'pm', 'al', 'perl', 'pod', 't'], + 'text/x-po' => ['po'], + 'text/x-pot' => ['pot'], + 'text/x-processing' => ['pde'], + 'text/x-python' => ['py', 'wsgi'], + 'text/x-python2' => ['py', 'py2'], + 'text/x-python3' => ['py', 'py3', 'pyi'], + 'text/x-qml' => ['qml', 'qmltypes', 'qmlproject'], + 'text/x-reject' => ['rej'], + 'text/x-rpm-spec' => ['spec'], + 'text/x-rst' => ['rst'], + 'text/x-sagemath' => ['sage'], + 'text/x-sass' => ['sass'], + 'text/x-scala' => ['scala', 'sc'], + 'text/x-scheme' => ['scm', 'ss'], + 'text/x-scss' => ['scss'], + 'text/x-setext' => ['etx'], + 'text/x-sfv' => ['sfv'], + 'text/x-sh' => ['sh'], + 'text/x-sql' => ['sql'], + 'text/x-ssa' => ['ssa', 'ass'], + 'text/x-subviewer' => ['sub'], + 'text/x-suse-ymp' => ['ymp'], + 'text/x-svhdr' => ['svh'], + 'text/x-svsrc' => ['sv'], + 'text/x-systemd-unit' => ['automount', 'device', 'mount', 'path', 'scope', 'service', 'slice', 'socket', 'swap', 'target', 'timer'], + 'text/x-tcl' => ['tcl', 'tk'], + 'text/x-tex' => ['tex', 'ltx', 'sty', 'cls', 'dtx', 'ins', 'latex'], + 'text/x-texinfo' => ['texi', 'texinfo'], + 'text/x-troff' => ['tr', 'roff', 't'], + 'text/x-troff-me' => ['me'], + 'text/x-troff-mm' => ['mm'], + 'text/x-troff-ms' => ['ms'], + 'text/x-twig' => ['twig'], + 'text/x-txt2tags' => ['t2t'], + 'text/x-typst' => ['typ'], + 'text/x-uil' => ['uil'], + 'text/x-uuencode' => ['uu', 'uue'], + 'text/x-vala' => ['vala', 'vapi'], + 'text/x-vb' => ['vb'], + 'text/x-vcalendar' => ['vcs', 'ics', 'ifb', 'icalendar'], + 'text/x-vcard' => ['vcf', 'vcard', 'vct', 'gcrd'], + 'text/x-verilog' => ['v'], + 'text/x-vhdl' => ['vhd', 'vhdl'], + 'text/x-xmi' => ['xmi'], + 'text/x-xslfo' => ['fo', 'xslfo'], + 'text/x-yaml' => ['yaml', 'yml'], + 'text/x.gcode' => ['gcode'], + 'text/xml' => ['xml', 'xbl', 'xsd', 'rng'], + 'text/xml-external-parsed-entity' => ['ent'], + 'text/yaml' => ['yaml', 'yml'], + 'video/3gp' => ['3gp', '3gpp', '3ga'], + 'video/3gpp' => ['3gp', '3gpp', '3ga'], + 'video/3gpp-encrypted' => ['3gp', '3gpp', '3ga'], + 'video/3gpp2' => ['3g2', '3gp2', '3gpp2'], + 'video/annodex' => ['axv'], + 'video/avi' => ['avi', 'avf', 'divx'], + 'video/divx' => ['avi', 'avf', 'divx'], + 'video/dv' => ['dv'], + 'video/fli' => ['fli', 'flc'], + 'video/flv' => ['flv'], + 'video/h261' => ['h261'], + 'video/h263' => ['h263'], + 'video/h264' => ['h264'], + 'video/iso.segment' => ['m4s'], + 'video/jpeg' => ['jpgv'], + 'video/jpm' => ['jpm', 'jpgm'], + 'video/mj2' => ['mj2', 'mjp2'], + 'video/mp2t' => ['ts', 'm2t', 'm2ts', 'mts', 'cpi', 'clpi', 'mpl', 'mpls', 'bdm', 'bdmv'], + 'video/mp4' => ['mp4', 'mp4v', 'mpg4', 'm4v', 'f4v', 'lrv'], + 'video/mp4v-es' => ['mp4', 'm4v', 'f4v', 'lrv'], + 'video/mpeg' => ['mpeg', 'mpg', 'mpe', 'm1v', 'm2v', 'mp2', 'vob'], + 'video/mpeg-system' => ['mpeg', 'mpg', 'mp2', 'mpe', 'vob'], + 'video/mpg4' => ['mpg4'], + 'video/msvideo' => ['avi', 'avf', 'divx'], + 'video/ogg' => ['ogv', 'ogg'], + 'video/quicktime' => ['mov', 'qt', 'moov', 'qtvr'], + 'video/vivo' => ['viv', 'vivo'], + 'video/vnd.avi' => ['avi', 'avf', 'divx'], + 'video/vnd.dece.hd' => ['uvh', 'uvvh'], + 'video/vnd.dece.mobile' => ['uvm', 'uvvm'], + 'video/vnd.dece.pd' => ['uvp', 'uvvp'], + 'video/vnd.dece.sd' => ['uvs', 'uvvs'], + 'video/vnd.dece.video' => ['uvv', 'uvvv'], + 'video/vnd.divx' => ['avi', 'avf', 'divx'], + 'video/vnd.dvb.file' => ['dvb'], + 'video/vnd.fvt' => ['fvt'], + 'video/vnd.mpegurl' => ['mxu', 'm4u', 'm1u'], + 'video/vnd.ms-playready.media.pyv' => ['pyv'], + 'video/vnd.radgamettools.bink' => ['bik', 'bk2'], + 'video/vnd.radgamettools.smacker' => ['smk'], + 'video/vnd.rn-realvideo' => ['rv', 'rvx'], + 'video/vnd.uvvu.mp4' => ['uvu', 'uvvu'], + 'video/vnd.vivo' => ['viv', 'vivo'], + 'video/vnd.youtube.yt' => ['yt'], + 'video/webm' => ['webm'], + 'video/x-anim' => ['anim1', 'anim2', 'anim3', 'anim4', 'anim5', 'anim6', 'anim7', 'anim8', 'anim9', 'animj'], + 'video/x-annodex' => ['axv'], + 'video/x-avi' => ['avi', 'avf', 'divx'], + 'video/x-f4v' => ['f4v'], + 'video/x-fli' => ['fli', 'flc'], + 'video/x-flic' => ['fli', 'flc'], + 'video/x-flv' => ['flv'], + 'video/x-javafx' => ['fxm'], + 'video/x-m4v' => ['m4v', 'mp4', 'f4v', 'lrv'], + 'video/x-matroska' => ['mkv', 'mk3d', 'mks'], + 'video/x-matroska-3d' => ['mk3d'], + 'video/x-mjpeg' => ['mjpeg', 'mjpg'], + 'video/x-mng' => ['mng'], + 'video/x-mpeg' => ['mpeg', 'mpg', 'mp2', 'mpe', 'vob'], + 'video/x-mpeg-system' => ['mpeg', 'mpg', 'mp2', 'mpe', 'vob'], + 'video/x-mpeg2' => ['mpeg', 'mpg', 'mp2', 'mpe', 'vob'], + 'video/x-mpegurl' => ['m1u', 'm4u', 'mxu'], + 'video/x-ms-asf' => ['asf', 'asx'], + 'video/x-ms-asf-plugin' => ['asf'], + 'video/x-ms-vob' => ['vob'], + 'video/x-ms-wax' => ['asx', 'wax', 'wvx', 'wmx'], + 'video/x-ms-wm' => ['wm', 'asf'], + 'video/x-ms-wmv' => ['wmv'], + 'video/x-ms-wmx' => ['wmx', 'asx', 'wax', 'wvx'], + 'video/x-ms-wvx' => ['wvx', 'asx', 'wax', 'wmx'], + 'video/x-msvideo' => ['avi', 'avf', 'divx'], + 'video/x-nsv' => ['nsv'], + 'video/x-ogg' => ['ogv', 'ogg'], + 'video/x-ogm' => ['ogm'], + 'video/x-ogm+ogg' => ['ogm'], + 'video/x-real-video' => ['rv', 'rvx'], + 'video/x-sgi-movie' => ['movie'], + 'video/x-smv' => ['smv'], + 'video/x-theora' => ['ogg'], + 'video/x-theora+ogg' => ['ogg'], + 'x-conference/x-cooltalk' => ['ice'], + 'x-epoc/x-sisx-app' => ['sisx'], + 'zz-application/zz-winassoc-123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'], + 'zz-application/zz-winassoc-cab' => ['cab'], + 'zz-application/zz-winassoc-cdr' => ['cdr'], + 'zz-application/zz-winassoc-doc' => ['doc'], + 'zz-application/zz-winassoc-hlp' => ['hlp'], + 'zz-application/zz-winassoc-mdb' => ['mdb'], + 'zz-application/zz-winassoc-uu' => ['uue'], + 'zz-application/zz-winassoc-xls' => ['xls', 'xlc', 'xll', 'xlm', 'xlw', 'xla', 'xlt', 'xld'], + ]; + + private const REVERSE_MAP = [ + '123' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'], + '1km' => ['application/vnd.1000minds.decision-model+xml'], + '32x' => ['application/x-genesis-32x-rom'], + '3dml' => ['text/vnd.in3d.3dml'], + '3ds' => ['application/x-nintendo-3ds-rom', 'image/x-3ds'], + '3dsx' => ['application/x-nintendo-3ds-executable'], + '3g2' => ['audio/3gpp2', 'video/3gpp2'], + '3ga' => ['audio/3gpp', 'audio/3gpp-encrypted', 'audio/x-rn-3gpp-amr', 'audio/x-rn-3gpp-amr-encrypted', 'audio/x-rn-3gpp-amr-wb', 'audio/x-rn-3gpp-amr-wb-encrypted', 'video/3gp', 'video/3gpp', 'video/3gpp-encrypted'], + '3gp' => ['audio/3gpp', 'audio/3gpp-encrypted', 'audio/x-rn-3gpp-amr', 'audio/x-rn-3gpp-amr-encrypted', 'audio/x-rn-3gpp-amr-wb', 'audio/x-rn-3gpp-amr-wb-encrypted', 'video/3gp', 'video/3gpp', 'video/3gpp-encrypted'], + '3gp2' => ['audio/3gpp2', 'video/3gpp2'], + '3gpp' => ['audio/3gpp', 'audio/3gpp-encrypted', 'audio/x-rn-3gpp-amr', 'audio/x-rn-3gpp-amr-encrypted', 'audio/x-rn-3gpp-amr-wb', 'audio/x-rn-3gpp-amr-wb-encrypted', 'video/3gp', 'video/3gpp', 'video/3gpp-encrypted'], + '3gpp2' => ['audio/3gpp2', 'video/3gpp2'], + '3mf' => ['application/vnd.ms-3mfdocument', 'model/3mf'], + '602' => ['application/x-t602'], + '669' => ['audio/x-mod'], + '7z' => ['application/x-7z-compressed'], + '7z.001' => ['application/x-7z-compressed'], + 'C' => ['text/x-c++src'], + 'PAR2' => ['application/x-par2'], + 'PL' => ['application/x-perl', 'text/x-perl'], + 'Z' => ['application/x-compress'], + 'a' => ['application/x-archive'], + 'a26' => ['application/x-atari-2600-rom'], + 'a78' => ['application/x-atari-7800-rom'], + 'aa' => ['audio/vnd.audible', 'audio/x-pn-audibleaudio'], + 'aab' => ['application/x-authorware-bin'], + 'aac' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts'], + 'aam' => ['application/x-authorware-map'], + 'aas' => ['application/x-authorware-seg'], + 'aax' => ['audio/vnd.audible', 'audio/vnd.audible.aax', 'audio/x-pn-audibleaudio'], + 'aaxc' => ['audio/vnd.audible.aaxc'], + 'abw' => ['application/x-abiword'], + 'abw.CRASHED' => ['application/x-abiword'], + 'abw.gz' => ['application/x-abiword'], + 'ac' => ['application/pkix-attr-cert', 'application/vnd.nokia.n-gage.ac+xml'], + 'ac3' => ['audio/ac3'], + 'acc' => ['application/vnd.americandynamics.acc'], + 'ace' => ['application/x-ace', 'application/x-ace-compressed'], + 'acu' => ['application/vnd.acucobol'], + 'acutc' => ['application/vnd.acucorp'], + 'adb' => ['text/x-adasrc'], + 'adf' => ['application/x-amiga-disk-format'], + 'adp' => ['audio/adpcm'], + 'ads' => ['text/x-adasrc'], + 'adts' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts'], + 'aep' => ['application/vnd.audiograph'], + 'afm' => ['application/x-font-afm', 'application/x-font-type1'], + 'afp' => ['application/vnd.ibm.modcap'], + 'ag' => ['image/x-applix-graphics'], + 'agb' => ['application/x-gba-rom'], + 'age' => ['application/vnd.age'], + 'ahead' => ['application/vnd.ahead.space'], + 'ai' => ['application/illustrator', 'application/postscript', 'application/vnd.adobe.illustrator'], + 'aif' => ['audio/x-aiff'], + 'aifc' => ['audio/x-aifc', 'audio/x-aiff', 'audio/x-aiffc'], + 'aiff' => ['audio/x-aiff'], + 'aiffc' => ['audio/x-aifc', 'audio/x-aiffc'], + 'air' => ['application/vnd.adobe.air-application-installer-package+zip'], + 'ait' => ['application/vnd.dvb.ait'], + 'al' => ['application/x-perl', 'text/x-perl'], + 'alz' => ['application/x-alz'], + 'ami' => ['application/vnd.amiga.ami'], + 'aml' => ['application/automationml-aml+xml'], + 'amlx' => ['application/automationml-amlx+zip'], + 'amr' => ['audio/amr', 'audio/amr-encrypted'], + 'amz' => ['audio/x-amzxml'], + 'ani' => ['application/x-navi-animation'], + 'anim1' => ['video/x-anim'], + 'anim2' => ['video/x-anim'], + 'anim3' => ['video/x-anim'], + 'anim4' => ['video/x-anim'], + 'anim5' => ['video/x-anim'], + 'anim6' => ['video/x-anim'], + 'anim7' => ['video/x-anim'], + 'anim8' => ['video/x-anim'], + 'anim9' => ['video/x-anim'], + 'animj' => ['video/x-anim'], + 'anx' => ['application/annodex', 'application/x-annodex'], + 'ape' => ['audio/x-ape'], + 'apk' => ['application/vnd.android.package-archive'], + 'apng' => ['image/apng', 'image/vnd.mozilla.apng'], + 'appcache' => ['text/cache-manifest'], + 'appimage' => ['application/vnd.appimage', 'application/x-iso9660-appimage'], + 'appinstaller' => ['application/appinstaller'], + 'application' => ['application/x-ms-application'], + 'appx' => ['application/appx'], + 'appxbundle' => ['application/appxbundle'], + 'apr' => ['application/vnd.lotus-approach'], + 'ar' => ['application/x-archive'], + 'arc' => ['application/x-freearc'], + 'arj' => ['application/x-arj'], + 'arw' => ['image/x-sony-arw'], + 'as' => ['application/x-applix-spreadsheet'], + 'asar' => ['application/x-asar'], + 'asc' => ['application/pgp', 'application/pgp-encrypted', 'application/pgp-keys', 'application/pgp-signature', 'text/plain'], + 'asd' => ['text/x-common-lisp'], + 'asf' => ['application/vnd.ms-asf', 'video/x-ms-asf', 'video/x-ms-asf-plugin', 'video/x-ms-wm'], + 'asice' => ['application/vnd.etsi.asic-e+zip'], + 'asm' => ['text/x-asm'], + 'aso' => ['application/vnd.accpac.simply.aso'], + 'asp' => ['application/x-asp'], + 'ass' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts', 'text/x-ssa'], + 'astc' => ['image/astc'], + 'asx' => ['application/x-ms-asx', 'audio/x-ms-asx', 'video/x-ms-asf', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'], + 'atc' => ['application/vnd.acucorp'], + 'atom' => ['application/atom+xml'], + 'atomcat' => ['application/atomcat+xml'], + 'atomdeleted' => ['application/atomdeleted+xml'], + 'atomsvc' => ['application/atomsvc+xml'], + 'atx' => ['application/vnd.antix.game-component'], + 'au' => ['audio/basic'], + 'automount' => ['text/x-systemd-unit'], + 'avci' => ['image/avci'], + 'avcs' => ['image/avcs'], + 'avf' => ['video/avi', 'video/divx', 'video/msvideo', 'video/vnd.avi', 'video/vnd.divx', 'video/x-avi', 'video/x-msvideo'], + 'avi' => ['video/avi', 'video/divx', 'video/msvideo', 'video/vnd.avi', 'video/vnd.divx', 'video/x-avi', 'video/x-msvideo'], + 'avif' => ['image/avif', 'image/avif-sequence'], + 'avifs' => ['image/avif', 'image/avif-sequence'], + 'aw' => ['application/applixware', 'application/x-applix-word'], + 'awb' => ['audio/amr-wb', 'audio/amr-wb-encrypted'], + 'awk' => ['application/x-awk'], + 'axa' => ['audio/annodex', 'audio/x-annodex'], + 'axv' => ['video/annodex', 'video/x-annodex'], + 'azf' => ['application/vnd.airzip.filesecure.azf'], + 'azs' => ['application/vnd.airzip.filesecure.azs'], + 'azv' => ['image/vnd.airzip.accelerator.azv'], + 'azw' => ['application/vnd.amazon.ebook'], + 'azw3' => ['application/vnd.amazon.mobi8-ebook', 'application/x-mobi8-ebook'], + 'b16' => ['image/vnd.pco.b16'], + 'bak' => ['application/x-trash'], + 'bary' => ['model/vnd.bary'], + 'bas' => ['text/x-basic'], + 'bat' => ['application/bat', 'application/x-bat', 'application/x-msdownload'], + 'bcpio' => ['application/x-bcpio'], + 'bdf' => ['application/x-font-bdf'], + 'bdm' => ['application/vnd.syncml.dm+wbxml', 'video/mp2t'], + 'bdmv' => ['video/mp2t'], + 'bdo' => ['application/vnd.nato.bindingdataobject+xml'], + 'bdoc' => ['application/bdoc', 'application/x-bdoc'], + 'bed' => ['application/vnd.realvnc.bed'], + 'bh2' => ['application/vnd.fujitsu.oasysprs'], + 'bib' => ['text/x-bibtex'], + 'bik' => ['video/vnd.radgamettools.bink'], + 'bin' => ['application/octet-stream'], + 'bk2' => ['video/vnd.radgamettools.bink'], + 'blb' => ['application/x-blorb'], + 'blend' => ['application/x-blender'], + 'blender' => ['application/x-blender'], + 'blorb' => ['application/x-blorb'], + 'blp' => ['text/x-blueprint'], + 'bmi' => ['application/vnd.bmi'], + 'bmml' => ['application/vnd.balsamiq.bmml+xml'], + 'bmp' => ['image/bmp', 'image/x-bmp', 'image/x-ms-bmp'], + 'book' => ['application/vnd.framemaker'], + 'box' => ['application/vnd.previewsystems.box'], + 'boz' => ['application/x-bzip2'], + 'bps' => ['application/x-bps-patch'], + 'brk' => ['chemical/x-pdb'], + 'bsdiff' => ['application/x-bsdiff'], + 'bsp' => ['model/vnd.valve.source.compiled-map'], + 'btf' => ['image/prs.btif'], + 'btif' => ['image/prs.btif'], + 'bz' => ['application/bzip2', 'application/x-bzip', 'application/x-bzip1'], + 'bz2' => ['application/x-bz2', 'application/bzip2', 'application/x-bzip', 'application/x-bzip2'], + 'bz3' => ['application/x-bzip3'], + 'c' => ['text/x-c', 'text/x-csrc'], + 'c++' => ['text/x-c++src'], + 'c11amc' => ['application/vnd.cluetrust.cartomobile-config'], + 'c11amz' => ['application/vnd.cluetrust.cartomobile-config-pkg'], + 'c4d' => ['application/vnd.clonk.c4group'], + 'c4f' => ['application/vnd.clonk.c4group'], + 'c4g' => ['application/vnd.clonk.c4group'], + 'c4p' => ['application/vnd.clonk.c4group'], + 'c4u' => ['application/vnd.clonk.c4group'], + 'cab' => ['application/vnd.ms-cab-compressed', 'zz-application/zz-winassoc-cab'], + 'caf' => ['audio/x-caf'], + 'cap' => ['application/pcap', 'application/vnd.tcpdump.pcap', 'application/x-pcap'], + 'car' => ['application/vnd.curl.car'], + 'cat' => ['application/vnd.ms-pki.seccat'], + 'cb7' => ['application/x-cb7', 'application/x-cbr'], + 'cba' => ['application/x-cbr'], + 'cbl' => ['text/x-cobol'], + 'cbor' => ['application/cbor'], + 'cbr' => ['application/vnd.comicbook-rar', 'application/x-cbr'], + 'cbt' => ['application/x-cbr', 'application/x-cbt'], + 'cbz' => ['application/vnd.comicbook+zip', 'application/x-cbr', 'application/x-cbz'], + 'cc' => ['text/x-c', 'text/x-c++src'], + 'cci' => ['application/x-nintendo-3ds-rom'], + 'ccmx' => ['application/x-ccmx'], + 'cco' => ['application/x-cocoa'], + 'cct' => ['application/x-director'], + 'ccxml' => ['application/ccxml+xml'], + 'cdbcmsg' => ['application/vnd.contact.cmsg'], + 'cdf' => ['application/x-netcdf'], + 'cdfx' => ['application/cdfx+xml'], + 'cdi' => ['application/x-discjuggler-cd-image'], + 'cdkey' => ['application/vnd.mediastation.cdkey'], + 'cdmia' => ['application/cdmi-capability'], + 'cdmic' => ['application/cdmi-container'], + 'cdmid' => ['application/cdmi-domain'], + 'cdmio' => ['application/cdmi-object'], + 'cdmiq' => ['application/cdmi-queue'], + 'cdr' => ['application/cdr', 'application/coreldraw', 'application/vnd.corel-draw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'], + 'cdx' => ['chemical/x-cdx'], + 'cdxml' => ['application/vnd.chemdraw+xml'], + 'cdy' => ['application/vnd.cinderella'], + 'cel' => ['image/x-kiss-cel'], + 'cer' => ['application/pkix-cert'], + 'cert' => ['application/x-x509-ca-cert'], + 'cfs' => ['application/x-cfs-compressed'], + 'cgb' => ['application/x-gameboy-color-rom'], + 'cgm' => ['image/cgm'], + 'chat' => ['application/x-chat'], + 'chd' => ['application/x-mame-chd'], + 'chm' => ['application/vnd.ms-htmlhelp', 'application/x-chm'], + 'chrt' => ['application/vnd.kde.kchart', 'application/x-kchart'], + 'cif' => ['chemical/x-cif'], + 'cii' => ['application/vnd.anser-web-certificate-issue-initiation'], + 'cil' => ['application/vnd.ms-artgalry'], + 'cjs' => ['application/node'], + 'cl' => ['text/x-opencl-src'], + 'cla' => ['application/vnd.claymore'], + 'class' => ['application/java', 'application/java-byte-code', 'application/java-vm', 'application/x-java', 'application/x-java-class', 'application/x-java-vm'], + 'cld' => ['model/vnd.cld'], + 'clkk' => ['application/vnd.crick.clicker.keyboard'], + 'clkp' => ['application/vnd.crick.clicker.palette'], + 'clkt' => ['application/vnd.crick.clicker.template'], + 'clkw' => ['application/vnd.crick.clicker.wordbank'], + 'clkx' => ['application/vnd.crick.clicker'], + 'clp' => ['application/x-msclip'], + 'clpi' => ['video/mp2t'], + 'cls' => ['application/x-tex', 'text/x-tex'], + 'cmake' => ['text/x-cmake'], + 'cmc' => ['application/vnd.cosmocaller'], + 'cmdf' => ['chemical/x-cmdf'], + 'cml' => ['chemical/x-cml'], + 'cmp' => ['application/vnd.yellowriver-custom-menu'], + 'cmx' => ['image/x-cmx'], + 'cob' => ['text/x-cobol'], + 'cod' => ['application/vnd.rim.cod'], + 'coffee' => ['application/vnd.coffeescript', 'text/coffeescript'], + 'com' => ['application/x-msdownload'], + 'conf' => ['text/plain'], + 'cpi' => ['video/mp2t'], + 'cpio' => ['application/x-cpio'], + 'cpio.gz' => ['application/x-cpio-compressed'], + 'cpl' => ['application/cpl+xml', 'application/vnd.microsoft.portable-executable', 'application/x-ms-dos-executable', 'application/x-ms-ne-executable', 'application/x-msdownload'], + 'cpp' => ['text/x-c', 'text/x-c++src'], + 'cpt' => ['application/mac-compactpro'], + 'cr' => ['text/crystal', 'text/x-crystal'], + 'cr2' => ['image/x-canon-cr2'], + 'cr3' => ['image/x-canon-cr3'], + 'crd' => ['application/x-mscardfile'], + 'crdownload' => ['application/x-partial-download'], + 'crl' => ['application/pkix-crl'], + 'crt' => ['application/x-x509-ca-cert'], + 'crw' => ['image/x-canon-crw'], + 'crx' => ['application/x-chrome-extension'], + 'cryptonote' => ['application/vnd.rig.cryptonote'], + 'cs' => ['text/x-csharp'], + 'csh' => ['application/x-csh'], + 'csl' => ['application/vnd.citationstyles.style+xml'], + 'csml' => ['chemical/x-csml'], + 'cso' => ['application/x-compressed-iso'], + 'csp' => ['application/vnd.commonspace'], + 'css' => ['text/css'], + 'cst' => ['application/x-director'], + 'csv' => ['text/csv', 'application/csv', 'text/x-comma-separated-values', 'text/x-csv'], + 'csvs' => ['text/csv-schema'], + 'cu' => ['application/cu-seeme'], + 'cue' => ['application/x-cue'], + 'cur' => ['image/x-win-bitmap'], + 'curl' => ['text/vnd.curl'], + 'cwk' => ['application/x-appleworks-document'], + 'cwl' => ['application/cwl'], + 'cww' => ['application/prs.cww'], + 'cxt' => ['application/x-director'], + 'cxx' => ['text/x-c', 'text/x-c++src'], + 'd' => ['text/x-dsrc'], + 'dae' => ['model/vnd.collada+xml'], + 'daf' => ['application/vnd.mobius.daf'], + 'dar' => ['application/x-dar'], + 'dart' => ['application/vnd.dart', 'text/x-dart'], + 'dataless' => ['application/vnd.fdsn.seed'], + 'davmount' => ['application/davmount+xml'], + 'dbf' => ['application/dbase', 'application/dbf', 'application/vnd.dbf', 'application/x-dbase', 'application/x-dbf'], + 'dbk' => ['application/docbook+xml', 'application/vnd.oasis.docbook+xml', 'application/x-docbook+xml'], + 'dc' => ['application/x-dc-rom'], + 'dcl' => ['text/x-dcl'], + 'dcm' => ['application/dicom'], + 'dcr' => ['application/x-director', 'image/x-kodak-dcr'], + 'dcurl' => ['text/vnd.curl.dcurl'], + 'dd2' => ['application/vnd.oma.dd2+xml'], + 'ddd' => ['application/vnd.fujixerox.ddd'], + 'ddf' => ['application/vnd.syncml.dmddf+xml'], + 'dds' => ['image/vnd.ms-dds', 'image/x-dds'], + 'deb' => ['application/vnd.debian.binary-package', 'application/x-deb', 'application/x-debian-package'], + 'def' => ['text/plain'], + 'der' => ['application/x-x509-ca-cert'], + 'desktop' => ['application/x-desktop', 'application/x-gnome-app-info'], + 'device' => ['text/x-systemd-unit'], + 'dfac' => ['application/vnd.dreamfactory'], + 'dff' => ['audio/dff', 'audio/x-dff'], + 'dgc' => ['application/x-dgc-compressed'], + 'di' => ['text/x-dsrc'], + 'dia' => ['application/x-dia-diagram'], + 'dib' => ['image/bmp', 'image/x-bmp', 'image/x-ms-bmp'], + 'dic' => ['text/x-c'], + 'diff' => ['text/x-diff', 'text/x-patch'], + 'dir' => ['application/x-director'], + 'dis' => ['application/vnd.mobius.dis'], + 'disposition-notification' => ['message/disposition-notification'], + 'divx' => ['video/avi', 'video/divx', 'video/msvideo', 'video/vnd.avi', 'video/vnd.divx', 'video/x-avi', 'video/x-msvideo'], + 'djv' => ['image/vnd.djvu', 'image/vnd.djvu+multipage', 'image/x-djvu', 'image/x.djvu'], + 'djvu' => ['image/vnd.djvu', 'image/vnd.djvu+multipage', 'image/x-djvu', 'image/x.djvu'], + 'dll' => ['application/vnd.microsoft.portable-executable', 'application/x-ms-dos-executable', 'application/x-ms-ne-executable', 'application/x-msdownload'], + 'dmg' => ['application/x-apple-diskimage'], + 'dmp' => ['application/pcap', 'application/vnd.tcpdump.pcap', 'application/x-pcap'], + 'dna' => ['application/vnd.dna'], + 'dng' => ['image/x-adobe-dng'], + 'doc' => ['application/msword', 'application/vnd.ms-word', 'application/x-msword', 'zz-application/zz-winassoc-doc'], + 'docbook' => ['application/docbook+xml', 'application/vnd.oasis.docbook+xml', 'application/x-docbook+xml'], + 'docm' => ['application/vnd.ms-word.document.macroenabled.12'], + 'docx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'], + 'dot' => ['application/msword', 'application/msword-template', 'text/vnd.graphviz'], + 'dotm' => ['application/vnd.ms-word.template.macroenabled.12'], + 'dotx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.template'], + 'dp' => ['application/vnd.osgi.dp'], + 'dpg' => ['application/vnd.dpgraph'], + 'dpx' => ['image/dpx'], + 'dra' => ['audio/vnd.dra'], + 'drl' => ['application/x-excellon'], + 'drle' => ['image/dicom-rle'], + 'drv' => ['application/vnd.microsoft.portable-executable', 'application/x-ms-dos-executable', 'application/x-ms-ne-executable', 'application/x-msdownload'], + 'dsc' => ['text/prs.lines.tag'], + 'dsf' => ['audio/dsd', 'audio/dsf', 'audio/x-dsd', 'audio/x-dsf'], + 'dsl' => ['text/x-dsl'], + 'dssc' => ['application/dssc+der'], + 'dtb' => ['application/x-dtbook+xml', 'text/x-devicetree-binary'], + 'dtd' => ['application/xml-dtd', 'text/x-dtd'], + 'dts' => ['audio/vnd.dts', 'audio/x-dts', 'text/x-devicetree-source'], + 'dtshd' => ['audio/vnd.dts.hd', 'audio/x-dtshd'], + 'dtsi' => ['text/x-devicetree-source'], + 'dtx' => ['application/x-tex', 'text/x-tex'], + 'dv' => ['video/dv'], + 'dvb' => ['video/vnd.dvb.file'], + 'dvi' => ['application/x-dvi'], + 'dvi.bz2' => ['application/x-bzdvi'], + 'dvi.gz' => ['application/x-gzdvi'], + 'dwd' => ['application/atsc-dwd+xml'], + 'dwf' => ['model/vnd.dwf'], + 'dwg' => ['image/vnd.dwg'], + 'dxf' => ['image/vnd.dxf'], + 'dxp' => ['application/vnd.spotfire.dxp'], + 'dxr' => ['application/x-director'], + 'e' => ['text/x-eiffel'], + 'ear' => ['application/java-archive'], + 'ecelp4800' => ['audio/vnd.nuera.ecelp4800'], + 'ecelp7470' => ['audio/vnd.nuera.ecelp7470'], + 'ecelp9600' => ['audio/vnd.nuera.ecelp9600'], + 'ecma' => ['application/ecmascript'], + 'edm' => ['application/vnd.novadigm.edm'], + 'edx' => ['application/vnd.novadigm.edx'], + 'efi' => ['application/vnd.microsoft.portable-executable'], + 'efif' => ['application/vnd.picsel'], + 'egon' => ['application/x-egon'], + 'ei6' => ['application/vnd.pg.osasli'], + 'eif' => ['text/x-eiffel'], + 'el' => ['text/x-emacs-lisp'], + 'emf' => ['application/emf', 'application/x-emf', 'application/x-msmetafile', 'image/emf', 'image/x-emf'], + 'eml' => ['message/rfc822'], + 'emma' => ['application/emma+xml'], + 'emotionml' => ['application/emotionml+xml'], + 'emp' => ['application/vnd.emusic-emusic_package'], + 'emz' => ['application/x-msmetafile'], + 'ent' => ['application/xml-external-parsed-entity', 'text/xml-external-parsed-entity'], + 'eol' => ['audio/vnd.digital-winds'], + 'eot' => ['application/vnd.ms-fontobject'], + 'eps' => ['application/postscript', 'image/x-eps'], + 'eps.bz2' => ['image/x-bzeps'], + 'eps.gz' => ['image/x-gzeps'], + 'epsf' => ['image/x-eps'], + 'epsf.bz2' => ['image/x-bzeps'], + 'epsf.gz' => ['image/x-gzeps'], + 'epsi' => ['image/x-eps'], + 'epsi.bz2' => ['image/x-bzeps'], + 'epsi.gz' => ['image/x-gzeps'], + 'epub' => ['application/epub+zip'], + 'eris' => ['application/x-eris-link+cbor'], + 'erl' => ['text/x-erlang'], + 'es' => ['application/ecmascript', 'text/ecmascript'], + 'es3' => ['application/vnd.eszigno3+xml'], + 'esa' => ['application/vnd.osgi.subsystem'], + 'escn' => ['application/x-godot-scene'], + 'esf' => ['application/vnd.epson.esf'], + 'et3' => ['application/vnd.eszigno3+xml'], + 'etheme' => ['application/x-e-theme'], + 'etx' => ['text/x-setext'], + 'eva' => ['application/x-eva'], + 'evy' => ['application/x-envoy'], + 'ex' => ['text/x-elixir'], + 'exe' => ['application/vnd.microsoft.portable-executable', 'application/x-dosexec', 'application/x-ms-dos-executable', 'application/x-ms-ne-executable', 'application/x-msdos-program', 'application/x-msdownload'], + 'exi' => ['application/exi'], + 'exp' => ['application/express'], + 'exr' => ['image/aces', 'image/x-exr'], + 'exs' => ['text/x-elixir'], + 'ext' => ['application/vnd.novadigm.ext'], + 'ez' => ['application/andrew-inset'], + 'ez2' => ['application/vnd.ezpix-album'], + 'ez3' => ['application/vnd.ezpix-package'], + 'f' => ['text/x-fortran'], + 'f4a' => ['audio/m4a', 'audio/mp4', 'audio/x-m4a'], + 'f4b' => ['audio/x-m4b'], + 'f4v' => ['video/mp4', 'video/mp4v-es', 'video/x-f4v', 'video/x-m4v'], + 'f77' => ['text/x-fortran'], + 'f90' => ['text/x-fortran'], + 'f95' => ['text/x-fortran'], + 'fasl' => ['text/x-common-lisp'], + 'fb2' => ['application/x-fictionbook', 'application/x-fictionbook+xml'], + 'fb2.zip' => ['application/x-zip-compressed-fb2'], + 'fbs' => ['image/vnd.fastbidsheet'], + 'fcdt' => ['application/vnd.adobe.formscentral.fcdt'], + 'fcs' => ['application/vnd.isac.fcs'], + 'fd' => ['application/x-fd-file', 'application/x-raw-floppy-disk-image'], + 'fdf' => ['application/fdf', 'application/vnd.fdf'], + 'fds' => ['application/x-fds-disk'], + 'fdt' => ['application/fdt+xml'], + 'fe_launch' => ['application/vnd.denovo.fcselayout-link'], + 'feature' => ['text/x-gherkin'], + 'fg5' => ['application/vnd.fujitsu.oasysgp'], + 'fgd' => ['application/x-director'], + 'fh' => ['image/x-freehand'], + 'fh4' => ['image/x-freehand'], + 'fh5' => ['image/x-freehand'], + 'fh7' => ['image/x-freehand'], + 'fhc' => ['image/x-freehand'], + 'fig' => ['application/x-xfig', 'image/x-xfig'], + 'fish' => ['application/x-fishscript', 'text/x-fish'], + 'fit' => ['application/fits', 'image/fits', 'image/x-fits'], + 'fits' => ['application/fits', 'image/fits', 'image/x-fits'], + 'fl' => ['application/x-fluid'], + 'flac' => ['audio/flac', 'audio/x-flac'], + 'flatpak' => ['application/vnd.flatpak', 'application/vnd.xdgapp'], + 'flatpakref' => ['application/vnd.flatpak.ref'], + 'flatpakrepo' => ['application/vnd.flatpak.repo'], + 'flc' => ['video/fli', 'video/x-fli', 'video/x-flic'], + 'fli' => ['video/fli', 'video/x-fli', 'video/x-flic'], + 'flo' => ['application/vnd.micrografx.flo'], + 'flv' => ['video/x-flv', 'application/x-flash-video', 'flv-application/octet-stream', 'video/flv'], + 'flw' => ['application/vnd.kde.kivio', 'application/x-kivio'], + 'flx' => ['text/vnd.fmi.flexstor'], + 'fly' => ['text/vnd.fly'], + 'fm' => ['application/vnd.framemaker', 'application/x-frame'], + 'fnc' => ['application/vnd.frogans.fnc'], + 'fo' => ['application/vnd.software602.filler.form+xml', 'text/x-xslfo'], + 'fodg' => ['application/vnd.oasis.opendocument.graphics-flat-xml'], + 'fodp' => ['application/vnd.oasis.opendocument.presentation-flat-xml'], + 'fods' => ['application/vnd.oasis.opendocument.spreadsheet-flat-xml'], + 'fodt' => ['application/vnd.oasis.opendocument.text-flat-xml'], + 'for' => ['text/x-fortran'], + 'fpx' => ['image/vnd.fpx', 'image/x-fpx'], + 'frame' => ['application/vnd.framemaker'], + 'fsc' => ['application/vnd.fsc.weblaunch'], + 'fst' => ['image/vnd.fst'], + 'ftc' => ['application/vnd.fluxtime.clip'], + 'fti' => ['application/vnd.anser-web-funds-transfer-initiation'], + 'fts' => ['application/fits', 'image/fits', 'image/x-fits'], + 'fvt' => ['video/vnd.fvt'], + 'fxm' => ['video/x-javafx'], + 'fxp' => ['application/vnd.adobe.fxp'], + 'fxpl' => ['application/vnd.adobe.fxp'], + 'fzs' => ['application/vnd.fuzzysheet'], + 'g2w' => ['application/vnd.geoplan'], + 'g3' => ['image/fax-g3', 'image/g3fax'], + 'g3w' => ['application/vnd.geospace'], + 'gac' => ['application/vnd.groove-account'], + 'gam' => ['application/x-tads'], + 'gb' => ['application/x-gameboy-rom'], + 'gba' => ['application/x-gba-rom'], + 'gbc' => ['application/x-gameboy-color-rom'], + 'gbr' => ['application/rpki-ghostbusters', 'application/vnd.gerber', 'application/x-gerber', 'image/x-gimp-gbr'], + 'gbrjob' => ['application/x-gerber-job'], + 'gca' => ['application/x-gca-compressed'], + 'gcode' => ['text/x.gcode'], + 'gcrd' => ['text/directory', 'text/vcard', 'text/x-vcard'], + 'gd' => ['application/x-gdscript'], + 'gdi' => ['application/x-gd-rom-cue'], + 'gdl' => ['model/vnd.gdl'], + 'gdoc' => ['application/vnd.google-apps.document'], + 'gdshader' => ['application/x-godot-shader'], + 'ged' => ['application/x-gedcom', 'text/gedcom', 'text/vnd.familysearch.gedcom'], + 'gedcom' => ['application/x-gedcom', 'text/gedcom', 'text/vnd.familysearch.gedcom'], + 'gem' => ['application/x-gtar', 'application/x-tar'], + 'gen' => ['application/x-genesis-rom'], + 'geo' => ['application/vnd.dynageo'], + 'geo.json' => ['application/geo+json', 'application/vnd.geo+json'], + 'geojson' => ['application/geo+json', 'application/vnd.geo+json'], + 'gex' => ['application/vnd.geometry-explorer'], + 'gf' => ['application/x-tex-gf'], + 'gg' => ['application/x-gamegear-rom'], + 'ggb' => ['application/vnd.geogebra.file'], + 'ggs' => ['application/vnd.geogebra.slides'], + 'ggt' => ['application/vnd.geogebra.tool'], + 'ghf' => ['application/vnd.groove-help'], + 'gif' => ['image/gif'], + 'gih' => ['image/x-gimp-gih'], + 'gim' => ['application/vnd.groove-identity-message'], + 'glade' => ['application/x-glade'], + 'glb' => ['model/gltf-binary'], + 'gltf' => ['model/gltf+json'], + 'gml' => ['application/gml+xml'], + 'gmo' => ['application/x-gettext-translation'], + 'gmx' => ['application/vnd.gmx'], + 'gnc' => ['application/x-gnucash'], + 'gnd' => ['application/gnunet-directory'], + 'gnucash' => ['application/x-gnucash'], + 'gnumeric' => ['application/x-gnumeric'], + 'gnuplot' => ['application/x-gnuplot'], + 'go' => ['text/x-go'], + 'gp' => ['application/x-gnuplot'], + 'gpg' => ['application/pgp', 'application/pgp-encrypted', 'application/pgp-keys', 'application/pgp-signature'], + 'gph' => ['application/vnd.flographit'], + 'gplt' => ['application/x-gnuplot'], + 'gpx' => ['application/gpx', 'application/gpx+xml', 'application/x-gpx', 'application/x-gpx+xml'], + 'gqf' => ['application/vnd.grafeq'], + 'gqs' => ['application/vnd.grafeq'], + 'gra' => ['application/x-graphite'], + 'gradle' => ['text/x-gradle'], + 'gram' => ['application/srgs'], + 'gramps' => ['application/x-gramps-xml'], + 'gre' => ['application/vnd.geometry-explorer'], + 'groovy' => ['text/x-groovy'], + 'grv' => ['application/vnd.groove-injector'], + 'grxml' => ['application/srgs+xml'], + 'gs' => ['text/x-genie'], + 'gsf' => ['application/x-font-ghostscript', 'application/x-font-type1'], + 'gsh' => ['text/x-groovy'], + 'gsheet' => ['application/vnd.google-apps.spreadsheet'], + 'gslides' => ['application/vnd.google-apps.presentation'], + 'gsm' => ['audio/x-gsm'], + 'gtar' => ['application/x-gtar', 'application/x-tar'], + 'gtm' => ['application/vnd.groove-tool-message'], + 'gtw' => ['model/vnd.gtw'], + 'gv' => ['text/vnd.graphviz'], + 'gvp' => ['text/google-video-pointer', 'text/x-google-video-pointer'], + 'gvy' => ['text/x-groovy'], + 'gx' => ['text/x-gcode-gx'], + 'gxf' => ['application/gxf'], + 'gxt' => ['application/vnd.geonext'], + 'gy' => ['text/x-groovy'], + 'gz' => ['application/x-gzip', 'application/gzip'], + 'h' => ['text/x-c', 'text/x-chdr'], + 'h++' => ['text/x-c++hdr'], + 'h261' => ['video/h261'], + 'h263' => ['video/h263'], + 'h264' => ['video/h264'], + 'h4' => ['application/x-hdf'], + 'h5' => ['application/x-hdf'], + 'hal' => ['application/vnd.hal+xml'], + 'hbci' => ['application/vnd.hbci'], + 'hbs' => ['text/x-handlebars-template'], + 'hdd' => ['application/x-virtualbox-hdd'], + 'hdf' => ['application/x-hdf'], + 'hdf4' => ['application/x-hdf'], + 'hdf5' => ['application/x-hdf'], + 'hdp' => ['image/jxr', 'image/vnd.ms-photo'], + 'heic' => ['image/heic', 'image/heic-sequence', 'image/heif', 'image/heif-sequence'], + 'heics' => ['image/heic-sequence'], + 'heif' => ['image/heic', 'image/heic-sequence', 'image/heif', 'image/heif-sequence'], + 'heifs' => ['image/heif-sequence'], + 'hej2' => ['image/hej2k'], + 'held' => ['application/atsc-held+xml'], + 'hfe' => ['application/x-hfe-file', 'application/x-hfe-floppy-image'], + 'hh' => ['text/x-c', 'text/x-c++hdr'], + 'hif' => ['image/heic', 'image/heic-sequence', 'image/heif', 'image/heif-sequence'], + 'hjson' => ['application/hjson'], + 'hlp' => ['application/winhlp', 'zz-application/zz-winassoc-hlp'], + 'hp' => ['text/x-c++hdr'], + 'hpgl' => ['application/vnd.hp-hpgl'], + 'hpid' => ['application/vnd.hp-hpid'], + 'hpp' => ['text/x-c++hdr'], + 'hps' => ['application/vnd.hp-hps'], + 'hqx' => ['application/stuffit', 'application/mac-binhex40'], + 'hs' => ['text/x-haskell'], + 'hsj2' => ['image/hsj2'], + 'hta' => ['application/hta'], + 'htc' => ['text/x-component'], + 'htke' => ['application/vnd.kenameaapp'], + 'htm' => ['text/html', 'application/xhtml+xml'], + 'html' => ['text/html', 'application/xhtml+xml'], + 'hvd' => ['application/vnd.yamaha.hv-dic'], + 'hvp' => ['application/vnd.yamaha.hv-voice'], + 'hvs' => ['application/vnd.yamaha.hv-script'], + 'hwp' => ['application/vnd.haansoft-hwp', 'application/x-hwp'], + 'hwt' => ['application/vnd.haansoft-hwt', 'application/x-hwt'], + 'hxx' => ['text/x-c++hdr'], + 'i2g' => ['application/vnd.intergeo'], + 'ica' => ['application/x-ica'], + 'icalendar' => ['application/ics', 'text/calendar', 'text/x-vcalendar'], + 'icb' => ['application/tga', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'], + 'icc' => ['application/vnd.iccprofile'], + 'ice' => ['x-conference/x-cooltalk'], + 'icm' => ['application/vnd.iccprofile'], + 'icns' => ['image/x-icns'], + 'ico' => ['application/ico', 'image/ico', 'image/icon', 'image/vnd.microsoft.icon', 'image/x-ico', 'image/x-icon', 'text/ico'], + 'ics' => ['application/ics', 'text/calendar', 'text/x-vcalendar'], + 'idl' => ['text/x-idl'], + 'ief' => ['image/ief'], + 'ifb' => ['application/ics', 'text/calendar', 'text/x-vcalendar'], + 'iff' => ['image/x-iff', 'image/x-ilbm'], + 'ifm' => ['application/vnd.shana.informed.formdata'], + 'iges' => ['model/iges'], + 'igl' => ['application/vnd.igloader'], + 'igm' => ['application/vnd.insors.igm'], + 'igs' => ['model/iges'], + 'igx' => ['application/vnd.micrografx.igx'], + 'iif' => ['application/vnd.shana.informed.interchange'], + 'ilbm' => ['image/x-iff', 'image/x-ilbm'], + 'ime' => ['audio/imelody', 'audio/x-imelody', 'text/x-imelody'], + 'img' => ['application/vnd.efi.img', 'application/x-raw-disk-image'], + 'img.xz' => ['application/x-raw-disk-image-xz-compressed'], + 'imp' => ['application/vnd.accpac.simply.imp'], + 'ims' => ['application/vnd.ms-ims'], + 'imy' => ['audio/imelody', 'audio/x-imelody', 'text/x-imelody'], + 'in' => ['text/plain'], + 'ini' => ['text/plain'], + 'ink' => ['application/inkml+xml'], + 'inkml' => ['application/inkml+xml'], + 'ins' => ['application/x-tex', 'text/x-tex'], + 'install' => ['application/x-install-instructions'], + 'iota' => ['application/vnd.astraea-software.iota'], + 'ipfix' => ['application/ipfix'], + 'ipk' => ['application/vnd.shana.informed.package'], + 'ips' => ['application/x-ips-patch'], + 'iptables' => ['text/x-iptables'], + 'ipynb' => ['application/x-ipynb+json'], + 'irm' => ['application/vnd.ibm.rights-management'], + 'irp' => ['application/vnd.irepository.package+xml'], + 'iso' => ['application/vnd.efi.iso', 'application/x-cd-image', 'application/x-dreamcast-rom', 'application/x-gamecube-iso-image', 'application/x-gamecube-rom', 'application/x-iso9660-image', 'application/x-saturn-rom', 'application/x-sega-cd-rom', 'application/x-sega-pico-rom', 'application/x-wbfs', 'application/x-wia', 'application/x-wii-iso-image', 'application/x-wii-rom'], + 'iso9660' => ['application/vnd.efi.iso', 'application/x-cd-image', 'application/x-iso9660-image'], + 'it' => ['audio/x-it'], + 'it87' => ['application/x-it87'], + 'itp' => ['application/vnd.shana.informed.formtemplate'], + 'its' => ['application/its+xml'], + 'ivp' => ['application/vnd.immervision-ivp'], + 'ivu' => ['application/vnd.immervision-ivu'], + 'j2c' => ['image/x-jp2-codestream'], + 'j2k' => ['image/x-jp2-codestream'], + 'jad' => ['text/vnd.sun.j2me.app-descriptor'], + 'jade' => ['text/jade'], + 'jam' => ['application/vnd.jam'], + 'jar' => ['application/x-java-archive', 'application/java-archive', 'application/x-jar'], + 'jardiff' => ['application/x-java-archive-diff'], + 'java' => ['text/x-java', 'text/x-java-source'], + 'jceks' => ['application/x-java-jce-keystore'], + 'jfif' => ['image/jpeg', 'image/pjpeg'], + 'jhc' => ['image/jphc'], + 'jisp' => ['application/vnd.jisp'], + 'jks' => ['application/x-java-keystore'], + 'jl' => ['text/julia'], + 'jls' => ['image/jls'], + 'jlt' => ['application/vnd.hp-jlyt'], + 'jng' => ['image/x-jng'], + 'jnlp' => ['application/x-java-jnlp-file'], + 'joda' => ['application/vnd.joost.joda-archive'], + 'jp2' => ['image/jp2', 'image/jpeg2000', 'image/jpeg2000-image', 'image/x-jpeg2000-image'], + 'jpc' => ['image/x-jp2-codestream'], + 'jpe' => ['image/jpeg', 'image/pjpeg'], + 'jpeg' => ['image/jpeg', 'image/pjpeg'], + 'jpf' => ['image/jpx'], + 'jpg' => ['image/jpeg', 'image/pjpeg'], + 'jpg2' => ['image/jp2', 'image/jpeg2000', 'image/jpeg2000-image', 'image/x-jpeg2000-image'], + 'jpgm' => ['image/jpm', 'video/jpm'], + 'jpgv' => ['video/jpeg'], + 'jph' => ['image/jph'], + 'jpm' => ['image/jpm', 'video/jpm'], + 'jpr' => ['application/x-jbuilder-project'], + 'jpx' => ['application/x-jbuilder-project', 'image/jpx'], + 'jrd' => ['application/jrd+json'], + 'js' => ['text/javascript', 'application/javascript', 'application/x-javascript', 'text/jscript'], + 'jse' => ['text/jscript.encode'], + 'jsm' => ['application/javascript', 'application/x-javascript', 'text/javascript', 'text/jscript'], + 'json' => ['application/json', 'application/schema+json'], + 'json-patch' => ['application/json-patch+json'], + 'json5' => ['application/json5'], + 'jsonld' => ['application/ld+json'], + 'jsonml' => ['application/jsonml+json'], + 'jsx' => ['text/jsx'], + 'jt' => ['model/jt'], + 'jxl' => ['image/jxl'], + 'jxr' => ['image/jxr', 'image/vnd.ms-photo'], + 'jxra' => ['image/jxra'], + 'jxrs' => ['image/jxrs'], + 'jxs' => ['image/jxs'], + 'jxsc' => ['image/jxsc'], + 'jxsi' => ['image/jxsi'], + 'jxss' => ['image/jxss'], + 'k25' => ['image/x-kodak-k25'], + 'k7' => ['application/x-thomson-cassette'], + 'kar' => ['audio/midi', 'audio/x-midi'], + 'karbon' => ['application/vnd.kde.karbon', 'application/x-karbon'], + 'kcf' => ['image/x-kiss-cel'], + 'kdbx' => ['application/x-keepass2'], + 'kdc' => ['image/x-kodak-kdc'], + 'kdelnk' => ['application/x-desktop', 'application/x-gnome-app-info'], + 'kexi' => ['application/x-kexiproject-sqlite', 'application/x-kexiproject-sqlite2', 'application/x-kexiproject-sqlite3', 'application/x-vnd.kde.kexi'], + 'kexic' => ['application/x-kexi-connectiondata'], + 'kexis' => ['application/x-kexiproject-shortcut'], + 'key' => ['application/vnd.apple.keynote', 'application/pgp-keys', 'application/x-iwork-keynote-sffkey'], + 'keynote' => ['application/vnd.apple.keynote'], + 'kfo' => ['application/vnd.kde.kformula', 'application/x-kformula'], + 'kfx' => ['application/vnd.amazon.mobi8-ebook', 'application/x-mobi8-ebook'], + 'kia' => ['application/vnd.kidspiration'], + 'kil' => ['application/x-killustrator'], + 'kino' => ['application/smil', 'application/smil+xml'], + 'kml' => ['application/vnd.google-earth.kml+xml'], + 'kmz' => ['application/vnd.google-earth.kmz'], + 'kne' => ['application/vnd.kinar'], + 'knp' => ['application/vnd.kinar'], + 'kon' => ['application/vnd.kde.kontour', 'application/x-kontour'], + 'kpm' => ['application/x-kpovmodeler'], + 'kpr' => ['application/vnd.kde.kpresenter', 'application/x-kpresenter'], + 'kpt' => ['application/vnd.kde.kpresenter', 'application/x-kpresenter'], + 'kpxx' => ['application/vnd.ds-keypoint'], + 'kra' => ['application/x-krita'], + 'krz' => ['application/x-krita'], + 'ks' => ['application/x-java-keystore'], + 'ksp' => ['application/vnd.kde.kspread', 'application/x-kspread'], + 'ksy' => ['text/x-kaitai-struct'], + 'kt' => ['text/x-kotlin'], + 'ktr' => ['application/vnd.kahootz'], + 'ktx' => ['image/ktx'], + 'ktx2' => ['image/ktx2'], + 'ktz' => ['application/vnd.kahootz'], + 'kud' => ['application/x-kugar'], + 'kwd' => ['application/vnd.kde.kword', 'application/x-kword'], + 'kwt' => ['application/vnd.kde.kword', 'application/x-kword'], + 'la' => ['application/x-shared-library-la'], + 'lasxml' => ['application/vnd.las.las+xml'], + 'latex' => ['application/x-latex', 'application/x-tex', 'text/x-tex'], + 'lbd' => ['application/vnd.llamagraphics.life-balance.desktop'], + 'lbe' => ['application/vnd.llamagraphics.life-balance.exchange+xml'], + 'lbm' => ['image/x-iff', 'image/x-ilbm'], + 'ldif' => ['text/x-ldif'], + 'les' => ['application/vnd.hhe.lesson-player'], + 'less' => ['text/less'], + 'lgr' => ['application/lgr+xml'], + 'lha' => ['application/x-lha', 'application/x-lzh-compressed'], + 'lhs' => ['text/x-literate-haskell'], + 'lhz' => ['application/x-lhz'], + 'lib' => ['application/vnd.microsoft.portable-executable', 'application/x-archive'], + 'link66' => ['application/vnd.route66.link66+xml'], + 'lisp' => ['text/x-common-lisp'], + 'list' => ['text/plain'], + 'list3820' => ['application/vnd.ibm.modcap'], + 'listafp' => ['application/vnd.ibm.modcap'], + 'litcoffee' => ['text/coffeescript'], + 'lmdb' => ['application/x-lmdb'], + 'lnk' => ['application/x-ms-shortcut', 'application/x-win-lnk'], + 'lnx' => ['application/x-atari-lynx-rom'], + 'loas' => ['audio/usac'], + 'log' => ['text/plain', 'text/x-log'], + 'lostxml' => ['application/lost+xml'], + 'lrf' => ['application/x-sony-bbeb'], + 'lrm' => ['application/vnd.ms-lrm'], + 'lrv' => ['video/mp4', 'video/mp4v-es', 'video/x-m4v'], + 'lrz' => ['application/x-lrzip'], + 'ltf' => ['application/vnd.frogans.ltf'], + 'ltx' => ['application/x-tex', 'text/x-tex'], + 'lua' => ['text/x-lua'], + 'luac' => ['application/x-lua-bytecode'], + 'lvp' => ['audio/vnd.lucent.voice'], + 'lwo' => ['image/x-lwo'], + 'lwob' => ['image/x-lwo'], + 'lwp' => ['application/vnd.lotus-wordpro'], + 'lws' => ['image/x-lws'], + 'ly' => ['text/x-lilypond'], + 'lyx' => ['application/x-lyx', 'text/x-lyx'], + 'lz' => ['application/x-lzip'], + 'lz4' => ['application/x-lz4'], + 'lzh' => ['application/x-lha', 'application/x-lzh-compressed'], + 'lzma' => ['application/x-lzma'], + 'lzo' => ['application/x-lzop'], + 'm' => ['text/x-matlab', 'text/x-objcsrc', 'text/x-octave'], + 'm13' => ['application/x-msmediaview'], + 'm14' => ['application/x-msmediaview'], + 'm15' => ['audio/x-mod'], + 'm1u' => ['video/vnd.mpegurl', 'video/x-mpegurl'], + 'm1v' => ['video/mpeg'], + 'm21' => ['application/mp21'], + 'm2a' => ['audio/mpeg'], + 'm2t' => ['video/mp2t'], + 'm2ts' => ['video/mp2t'], + 'm2v' => ['video/mpeg'], + 'm3a' => ['audio/mpeg'], + 'm3u' => ['audio/x-mpegurl', 'application/m3u', 'application/vnd.apple.mpegurl', 'audio/m3u', 'audio/mpegurl', 'audio/x-m3u', 'audio/x-mp3-playlist'], + 'm3u8' => ['application/m3u', 'application/vnd.apple.mpegurl', 'audio/m3u', 'audio/mpegurl', 'audio/x-m3u', 'audio/x-mp3-playlist', 'audio/x-mpegurl'], + 'm4' => ['application/x-m4'], + 'm4a' => ['audio/mp4', 'audio/m4a', 'audio/x-m4a'], + 'm4b' => ['audio/x-m4b'], + 'm4p' => ['application/mp4'], + 'm4r' => ['audio/x-m4r'], + 'm4s' => ['video/iso.segment'], + 'm4u' => ['video/vnd.mpegurl', 'video/x-mpegurl'], + 'm4v' => ['video/mp4', 'video/mp4v-es', 'video/x-m4v'], + 'm7' => ['application/x-thomson-cartridge-memo7'], + 'ma' => ['application/mathematica'], + 'mab' => ['application/x-markaby'], + 'mads' => ['application/mads+xml'], + 'maei' => ['application/mmt-aei+xml'], + 'mag' => ['application/vnd.ecowin.chart'], + 'mak' => ['text/x-makefile'], + 'maker' => ['application/vnd.framemaker'], + 'man' => ['application/x-troff-man', 'text/troff'], + 'manifest' => ['text/cache-manifest'], + 'map' => ['application/json'], + 'markdown' => ['text/markdown', 'text/x-markdown'], + 'mathml' => ['application/mathml+xml'], + 'mb' => ['application/mathematica'], + 'mbk' => ['application/vnd.mobius.mbk'], + 'mbox' => ['application/mbox'], + 'mc1' => ['application/vnd.medcalcdata'], + 'mc2' => ['text/vnd.senx.warpscript'], + 'mcd' => ['application/vnd.mcd'], + 'mcurl' => ['text/vnd.curl.mcurl'], + 'md' => ['text/markdown', 'text/x-markdown', 'application/x-genesis-rom'], + 'mdb' => ['application/x-msaccess', 'application/mdb', 'application/msaccess', 'application/vnd.ms-access', 'application/vnd.msaccess', 'application/x-lmdb', 'application/x-mdb', 'zz-application/zz-winassoc-mdb'], + 'mdi' => ['image/vnd.ms-modi'], + 'mdx' => ['application/x-genesis-32x-rom', 'text/mdx'], + 'me' => ['text/troff', 'text/x-troff-me'], + 'med' => ['audio/x-mod'], + 'mesh' => ['model/mesh'], + 'meta4' => ['application/metalink4+xml'], + 'metalink' => ['application/metalink+xml'], + 'mets' => ['application/mets+xml'], + 'mfm' => ['application/vnd.mfmp'], + 'mft' => ['application/rpki-manifest'], + 'mgp' => ['application/vnd.osgeo.mapguide.package', 'application/x-magicpoint'], + 'mgz' => ['application/vnd.proteus.magazine'], + 'mht' => ['application/x-mimearchive'], + 'mhtml' => ['application/x-mimearchive'], + 'mid' => ['audio/midi', 'audio/x-midi'], + 'midi' => ['audio/midi', 'audio/x-midi'], + 'mie' => ['application/x-mie'], + 'mif' => ['application/vnd.mif', 'application/x-mif'], + 'mime' => ['message/rfc822'], + 'minipsf' => ['audio/x-minipsf'], + 'mj2' => ['video/mj2'], + 'mjp2' => ['video/mj2'], + 'mjpeg' => ['video/x-mjpeg'], + 'mjpg' => ['video/x-mjpeg'], + 'mjs' => ['application/javascript', 'application/x-javascript', 'text/javascript', 'text/jscript'], + 'mk' => ['text/x-makefile'], + 'mk3d' => ['video/x-matroska', 'video/x-matroska-3d'], + 'mka' => ['audio/x-matroska'], + 'mkd' => ['text/markdown', 'text/x-markdown'], + 'mks' => ['video/x-matroska'], + 'mkv' => ['video/x-matroska'], + 'ml' => ['text/x-ocaml'], + 'mli' => ['text/x-ocaml'], + 'mlp' => ['application/vnd.dolby.mlp'], + 'mm' => ['text/x-objc++src', 'text/x-troff-mm'], + 'mmd' => ['application/vnd.chipnuts.karaoke-mmd'], + 'mmf' => ['application/vnd.smaf', 'application/x-smaf'], + 'mml' => ['application/mathml+xml', 'text/mathml'], + 'mmr' => ['image/vnd.fujixerox.edmics-mmr'], + 'mng' => ['video/x-mng'], + 'mny' => ['application/x-msmoney'], + 'mo' => ['application/x-gettext-translation', 'text/x-modelica'], + 'mo3' => ['audio/x-mo3'], + 'mobi' => ['application/x-mobipocket-ebook'], + 'moc' => ['text/x-moc'], + 'mod' => ['application/x-object', 'audio/x-mod'], + 'mods' => ['application/mods+xml'], + 'mof' => ['text/x-mof'], + 'moov' => ['video/quicktime'], + 'mount' => ['text/x-systemd-unit'], + 'mov' => ['video/quicktime'], + 'movie' => ['video/x-sgi-movie'], + 'mp+' => ['audio/x-musepack'], + 'mp2' => ['audio/mp2', 'audio/mpeg', 'audio/x-mp2', 'video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'], + 'mp21' => ['application/mp21'], + 'mp2a' => ['audio/mpeg'], + 'mp3' => ['audio/mpeg', 'audio/mp3', 'audio/x-mp3', 'audio/x-mpeg', 'audio/x-mpg'], + 'mp4' => ['video/mp4', 'application/mp4', 'video/mp4v-es', 'video/x-m4v'], + 'mp4a' => ['audio/mp4'], + 'mp4s' => ['application/mp4'], + 'mp4v' => ['video/mp4'], + 'mpc' => ['application/vnd.mophun.certificate', 'audio/x-musepack'], + 'mpd' => ['application/dash+xml'], + 'mpe' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'], + 'mpeg' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'], + 'mpf' => ['application/media-policy-dataset+xml'], + 'mpg' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'], + 'mpg4' => ['video/mpg4', 'application/mp4', 'video/mp4'], + 'mpga' => ['audio/mp3', 'audio/mpeg', 'audio/x-mp3', 'audio/x-mpeg', 'audio/x-mpg'], + 'mpkg' => ['application/vnd.apple.installer+xml'], + 'mpl' => ['text/x-mpl2', 'video/mp2t'], + 'mpls' => ['video/mp2t'], + 'mpm' => ['application/vnd.blueice.multipass'], + 'mpn' => ['application/vnd.mophun.application'], + 'mpp' => ['application/dash-patch+xml', 'application/vnd.ms-project', 'audio/x-musepack'], + 'mpt' => ['application/vnd.ms-project'], + 'mpy' => ['application/vnd.ibm.minipay'], + 'mqy' => ['application/vnd.mobius.mqy'], + 'mrc' => ['application/marc'], + 'mrcx' => ['application/marcxml+xml'], + 'mrl' => ['text/x-mrml'], + 'mrml' => ['text/x-mrml'], + 'mrpack' => ['application/x-modrinth-modpack+zip'], + 'mrw' => ['image/x-minolta-mrw'], + 'ms' => ['text/troff', 'text/x-troff-ms'], + 'mscml' => ['application/mediaservercontrol+xml'], + 'mseed' => ['application/vnd.fdsn.mseed'], + 'mseq' => ['application/vnd.mseq'], + 'msf' => ['application/vnd.epson.msf'], + 'msg' => ['application/vnd.ms-outlook'], + 'msh' => ['model/mesh'], + 'msi' => ['application/x-msdownload', 'application/x-msi'], + 'msix' => ['application/msix'], + 'msixbundle' => ['application/msixbundle'], + 'msl' => ['application/vnd.mobius.msl'], + 'msod' => ['image/x-msod'], + 'msp' => ['application/microsoftpatch'], + 'msty' => ['application/vnd.muvee.style'], + 'msu' => ['application/microsoftupdate'], + 'msx' => ['application/x-msx-rom'], + 'mtl' => ['model/mtl'], + 'mtm' => ['audio/x-mod'], + 'mts' => ['model/vnd.mts', 'video/mp2t'], + 'mup' => ['text/x-mup'], + 'mus' => ['application/vnd.musician'], + 'musd' => ['application/mmt-usd+xml'], + 'musicxml' => ['application/vnd.recordare.musicxml+xml'], + 'mvb' => ['application/x-msmediaview'], + 'mvt' => ['application/vnd.mapbox-vector-tile'], + 'mwf' => ['application/vnd.mfer'], + 'mxf' => ['application/mxf'], + 'mxl' => ['application/vnd.recordare.musicxml'], + 'mxmf' => ['audio/mobile-xmf', 'audio/vnd.nokia.mobile-xmf'], + 'mxml' => ['application/xv+xml'], + 'mxs' => ['application/vnd.triscape.mxs'], + 'mxu' => ['video/vnd.mpegurl', 'video/x-mpegurl'], + 'n-gage' => ['application/vnd.nokia.n-gage.symbian.install'], + 'n3' => ['text/n3'], + 'n64' => ['application/x-n64-rom'], + 'nb' => ['application/mathematica', 'application/x-mathematica'], + 'nbp' => ['application/vnd.wolfram.player'], + 'nc' => ['application/x-netcdf'], + 'ncx' => ['application/x-dtbncx+xml'], + 'nds' => ['application/x-nintendo-ds-rom'], + 'nef' => ['image/x-nikon-nef'], + 'nes' => ['application/x-nes-rom'], + 'nez' => ['application/x-nes-rom'], + 'nfo' => ['text/x-nfo'], + 'ngc' => ['application/x-neo-geo-pocket-color-rom'], + 'ngdat' => ['application/vnd.nokia.n-gage.data'], + 'ngp' => ['application/x-neo-geo-pocket-rom'], + 'nim' => ['text/x-nim'], + 'nimble' => ['text/x-nimscript'], + 'nims' => ['text/x-nimscript'], + 'nitf' => ['application/vnd.nitf'], + 'nix' => ['text/x-nix'], + 'nlu' => ['application/vnd.neurolanguage.nlu'], + 'nml' => ['application/vnd.enliven'], + 'nnd' => ['application/vnd.noblenet-directory'], + 'nns' => ['application/vnd.noblenet-sealer'], + 'nnw' => ['application/vnd.noblenet-web'], + 'not' => ['text/x-mup'], + 'npx' => ['image/vnd.net-fpx'], + 'nq' => ['application/n-quads'], + 'nrw' => ['image/x-nikon-nrw'], + 'nsc' => ['application/x-conference', 'application/x-netshow-channel'], + 'nsf' => ['application/vnd.lotus-notes'], + 'nsv' => ['video/x-nsv'], + 'nt' => ['application/n-triples'], + 'ntar' => ['application/x-pcapng'], + 'ntf' => ['application/vnd.nitf'], + 'nu' => ['application/x-nuscript', 'text/x-nu'], + 'numbers' => ['application/vnd.apple.numbers', 'application/x-iwork-numbers-sffnumbers'], + 'nzb' => ['application/x-nzb'], + 'o' => ['application/x-object'], + 'oa2' => ['application/vnd.fujitsu.oasys2'], + 'oa3' => ['application/vnd.fujitsu.oasys3'], + 'oas' => ['application/vnd.fujitsu.oasys'], + 'obd' => ['application/x-msbinder'], + 'obgx' => ['application/vnd.openblox.game+xml'], + 'obj' => ['application/prs.wavefront-obj', 'application/x-tgif', 'model/obj'], + 'ocl' => ['text/x-ocl'], + 'ocx' => ['application/vnd.microsoft.portable-executable'], + 'oda' => ['application/oda'], + 'odb' => ['application/vnd.oasis.opendocument.base', 'application/vnd.oasis.opendocument.database', 'application/vnd.sun.xml.base'], + 'odc' => ['application/vnd.oasis.opendocument.chart'], + 'odf' => ['application/vnd.oasis.opendocument.formula'], + 'odft' => ['application/vnd.oasis.opendocument.formula-template'], + 'odg' => ['application/vnd.oasis.opendocument.graphics'], + 'odi' => ['application/vnd.oasis.opendocument.image'], + 'odm' => ['application/vnd.oasis.opendocument.text-master'], + 'odp' => ['application/vnd.oasis.opendocument.presentation'], + 'ods' => ['application/vnd.oasis.opendocument.spreadsheet'], + 'odt' => ['application/vnd.oasis.opendocument.text'], + 'oga' => ['audio/ogg', 'audio/vorbis', 'audio/x-flac+ogg', 'audio/x-ogg', 'audio/x-oggflac', 'audio/x-speex+ogg', 'audio/x-vorbis', 'audio/x-vorbis+ogg'], + 'ogex' => ['model/vnd.opengex'], + 'ogg' => ['audio/ogg', 'audio/vorbis', 'audio/x-flac+ogg', 'audio/x-ogg', 'audio/x-oggflac', 'audio/x-speex+ogg', 'audio/x-vorbis', 'audio/x-vorbis+ogg', 'video/ogg', 'video/x-ogg', 'video/x-theora', 'video/x-theora+ogg'], + 'ogm' => ['video/x-ogm', 'video/x-ogm+ogg'], + 'ogv' => ['video/ogg', 'video/x-ogg'], + 'ogx' => ['application/ogg', 'application/x-ogg'], + 'old' => ['application/x-trash'], + 'oleo' => ['application/x-oleo'], + 'omdoc' => ['application/omdoc+xml'], + 'onepkg' => ['application/onenote'], + 'onetmp' => ['application/onenote'], + 'onetoc' => ['application/onenote'], + 'onetoc2' => ['application/onenote'], + 'ooc' => ['text/x-ooc'], + 'openvpn' => ['application/x-openvpn-profile'], + 'opf' => ['application/oebps-package+xml'], + 'opml' => ['text/x-opml', 'text/x-opml+xml'], + 'oprc' => ['application/vnd.palm', 'application/x-palm-database'], + 'opus' => ['audio/ogg', 'audio/x-ogg', 'audio/x-opus+ogg'], + 'ora' => ['image/openraster'], + 'orf' => ['image/x-olympus-orf'], + 'org' => ['application/vnd.lotus-organizer', 'text/org', 'text/x-org'], + 'osf' => ['application/vnd.yamaha.openscoreformat'], + 'osfpvg' => ['application/vnd.yamaha.openscoreformat.osfpvg+xml'], + 'osm' => ['application/vnd.openstreetmap.data+xml'], + 'otc' => ['application/vnd.oasis.opendocument.chart-template'], + 'otf' => ['application/vnd.oasis.opendocument.formula-template', 'application/x-font-otf', 'font/otf'], + 'otg' => ['application/vnd.oasis.opendocument.graphics-template'], + 'oth' => ['application/vnd.oasis.opendocument.text-web'], + 'oti' => ['application/vnd.oasis.opendocument.image-template'], + 'otm' => ['application/vnd.oasis.opendocument.text-master-template'], + 'otp' => ['application/vnd.oasis.opendocument.presentation-template'], + 'ots' => ['application/vnd.oasis.opendocument.spreadsheet-template'], + 'ott' => ['application/vnd.oasis.opendocument.text-template'], + 'ova' => ['application/ovf', 'application/x-virtualbox-ova'], + 'ovf' => ['application/x-virtualbox-ovf'], + 'ovpn' => ['application/x-openvpn-profile'], + 'owl' => ['application/rdf+xml', 'text/rdf'], + 'owx' => ['application/owl+xml'], + 'oxps' => ['application/oxps'], + 'oxt' => ['application/vnd.openofficeorg.extension'], + 'p' => ['text/x-pascal'], + 'p10' => ['application/pkcs10'], + 'p12' => ['application/pkcs12', 'application/x-pkcs12'], + 'p65' => ['application/x-pagemaker'], + 'p7b' => ['application/x-pkcs7-certificates'], + 'p7c' => ['application/pkcs7-mime'], + 'p7m' => ['application/pkcs7-mime'], + 'p7r' => ['application/x-pkcs7-certreqresp'], + 'p7s' => ['application/pkcs7-signature'], + 'p8' => ['application/pkcs8'], + 'p8e' => ['application/pkcs8-encrypted'], + 'pac' => ['application/x-ns-proxy-autoconfig'], + 'pack' => ['application/x-java-pack200'], + 'pages' => ['application/vnd.apple.pages', 'application/x-iwork-pages-sffpages'], + 'pak' => ['application/x-pak'], + 'par2' => ['application/x-par2'], + 'parquet' => ['application/vnd.apache.parquet', 'application/x-parquet'], + 'part' => ['application/x-partial-download'], + 'pas' => ['text/x-pascal'], + 'pat' => ['image/x-gimp-pat'], + 'patch' => ['text/x-diff', 'text/x-patch'], + 'path' => ['text/x-systemd-unit'], + 'paw' => ['application/vnd.pawaafile'], + 'pbd' => ['application/vnd.powerbuilder6'], + 'pbm' => ['image/x-portable-bitmap'], + 'pcap' => ['application/pcap', 'application/vnd.tcpdump.pcap', 'application/x-pcap'], + 'pcapng' => ['application/x-pcapng'], + 'pcd' => ['image/x-photo-cd'], + 'pce' => ['application/x-pc-engine-rom'], + 'pcf' => ['application/x-cisco-vpn-settings', 'application/x-font-pcf'], + 'pcf.Z' => ['application/x-font-pcf'], + 'pcf.gz' => ['application/x-font-pcf'], + 'pcl' => ['application/vnd.hp-pcl'], + 'pclxl' => ['application/vnd.hp-pclxl'], + 'pct' => ['image/x-pict'], + 'pcurl' => ['application/vnd.curl.pcurl'], + 'pcx' => ['image/vnd.zbrush.pcx', 'image/x-pcx'], + 'pdb' => ['application/vnd.palm', 'application/x-aportisdoc', 'application/x-ms-pdb', 'application/x-palm-database', 'application/x-pilot', 'chemical/x-pdb'], + 'pdc' => ['application/x-aportisdoc'], + 'pde' => ['text/x-processing'], + 'pdf' => ['application/pdf', 'application/acrobat', 'application/nappdf', 'application/x-pdf', 'image/pdf'], + 'pdf.bz2' => ['application/x-bzpdf'], + 'pdf.gz' => ['application/x-gzpdf'], + 'pdf.lz' => ['application/x-lzpdf'], + 'pdf.xz' => ['application/x-xzpdf'], + 'pef' => ['image/x-pentax-pef'], + 'pem' => ['application/x-x509-ca-cert'], + 'perl' => ['application/x-perl', 'text/x-perl'], + 'pfa' => ['application/x-font-type1'], + 'pfb' => ['application/x-font-type1'], + 'pfm' => ['application/x-font-type1', 'image/x-pfm'], + 'pfr' => ['application/font-tdpfr', 'application/vnd.truedoc'], + 'pfx' => ['application/pkcs12', 'application/x-pkcs12'], + 'pgm' => ['image/x-portable-graymap'], + 'pgn' => ['application/vnd.chess-pgn', 'application/x-chess-pgn'], + 'pgp' => ['application/pgp', 'application/pgp-encrypted', 'application/pgp-keys', 'application/pgp-signature'], + 'php' => ['application/x-php', 'application/x-httpd-php'], + 'php3' => ['application/x-php'], + 'php4' => ['application/x-php'], + 'php5' => ['application/x-php'], + 'phps' => ['application/x-php'], + 'pic' => ['image/x-pict'], + 'pict' => ['image/x-pict'], + 'pict1' => ['image/x-pict'], + 'pict2' => ['image/x-pict'], + 'pk' => ['application/x-tex-pk'], + 'pkg' => ['application/x-xar'], + 'pki' => ['application/pkixcmp'], + 'pkipath' => ['application/pkix-pkipath'], + 'pkpass' => ['application/vnd.apple.pkpass'], + 'pkr' => ['application/pgp-keys'], + 'pl' => ['application/x-perl', 'text/x-perl'], + 'pla' => ['audio/x-iriver-pla'], + 'plb' => ['application/vnd.3gpp.pic-bw-large'], + 'plc' => ['application/vnd.mobius.plc'], + 'plf' => ['application/vnd.pocketlearn'], + 'pln' => ['application/x-planperfect'], + 'pls' => ['application/pls', 'application/pls+xml', 'audio/scpls', 'audio/x-scpls'], + 'pm' => ['application/x-pagemaker', 'application/x-perl', 'text/x-perl'], + 'pm6' => ['application/x-pagemaker'], + 'pmd' => ['application/x-pagemaker'], + 'pml' => ['application/vnd.ctc-posml'], + 'png' => ['image/png', 'image/apng', 'image/vnd.mozilla.apng'], + 'pnm' => ['image/x-portable-anymap'], + 'pntg' => ['image/x-macpaint'], + 'po' => ['application/x-gettext', 'text/x-gettext-translation', 'text/x-po'], + 'pod' => ['application/x-perl', 'text/x-perl'], + 'por' => ['application/x-spss-por'], + 'portpkg' => ['application/vnd.macports.portpkg'], + 'pot' => ['application/mspowerpoint', 'application/powerpoint', 'application/vnd.ms-powerpoint', 'application/x-mspowerpoint', 'text/x-gettext-translation-template', 'text/x-pot'], + 'potm' => ['application/vnd.ms-powerpoint.template.macroenabled.12'], + 'potx' => ['application/vnd.openxmlformats-officedocument.presentationml.template'], + 'ppam' => ['application/vnd.ms-powerpoint.addin.macroenabled.12'], + 'ppd' => ['application/vnd.cups-ppd'], + 'ppm' => ['image/x-portable-pixmap'], + 'pps' => ['application/mspowerpoint', 'application/powerpoint', 'application/vnd.ms-powerpoint', 'application/x-mspowerpoint'], + 'ppsm' => ['application/vnd.ms-powerpoint.slideshow.macroenabled.12'], + 'ppsx' => ['application/vnd.openxmlformats-officedocument.presentationml.slideshow'], + 'ppt' => ['application/vnd.ms-powerpoint', 'application/mspowerpoint', 'application/powerpoint', 'application/x-mspowerpoint'], + 'pptm' => ['application/vnd.ms-powerpoint.presentation.macroenabled.12'], + 'pptx' => ['application/vnd.openxmlformats-officedocument.presentationml.presentation'], + 'ppz' => ['application/mspowerpoint', 'application/powerpoint', 'application/vnd.ms-powerpoint', 'application/x-mspowerpoint'], + 'pqa' => ['application/vnd.palm', 'application/x-palm-database'], + 'prc' => ['application/vnd.palm', 'application/x-mobipocket-ebook', 'application/x-palm-database', 'application/x-pilot', 'model/prc'], + 'pre' => ['application/vnd.lotus-freelance'], + 'prf' => ['application/pics-rules'], + 'provx' => ['application/provenance+xml'], + 'ps' => ['application/postscript'], + 'ps.bz2' => ['application/x-bzpostscript'], + 'ps.gz' => ['application/x-gzpostscript'], + 'ps1' => ['application/x-powershell'], + 'psb' => ['application/vnd.3gpp.pic-bw-small'], + 'psd' => ['application/photoshop', 'application/x-photoshop', 'image/photoshop', 'image/psd', 'image/vnd.adobe.photoshop', 'image/x-photoshop', 'image/x-psd'], + 'psf' => ['application/x-font-linux-psf', 'audio/x-psf'], + 'psf.gz' => ['application/x-gz-font-linux-psf'], + 'psflib' => ['audio/x-psflib'], + 'psid' => ['audio/prs.sid'], + 'pskcxml' => ['application/pskc+xml'], + 'psw' => ['application/x-pocket-word'], + 'pti' => ['image/prs.pti'], + 'ptid' => ['application/vnd.pvi.ptid1'], + 'pub' => ['application/vnd.ms-publisher', 'application/x-mspublisher'], + 'pvb' => ['application/vnd.3gpp.pic-bw-var'], + 'pw' => ['application/x-pw'], + 'pwn' => ['application/vnd.3m.post-it-notes'], + 'pxd' => ['text/x-cython'], + 'pxi' => ['text/x-cython'], + 'pxr' => ['image/x-pxr'], + 'py' => ['text/x-python', 'text/x-python2', 'text/x-python3'], + 'py2' => ['text/x-python2'], + 'py3' => ['text/x-python3'], + 'pya' => ['audio/vnd.ms-playready.media.pya'], + 'pyc' => ['application/x-python-bytecode'], + 'pyi' => ['text/x-python3'], + 'pyo' => ['application/x-python-bytecode', 'model/vnd.pytha.pyox'], + 'pyox' => ['model/vnd.pytha.pyox'], + 'pys' => ['application/x-pyspread-bz-spreadsheet'], + 'pysu' => ['application/x-pyspread-spreadsheet'], + 'pyv' => ['video/vnd.ms-playready.media.pyv'], + 'pyx' => ['text/x-cython'], + 'qam' => ['application/vnd.epson.quickanime'], + 'qbo' => ['application/vnd.intu.qbo'], + 'qbrew' => ['application/x-qbrew'], + 'qcow' => ['application/x-qemu-disk'], + 'qcow2' => ['application/x-qemu-disk'], + 'qd' => ['application/x-fd-file', 'application/x-raw-floppy-disk-image'], + 'qed' => ['application/x-qed-disk'], + 'qfx' => ['application/vnd.intu.qfx'], + 'qif' => ['application/x-qw', 'image/x-quicktime'], + 'qml' => ['text/x-qml'], + 'qmlproject' => ['text/x-qml'], + 'qmltypes' => ['text/x-qml'], + 'qoi' => ['image/qoi'], + 'qp' => ['application/x-qpress'], + 'qps' => ['application/vnd.publishare-delta-tree'], + 'qpw' => ['application/x-quattropro'], + 'qs' => ['application/sparql-query'], + 'qt' => ['video/quicktime'], + 'qti' => ['application/x-qtiplot'], + 'qti.gz' => ['application/x-qtiplot'], + 'qtif' => ['image/x-quicktime'], + 'qtl' => ['application/x-quicktime-media-link', 'application/x-quicktimeplayer'], + 'qtvr' => ['video/quicktime'], + 'qwd' => ['application/vnd.quark.quarkxpress'], + 'qwt' => ['application/vnd.quark.quarkxpress'], + 'qxb' => ['application/vnd.quark.quarkxpress'], + 'qxd' => ['application/vnd.quark.quarkxpress'], + 'qxl' => ['application/vnd.quark.quarkxpress'], + 'qxp' => ['application/vnd.quark.quarkxpress'], + 'qxt' => ['application/vnd.quark.quarkxpress'], + 'ra' => ['audio/vnd.m-realaudio', 'audio/vnd.rn-realaudio', 'audio/x-pn-realaudio', 'audio/x-realaudio'], + 'raf' => ['image/x-fuji-raf'], + 'ram' => ['application/ram', 'audio/x-pn-realaudio'], + 'raml' => ['application/raml+yaml'], + 'rapd' => ['application/route-apd+xml'], + 'rar' => ['application/x-rar-compressed', 'application/vnd.rar', 'application/x-rar'], + 'ras' => ['image/x-cmu-raster'], + 'raw' => ['image/x-panasonic-raw', 'image/x-panasonic-rw'], + 'raw-disk-image' => ['application/vnd.efi.img', 'application/x-raw-disk-image'], + 'raw-disk-image.xz' => ['application/x-raw-disk-image-xz-compressed'], + 'rax' => ['audio/vnd.m-realaudio', 'audio/vnd.rn-realaudio', 'audio/x-pn-realaudio'], + 'rb' => ['application/x-ruby'], + 'rcprofile' => ['application/vnd.ipunplugged.rcprofile'], + 'rdf' => ['application/rdf+xml', 'text/rdf'], + 'rdfs' => ['application/rdf+xml', 'text/rdf'], + 'rdz' => ['application/vnd.data-vision.rdz'], + 'reg' => ['text/x-ms-regedit'], + 'rej' => ['application/x-reject', 'text/x-reject'], + 'relo' => ['application/p2p-overlay+xml'], + 'rep' => ['application/vnd.businessobjects'], + 'res' => ['application/x-dtbresource+xml', 'application/x-godot-resource'], + 'rgb' => ['image/x-rgb'], + 'rif' => ['application/reginfo+xml'], + 'rip' => ['audio/vnd.rip'], + 'ris' => ['application/x-research-info-systems'], + 'rl' => ['application/resource-lists+xml'], + 'rlc' => ['image/vnd.fujixerox.edmics-rlc'], + 'rld' => ['application/resource-lists-diff+xml'], + 'rle' => ['image/rle'], + 'rm' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'], + 'rmi' => ['audio/midi'], + 'rmj' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'], + 'rmm' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'], + 'rmp' => ['audio/x-pn-realaudio-plugin'], + 'rms' => ['application/vnd.jcp.javame.midlet-rms', 'application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'], + 'rmvb' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'], + 'rmx' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'], + 'rnc' => ['application/relax-ng-compact-syntax', 'application/x-rnc'], + 'rng' => ['application/xml', 'text/xml'], + 'roa' => ['application/rpki-roa'], + 'roff' => ['application/x-troff', 'text/troff', 'text/x-troff'], + 'ros' => ['text/x-common-lisp'], + 'rp' => ['image/vnd.rn-realpix'], + 'rp9' => ['application/vnd.cloanto.rp9'], + 'rpm' => ['application/x-redhat-package-manager', 'application/x-rpm'], + 'rpss' => ['application/vnd.nokia.radio-presets'], + 'rpst' => ['application/vnd.nokia.radio-preset'], + 'rq' => ['application/sparql-query'], + 'rs' => ['application/rls-services+xml', 'text/rust'], + 'rsat' => ['application/atsc-rsat+xml'], + 'rsd' => ['application/rsd+xml'], + 'rsheet' => ['application/urc-ressheet+xml'], + 'rss' => ['application/rss+xml', 'text/rss'], + 'rst' => ['text/x-rst'], + 'rt' => ['text/vnd.rn-realtext'], + 'rtf' => ['application/rtf', 'text/rtf'], + 'rtx' => ['text/richtext'], + 'run' => ['application/x-makeself'], + 'rusd' => ['application/route-usd+xml'], + 'rv' => ['video/vnd.rn-realvideo', 'video/x-real-video'], + 'rvx' => ['video/vnd.rn-realvideo', 'video/x-real-video'], + 'rw2' => ['image/x-panasonic-raw2', 'image/x-panasonic-rw2'], + 'rz' => ['application/x-rzip'], + 's' => ['text/x-asm'], + 's3m' => ['audio/s3m', 'audio/x-s3m'], + 'saf' => ['application/vnd.yamaha.smaf-audio'], + 'sage' => ['text/x-sagemath'], + 'sam' => ['application/x-amipro'], + 'sami' => ['application/x-sami'], + 'sap' => ['application/x-sap-file', 'application/x-thomson-sap-image'], + 'sass' => ['text/x-sass'], + 'sav' => ['application/x-spss-sav', 'application/x-spss-savefile'], + 'sbml' => ['application/sbml+xml'], + 'sc' => ['application/vnd.ibm.secure-container', 'text/x-scala'], + 'scala' => ['text/x-scala'], + 'scd' => ['application/x-msschedule'], + 'scm' => ['application/vnd.lotus-screencam', 'text/x-scheme'], + 'scn' => ['application/x-godot-scene'], + 'scope' => ['text/x-systemd-unit'], + 'scq' => ['application/scvp-cv-request'], + 'scr' => ['application/vnd.microsoft.portable-executable', 'application/x-ms-dos-executable', 'application/x-ms-ne-executable', 'application/x-msdownload'], + 'scs' => ['application/scvp-cv-response'], + 'scss' => ['text/x-scss'], + 'sct' => ['image/x-sct'], + 'scurl' => ['text/vnd.curl.scurl'], + 'sda' => ['application/vnd.stardivision.draw', 'application/x-stardraw'], + 'sdc' => ['application/vnd.stardivision.calc', 'application/x-starcalc'], + 'sdd' => ['application/vnd.stardivision.impress', 'application/x-starimpress'], + 'sdkd' => ['application/vnd.solent.sdkm+xml'], + 'sdkm' => ['application/vnd.solent.sdkm+xml'], + 'sdm' => ['application/vnd.stardivision.mail'], + 'sdp' => ['application/sdp', 'application/vnd.sdp', 'application/vnd.stardivision.impress-packed', 'application/x-sdp'], + 'sds' => ['application/vnd.stardivision.chart', 'application/x-starchart'], + 'sdw' => ['application/vnd.stardivision.writer', 'application/x-starwriter'], + 'sea' => ['application/x-sea'], + 'see' => ['application/vnd.seemail'], + 'seed' => ['application/vnd.fdsn.seed'], + 'sema' => ['application/vnd.sema'], + 'semd' => ['application/vnd.semd'], + 'semf' => ['application/vnd.semf'], + 'senmlx' => ['application/senml+xml'], + 'sensmlx' => ['application/sensml+xml'], + 'ser' => ['application/java-serialized-object'], + 'service' => ['text/x-dbus-service', 'text/x-systemd-unit'], + 'setpay' => ['application/set-payment-initiation'], + 'setreg' => ['application/set-registration-initiation'], + 'sfc' => ['application/vnd.nintendo.snes.rom', 'application/x-snes-rom'], + 'sfd-hdstx' => ['application/vnd.hydrostatix.sof-data'], + 'sfs' => ['application/vnd.spotfire.sfs', 'application/vnd.squashfs'], + 'sfv' => ['text/x-sfv'], + 'sg' => ['application/x-sg1000-rom'], + 'sgb' => ['application/x-gameboy-rom'], + 'sgd' => ['application/x-genesis-rom'], + 'sgf' => ['application/x-go-sgf'], + 'sgi' => ['image/sgi', 'image/x-sgi'], + 'sgl' => ['application/vnd.stardivision.writer-global', 'application/x-starwriter-global'], + 'sgm' => ['text/sgml'], + 'sgml' => ['text/sgml'], + 'sh' => ['application/x-sh', 'application/x-shellscript', 'text/x-sh'], + 'shape' => ['application/x-dia-shape'], + 'shar' => ['application/x-shar'], + 'shex' => ['text/shex'], + 'shf' => ['application/shf+xml'], + 'shn' => ['application/x-shorten', 'audio/x-shorten'], + 'shtml' => ['text/html'], + 'siag' => ['application/x-siag'], + 'sid' => ['audio/prs.sid', 'image/x-mrsid-image'], + 'sieve' => ['application/sieve'], + 'sig' => ['application/pgp-signature'], + 'sik' => ['application/x-trash'], + 'sil' => ['audio/silk'], + 'silo' => ['model/mesh'], + 'sis' => ['application/vnd.symbian.install'], + 'sisx' => ['application/vnd.symbian.install', 'x-epoc/x-sisx-app'], + 'sit' => ['application/x-stuffit', 'application/stuffit', 'application/x-sit'], + 'sitx' => ['application/x-sitx', 'application/x-stuffitx'], + 'siv' => ['application/sieve'], + 'sk' => ['image/x-skencil'], + 'sk1' => ['image/x-skencil'], + 'skd' => ['application/vnd.koan'], + 'skm' => ['application/vnd.koan'], + 'skp' => ['application/vnd.koan'], + 'skr' => ['application/pgp-keys'], + 'skt' => ['application/vnd.koan'], + 'sldm' => ['application/vnd.ms-powerpoint.slide.macroenabled.12'], + 'sldx' => ['application/vnd.openxmlformats-officedocument.presentationml.slide'], + 'slice' => ['text/x-systemd-unit'], + 'slim' => ['text/slim'], + 'slk' => ['application/x-sylk', 'text/spreadsheet'], + 'slm' => ['text/slim'], + 'sls' => ['application/route-s-tsid+xml'], + 'slt' => ['application/vnd.epson.salt'], + 'sm' => ['application/vnd.stepmania.stepchart'], + 'smaf' => ['application/vnd.smaf', 'application/x-smaf'], + 'smc' => ['application/vnd.nintendo.snes.rom', 'application/x-snes-rom'], + 'smd' => ['application/x-genesis-rom', 'application/x-starmail'], + 'smf' => ['application/vnd.stardivision.math', 'application/x-starmath'], + 'smi' => ['application/smil', 'application/smil+xml', 'application/x-sami'], + 'smil' => ['application/smil', 'application/smil+xml'], + 'smk' => ['video/vnd.radgamettools.smacker'], + 'sml' => ['application/smil', 'application/smil+xml'], + 'sms' => ['application/x-sms-rom'], + 'smv' => ['video/x-smv'], + 'smzip' => ['application/vnd.stepmania.package'], + 'snap' => ['application/vnd.snap'], + 'snd' => ['audio/basic'], + 'snf' => ['application/x-font-snf'], + 'so' => ['application/x-sharedlib'], + 'socket' => ['text/x-systemd-unit'], + 'spc' => ['application/x-pkcs7-certificates'], + 'spd' => ['application/x-font-speedo'], + 'spdx' => ['text/spdx'], + 'spec' => ['text/x-rpm-spec'], + 'spf' => ['application/vnd.yamaha.smaf-phrase'], + 'spl' => ['application/futuresplash', 'application/vnd.adobe.flash.movie', 'application/x-futuresplash', 'application/x-shockwave-flash'], + 'spm' => ['application/x-source-rpm'], + 'spot' => ['text/vnd.in3d.spot'], + 'spp' => ['application/scvp-vp-response'], + 'spq' => ['application/scvp-vp-request'], + 'spx' => ['application/x-apple-systemprofiler+xml', 'audio/ogg', 'audio/x-speex', 'audio/x-speex+ogg'], + 'sqfs' => ['application/vnd.squashfs'], + 'sql' => ['application/sql', 'application/x-sql', 'text/x-sql'], + 'sqlite2' => ['application/x-sqlite2'], + 'sqlite3' => ['application/vnd.sqlite3', 'application/x-sqlite3'], + 'sqsh' => ['application/vnd.squashfs'], + 'squashfs' => ['application/vnd.squashfs'], + 'sr2' => ['image/x-sony-sr2'], + 'src' => ['application/x-wais-source'], + 'src.rpm' => ['application/x-source-rpm'], + 'srf' => ['image/x-sony-srf'], + 'srt' => ['application/x-srt', 'application/x-subrip'], + 'sru' => ['application/sru+xml'], + 'srx' => ['application/sparql-results+xml'], + 'ss' => ['text/x-scheme'], + 'ssa' => ['text/x-ssa'], + 'ssdl' => ['application/ssdl+xml'], + 'sse' => ['application/vnd.kodak-descriptor'], + 'ssf' => ['application/vnd.epson.ssf'], + 'ssml' => ['application/ssml+xml'], + 'st' => ['application/vnd.sailingtracker.track'], + 'stc' => ['application/vnd.sun.xml.calc.template'], + 'std' => ['application/vnd.sun.xml.draw.template'], + 'step' => ['model/step'], + 'stf' => ['application/vnd.wt.stf'], + 'sti' => ['application/vnd.sun.xml.impress.template'], + 'stk' => ['application/hyperstudio'], + 'stl' => ['application/vnd.ms-pki.stl', 'model/stl', 'model/x.stl-ascii', 'model/x.stl-binary'], + 'stm' => ['audio/x-stm'], + 'stp' => ['model/step'], + 'stpx' => ['model/step+xml'], + 'stpxz' => ['model/step-xml+zip'], + 'stpz' => ['model/step+zip'], + 'str' => ['application/vnd.pg.format'], + 'stw' => ['application/vnd.sun.xml.writer.template'], + 'sty' => ['application/x-tex', 'text/x-tex'], + 'styl' => ['text/stylus'], + 'stylus' => ['text/stylus'], + 'sub' => ['image/vnd.dvb.subtitle', 'text/vnd.dvb.subtitle', 'text/x-microdvd', 'text/x-mpsub', 'text/x-subviewer'], + 'sun' => ['image/x-sun-raster'], + 'sus' => ['application/vnd.sus-calendar'], + 'susp' => ['application/vnd.sus-calendar'], + 'sv' => ['text/x-svsrc'], + 'sv4cpio' => ['application/x-sv4cpio'], + 'sv4crc' => ['application/x-sv4crc'], + 'svc' => ['application/vnd.dvb.service'], + 'svd' => ['application/vnd.svd'], + 'svg' => ['image/svg+xml', 'image/svg'], + 'svg.gz' => ['image/svg+xml-compressed'], + 'svgz' => ['image/svg+xml', 'image/svg+xml-compressed'], + 'svh' => ['text/x-svhdr'], + 'swa' => ['application/x-director'], + 'swap' => ['text/x-systemd-unit'], + 'swf' => ['application/futuresplash', 'application/vnd.adobe.flash.movie', 'application/x-shockwave-flash'], + 'swi' => ['application/vnd.aristanetworks.swi'], + 'swidtag' => ['application/swid+xml'], + 'swm' => ['application/x-ms-wim'], + 'sxc' => ['application/vnd.sun.xml.calc'], + 'sxd' => ['application/vnd.sun.xml.draw'], + 'sxg' => ['application/vnd.sun.xml.writer.global'], + 'sxi' => ['application/vnd.sun.xml.impress'], + 'sxm' => ['application/vnd.sun.xml.math'], + 'sxw' => ['application/vnd.sun.xml.writer'], + 'sylk' => ['application/x-sylk', 'text/spreadsheet'], + 'sys' => ['application/vnd.microsoft.portable-executable'], + 't' => ['application/x-perl', 'application/x-troff', 'text/troff', 'text/x-perl', 'text/x-troff'], + 't2t' => ['text/x-txt2tags'], + 't3' => ['application/x-t3vm-image'], + 't38' => ['image/t38'], + 'taglet' => ['application/vnd.mynfc'], + 'tak' => ['audio/x-tak'], + 'tao' => ['application/vnd.tao.intent-module-archive'], + 'tap' => ['image/vnd.tencent.tap'], + 'tar' => ['application/x-tar', 'application/x-gtar'], + 'tar.Z' => ['application/x-tarz'], + 'tar.bz' => ['application/x-bzip1-compressed-tar'], + 'tar.bz2' => ['application/x-bzip-compressed-tar', 'application/x-bzip2-compressed-tar'], + 'tar.bz3' => ['application/x-bzip3-compressed-tar'], + 'tar.gz' => ['application/x-compressed-tar'], + 'tar.lrz' => ['application/x-lrzip-compressed-tar'], + 'tar.lz' => ['application/x-lzip-compressed-tar'], + 'tar.lz4' => ['application/x-lz4-compressed-tar'], + 'tar.lzma' => ['application/x-lzma-compressed-tar'], + 'tar.lzo' => ['application/x-tzo'], + 'tar.rz' => ['application/x-rzip-compressed-tar'], + 'tar.xz' => ['application/x-xz-compressed-tar'], + 'tar.zst' => ['application/x-zstd-compressed-tar'], + 'target' => ['text/x-systemd-unit'], + 'taz' => ['application/x-tarz'], + 'tb2' => ['application/x-bzip-compressed-tar', 'application/x-bzip2-compressed-tar'], + 'tbz' => ['application/x-bzip1-compressed-tar'], + 'tbz2' => ['application/x-bzip-compressed-tar', 'application/x-bzip2-compressed-tar'], + 'tbz3' => ['application/x-bzip3-compressed-tar'], + 'tcap' => ['application/vnd.3gpp2.tcap'], + 'tcl' => ['application/x-tcl', 'text/tcl', 'text/x-tcl'], + 'td' => ['application/urc-targetdesc+xml'], + 'teacher' => ['application/vnd.smart.teacher'], + 'tei' => ['application/tei+xml'], + 'teicorpus' => ['application/tei+xml'], + 'tex' => ['application/x-tex', 'text/x-tex'], + 'texi' => ['application/x-texinfo', 'text/x-texinfo'], + 'texinfo' => ['application/x-texinfo', 'text/x-texinfo'], + 'text' => ['text/plain'], + 'tfi' => ['application/thraud+xml'], + 'tfm' => ['application/x-tex-tfm'], + 'tfx' => ['image/tiff-fx'], + 'tga' => ['application/tga', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'], + 'tgz' => ['application/x-compressed-tar'], + 'theme' => ['application/x-theme'], + 'themepack' => ['application/x-windows-themepack'], + 'thmx' => ['application/vnd.ms-officetheme'], + 'tif' => ['image/tiff'], + 'tiff' => ['image/tiff'], + 'timer' => ['text/x-systemd-unit'], + 'tk' => ['application/x-tcl', 'text/tcl', 'text/x-tcl'], + 'tlrz' => ['application/x-lrzip-compressed-tar'], + 'tlz' => ['application/x-lzma-compressed-tar'], + 'tmo' => ['application/vnd.tmobile-livetv'], + 'tmx' => ['application/x-tiled-tmx'], + 'tnef' => ['application/ms-tnef', 'application/vnd.ms-tnef'], + 'tnf' => ['application/ms-tnef', 'application/vnd.ms-tnef'], + 'toc' => ['application/x-cdrdao-toc'], + 'toml' => ['application/toml'], + 'torrent' => ['application/x-bittorrent'], + 'tpic' => ['application/tga', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'], + 'tpl' => ['application/vnd.groove-tool-template'], + 'tpt' => ['application/vnd.trid.tpt'], + 'tr' => ['application/x-troff', 'text/troff', 'text/x-troff'], + 'tra' => ['application/vnd.trueapp'], + 'tres' => ['application/x-godot-resource'], + 'trig' => ['application/trig', 'application/x-trig'], + 'trm' => ['application/x-msterminal'], + 'trz' => ['application/x-rzip-compressed-tar'], + 'ts' => ['application/x-linguist', 'text/vnd.qt.linguist', 'text/vnd.trolltech.linguist', 'video/mp2t'], + 'tscn' => ['application/x-godot-scene'], + 'tsd' => ['application/timestamped-data'], + 'tsv' => ['text/tab-separated-values'], + 'tsx' => ['application/x-tiled-tsx'], + 'tta' => ['audio/tta', 'audio/x-tta'], + 'ttc' => ['font/collection'], + 'ttf' => ['application/x-font-truetype', 'application/x-font-ttf', 'font/ttf'], + 'ttl' => ['text/turtle'], + 'ttml' => ['application/ttml+xml'], + 'ttx' => ['application/x-font-ttx'], + 'twd' => ['application/vnd.simtech-mindmapper'], + 'twds' => ['application/vnd.simtech-mindmapper'], + 'twig' => ['text/x-twig'], + 'txd' => ['application/vnd.genomatix.tuxedo'], + 'txf' => ['application/vnd.mobius.txf'], + 'txt' => ['text/plain'], + 'txz' => ['application/x-xz-compressed-tar'], + 'typ' => ['text/x-typst'], + 'tzo' => ['application/x-tzo'], + 'tzst' => ['application/x-zstd-compressed-tar'], + 'u32' => ['application/x-authorware-bin'], + 'u3d' => ['model/u3d'], + 'u8dsn' => ['message/global-delivery-status'], + 'u8hdr' => ['message/global-headers'], + 'u8mdn' => ['message/global-disposition-notification'], + 'u8msg' => ['message/global'], + 'ubj' => ['application/ubjson'], + 'udeb' => ['application/vnd.debian.binary-package', 'application/x-deb', 'application/x-debian-package'], + 'ufd' => ['application/vnd.ufdl'], + 'ufdl' => ['application/vnd.ufdl'], + 'ufraw' => ['application/x-ufraw'], + 'ui' => ['application/x-designer', 'application/x-gtk-builder'], + 'uil' => ['text/x-uil'], + 'ult' => ['audio/x-mod'], + 'ulx' => ['application/x-glulx'], + 'umj' => ['application/vnd.umajin'], + 'unf' => ['application/x-nes-rom'], + 'uni' => ['audio/x-mod'], + 'unif' => ['application/x-nes-rom'], + 'unityweb' => ['application/vnd.unity'], + 'uo' => ['application/vnd.uoml+xml'], + 'uoml' => ['application/vnd.uoml+xml'], + 'uri' => ['text/uri-list'], + 'uris' => ['text/uri-list'], + 'url' => ['application/x-mswinurl'], + 'urls' => ['text/uri-list'], + 'usda' => ['model/vnd.usda'], + 'usdz' => ['model/vnd.usdz+zip'], + 'ustar' => ['application/x-ustar'], + 'utz' => ['application/vnd.uiq.theme'], + 'uu' => ['text/x-uuencode'], + 'uue' => ['text/x-uuencode', 'zz-application/zz-winassoc-uu'], + 'uva' => ['audio/vnd.dece.audio'], + 'uvd' => ['application/vnd.dece.data'], + 'uvf' => ['application/vnd.dece.data'], + 'uvg' => ['image/vnd.dece.graphic'], + 'uvh' => ['video/vnd.dece.hd'], + 'uvi' => ['image/vnd.dece.graphic'], + 'uvm' => ['video/vnd.dece.mobile'], + 'uvp' => ['video/vnd.dece.pd'], + 'uvs' => ['video/vnd.dece.sd'], + 'uvt' => ['application/vnd.dece.ttml+xml'], + 'uvu' => ['video/vnd.uvvu.mp4'], + 'uvv' => ['video/vnd.dece.video'], + 'uvva' => ['audio/vnd.dece.audio'], + 'uvvd' => ['application/vnd.dece.data'], + 'uvvf' => ['application/vnd.dece.data'], + 'uvvg' => ['image/vnd.dece.graphic'], + 'uvvh' => ['video/vnd.dece.hd'], + 'uvvi' => ['image/vnd.dece.graphic'], + 'uvvm' => ['video/vnd.dece.mobile'], + 'uvvp' => ['video/vnd.dece.pd'], + 'uvvs' => ['video/vnd.dece.sd'], + 'uvvt' => ['application/vnd.dece.ttml+xml'], + 'uvvu' => ['video/vnd.uvvu.mp4'], + 'uvvv' => ['video/vnd.dece.video'], + 'uvvx' => ['application/vnd.dece.unspecified'], + 'uvvz' => ['application/vnd.dece.zip'], + 'uvx' => ['application/vnd.dece.unspecified'], + 'uvz' => ['application/vnd.dece.zip'], + 'v' => ['text/x-verilog'], + 'v64' => ['application/x-n64-rom'], + 'vala' => ['text/x-vala'], + 'vapi' => ['text/x-vala'], + 'vb' => ['application/x-virtual-boy-rom', 'text/x-vb'], + 'vbe' => ['text/vbscript.encode'], + 'vbox' => ['application/x-virtualbox-vbox'], + 'vbox-extpack' => ['application/x-virtualbox-vbox-extpack'], + 'vbs' => ['text/vbs', 'text/vbscript'], + 'vcard' => ['text/directory', 'text/vcard', 'text/x-vcard'], + 'vcd' => ['application/x-cdlink'], + 'vcf' => ['text/x-vcard', 'text/directory', 'text/vcard'], + 'vcg' => ['application/vnd.groove-vcard'], + 'vcs' => ['application/ics', 'text/calendar', 'text/x-vcalendar'], + 'vct' => ['text/directory', 'text/vcard', 'text/x-vcard'], + 'vcx' => ['application/vnd.vcx'], + 'vda' => ['application/tga', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'], + 'vdi' => ['application/x-vdi-disk', 'application/x-virtualbox-vdi'], + 'vds' => ['model/vnd.sap.vds'], + 'vhd' => ['application/x-vhd-disk', 'application/x-virtualbox-vhd', 'text/x-vhdl'], + 'vhdl' => ['text/x-vhdl'], + 'vhdx' => ['application/x-vhdx-disk', 'application/x-virtualbox-vhdx'], + 'vis' => ['application/vnd.visionary'], + 'viv' => ['video/vivo', 'video/vnd.vivo'], + 'vivo' => ['video/vivo', 'video/vnd.vivo'], + 'vlc' => ['application/m3u', 'audio/m3u', 'audio/mpegurl', 'audio/x-m3u', 'audio/x-mp3-playlist', 'audio/x-mpegurl'], + 'vmdk' => ['application/x-virtualbox-vmdk', 'application/x-vmdk-disk'], + 'vob' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2', 'video/x-ms-vob'], + 'voc' => ['audio/x-voc'], + 'vor' => ['application/vnd.stardivision.writer', 'application/x-starwriter'], + 'vox' => ['application/x-authorware-bin'], + 'vpc' => ['application/x-vhd-disk', 'application/x-virtualbox-vhd'], + 'vrm' => ['model/vrml'], + 'vrml' => ['model/vrml'], + 'vsd' => ['application/vnd.visio'], + 'vsdm' => ['application/vnd.ms-visio.drawing.macroenabled.main+xml'], + 'vsdx' => ['application/vnd.ms-visio.drawing.main+xml'], + 'vsf' => ['application/vnd.vsf'], + 'vss' => ['application/vnd.visio'], + 'vssm' => ['application/vnd.ms-visio.stencil.macroenabled.main+xml'], + 'vssx' => ['application/vnd.ms-visio.stencil.main+xml'], + 'vst' => ['application/tga', 'application/vnd.visio', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'], + 'vstm' => ['application/vnd.ms-visio.template.macroenabled.main+xml'], + 'vstx' => ['application/vnd.ms-visio.template.main+xml'], + 'vsw' => ['application/vnd.visio'], + 'vtf' => ['image/vnd.valve.source.texture'], + 'vtt' => ['text/vtt'], + 'vtu' => ['model/vnd.vtu'], + 'vxml' => ['application/voicexml+xml'], + 'w3d' => ['application/x-director'], + 'wad' => ['application/x-doom', 'application/x-doom-wad', 'application/x-wii-wad'], + 'wadl' => ['application/vnd.sun.wadl+xml'], + 'war' => ['application/java-archive'], + 'wasm' => ['application/wasm'], + 'wav' => ['audio/wav', 'audio/vnd.wave', 'audio/wave', 'audio/x-wav'], + 'wax' => ['application/x-ms-asx', 'audio/x-ms-asx', 'audio/x-ms-wax', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'], + 'wb1' => ['application/x-quattropro'], + 'wb2' => ['application/x-quattropro'], + 'wb3' => ['application/x-quattropro'], + 'wbmp' => ['image/vnd.wap.wbmp'], + 'wbs' => ['application/vnd.criticaltools.wbs+xml'], + 'wbxml' => ['application/vnd.wap.wbxml'], + 'wcm' => ['application/vnd.ms-works'], + 'wdb' => ['application/vnd.ms-works'], + 'wdp' => ['image/jxr', 'image/vnd.ms-photo'], + 'weba' => ['audio/webm'], + 'webapp' => ['application/x-web-app-manifest+json'], + 'webm' => ['video/webm'], + 'webmanifest' => ['application/manifest+json'], + 'webp' => ['image/webp'], + 'wg' => ['application/vnd.pmi.widget'], + 'wgsl' => ['text/wgsl'], + 'wgt' => ['application/widget'], + 'wif' => ['application/watcherinfo+xml'], + 'wim' => ['application/x-ms-wim'], + 'wk1' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'], + 'wk3' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'], + 'wk4' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'], + 'wkdownload' => ['application/x-partial-download'], + 'wks' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/vnd.ms-works', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'], + 'wm' => ['video/x-ms-wm'], + 'wma' => ['audio/x-ms-wma', 'audio/wma'], + 'wmd' => ['application/x-ms-wmd'], + 'wmf' => ['application/wmf', 'application/x-msmetafile', 'application/x-wmf', 'image/wmf', 'image/x-win-metafile', 'image/x-wmf'], + 'wml' => ['text/vnd.wap.wml'], + 'wmlc' => ['application/vnd.wap.wmlc'], + 'wmls' => ['text/vnd.wap.wmlscript'], + 'wmlsc' => ['application/vnd.wap.wmlscriptc'], + 'wmv' => ['audio/x-ms-wmv', 'video/x-ms-wmv'], + 'wmx' => ['application/x-ms-asx', 'audio/x-ms-asx', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'], + 'wmz' => ['application/x-ms-wmz', 'application/x-msmetafile'], + 'woff' => ['application/font-woff', 'application/x-font-woff', 'font/woff'], + 'woff2' => ['font/woff2'], + 'wp' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'], + 'wp4' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'], + 'wp5' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'], + 'wp6' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'], + 'wpd' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'], + 'wpg' => ['application/x-wpg'], + 'wpl' => ['application/vnd.ms-wpl'], + 'wpp' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'], + 'wps' => ['application/vnd.ms-works'], + 'wqd' => ['application/vnd.wqd'], + 'wri' => ['application/x-mswrite'], + 'wrl' => ['model/vrml'], + 'ws' => ['application/x-wonderswan-rom'], + 'wsc' => ['application/x-wonderswan-color-rom', 'message/vnd.wfa.wsc'], + 'wsdl' => ['application/wsdl+xml'], + 'wsgi' => ['text/x-python'], + 'wspolicy' => ['application/wspolicy+xml'], + 'wtb' => ['application/vnd.webturbo'], + 'wv' => ['audio/x-wavpack'], + 'wvc' => ['audio/x-wavpack-correction'], + 'wvp' => ['audio/x-wavpack'], + 'wvx' => ['application/x-ms-asx', 'audio/x-ms-asx', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'], + 'wwf' => ['application/wwf', 'application/x-wwf'], + 'x32' => ['application/x-authorware-bin'], + 'x3d' => ['model/x3d+xml'], + 'x3db' => ['model/x3d+binary', 'model/x3d+fastinfoset'], + 'x3dbz' => ['model/x3d+binary'], + 'x3dv' => ['model/x3d+vrml', 'model/x3d-vrml'], + 'x3dvz' => ['model/x3d+vrml'], + 'x3dz' => ['model/x3d+xml'], + 'x3f' => ['image/x-sigma-x3f'], + 'x_b' => ['model/vnd.parasolid.transmit.binary'], + 'x_t' => ['model/vnd.parasolid.transmit.text'], + 'xac' => ['application/x-gnucash'], + 'xaml' => ['application/xaml+xml'], + 'xap' => ['application/x-silverlight-app'], + 'xar' => ['application/vnd.xara', 'application/x-xar'], + 'xav' => ['application/xcap-att+xml'], + 'xbap' => ['application/x-ms-xbap'], + 'xbd' => ['application/vnd.fujixerox.docuworks.binder'], + 'xbel' => ['application/x-xbel'], + 'xbl' => ['application/xml', 'text/xml'], + 'xbm' => ['image/x-xbitmap'], + 'xca' => ['application/xcap-caps+xml'], + 'xcf' => ['image/x-xcf'], + 'xcf.bz2' => ['image/x-compressed-xcf'], + 'xcf.gz' => ['image/x-compressed-xcf'], + 'xci' => ['application/x-nintendo-switch-xci', 'application/x-nx-xci'], + 'xcs' => ['application/calendar+xml'], + 'xdcf' => ['application/vnd.gov.sk.xmldatacontainer+xml'], + 'xdf' => ['application/mrb-consumer+xml', 'application/mrb-publish+xml', 'application/xcap-diff+xml'], + 'xdgapp' => ['application/vnd.flatpak', 'application/vnd.xdgapp'], + 'xdm' => ['application/vnd.syncml.dm+xml'], + 'xdp' => ['application/vnd.adobe.xdp+xml'], + 'xdssc' => ['application/dssc+xml'], + 'xdw' => ['application/vnd.fujixerox.docuworks'], + 'xel' => ['application/xcap-el+xml'], + 'xenc' => ['application/xenc+xml'], + 'xer' => ['application/patch-ops-error+xml', 'application/xcap-error+xml'], + 'xfdf' => ['application/vnd.adobe.xfdf', 'application/xfdf'], + 'xfdl' => ['application/vnd.xfdl'], + 'xhe' => ['audio/usac'], + 'xht' => ['application/xhtml+xml'], + 'xhtm' => ['application/vnd.pwg-xhtml-print+xml'], + 'xhtml' => ['application/xhtml+xml'], + 'xhvml' => ['application/xv+xml'], + 'xi' => ['audio/x-xi'], + 'xif' => ['image/vnd.xiff'], + 'xla' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xlam' => ['application/vnd.ms-excel.addin.macroenabled.12'], + 'xlc' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xld' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xlf' => ['application/x-xliff', 'application/x-xliff+xml', 'application/xliff+xml'], + 'xliff' => ['application/x-xliff', 'application/xliff+xml'], + 'xll' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xlm' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xlr' => ['application/vnd.ms-works'], + 'xls' => ['application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xlsb' => ['application/vnd.ms-excel.sheet.binary.macroenabled.12'], + 'xlsm' => ['application/vnd.ms-excel.sheet.macroenabled.12'], + 'xlsx' => ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'], + 'xlt' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xltm' => ['application/vnd.ms-excel.template.macroenabled.12'], + 'xltx' => ['application/vnd.openxmlformats-officedocument.spreadsheetml.template'], + 'xlw' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xm' => ['audio/x-xm', 'audio/xm'], + 'xmf' => ['audio/x-xmf', 'audio/xmf'], + 'xmi' => ['text/x-xmi'], + 'xml' => ['application/xml', 'text/xml'], + 'xns' => ['application/xcap-ns+xml'], + 'xo' => ['application/vnd.olpc-sugar'], + 'xop' => ['application/xop+xml'], + 'xpi' => ['application/x-xpinstall'], + 'xpl' => ['application/xproc+xml'], + 'xpm' => ['image/x-xpixmap', 'image/x-xpm'], + 'xpr' => ['application/vnd.is-xpr'], + 'xps' => ['application/vnd.ms-xpsdocument', 'application/xps'], + 'xpw' => ['application/vnd.intercon.formnet'], + 'xpx' => ['application/vnd.intercon.formnet'], + 'xsd' => ['application/xml', 'text/xml'], + 'xsf' => ['application/prs.xsf+xml'], + 'xsl' => ['application/xml', 'application/xslt+xml'], + 'xslfo' => ['text/x-xslfo'], + 'xslt' => ['application/xslt+xml'], + 'xsm' => ['application/vnd.syncml+xml'], + 'xspf' => ['application/x-xspf+xml', 'application/xspf+xml'], + 'xul' => ['application/vnd.mozilla.xul+xml'], + 'xvm' => ['application/xv+xml'], + 'xvml' => ['application/xv+xml'], + 'xwd' => ['image/x-xwindowdump'], + 'xyz' => ['chemical/x-xyz'], + 'xz' => ['application/x-xz'], + 'yaml' => ['application/yaml', 'application/x-yaml', 'text/x-yaml', 'text/yaml'], + 'yang' => ['application/yang'], + 'yin' => ['application/yin+xml'], + 'yml' => ['application/yaml', 'application/x-yaml', 'text/x-yaml', 'text/yaml'], + 'ymp' => ['text/x-suse-ymp'], + 'yt' => ['application/vnd.youtube.yt', 'video/vnd.youtube.yt'], + 'z1' => ['application/x-zmachine'], + 'z2' => ['application/x-zmachine'], + 'z3' => ['application/x-zmachine'], + 'z4' => ['application/x-zmachine'], + 'z5' => ['application/x-zmachine'], + 'z6' => ['application/x-zmachine'], + 'z64' => ['application/x-n64-rom'], + 'z7' => ['application/x-zmachine'], + 'z8' => ['application/x-zmachine'], + 'zabw' => ['application/x-abiword'], + 'zaz' => ['application/vnd.zzazz.deck+xml'], + 'zim' => ['application/x-openzim'], + 'zip' => ['application/zip', 'application/x-zip', 'application/x-zip-compressed'], + 'zipx' => ['application/x-zip', 'application/x-zip-compressed', 'application/zip'], + 'zir' => ['application/vnd.zul'], + 'zirz' => ['application/vnd.zul'], + 'zmm' => ['application/vnd.handheld-entertainment+xml'], + 'zoo' => ['application/x-zoo'], + 'zpaq' => ['application/x-zpaq'], + 'zsav' => ['application/x-spss-sav', 'application/x-spss-savefile'], + 'zst' => ['application/zstd'], + 'zz' => ['application/zlib'], + ]; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/MimeTypesInterface.php b/lib/SymfonyMailer/vendor/symfony/mime/MimeTypesInterface.php new file mode 100644 index 0000000..17d45ad --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/MimeTypesInterface.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +/** + * @author Fabien Potencier + */ +interface MimeTypesInterface extends MimeTypeGuesserInterface +{ + /** + * Gets the extensions for the given MIME type in decreasing order of preference. + * + * @return string[] + */ + public function getExtensions(string $mimeType): array; + + /** + * Gets the MIME types for the given extension in decreasing order of preference. + * + * @return string[] + */ + public function getMimeTypes(string $ext): array; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Part/AbstractMultipartPart.php b/lib/SymfonyMailer/vendor/symfony/mime/Part/AbstractMultipartPart.php new file mode 100644 index 0000000..1da0ddf --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Part/AbstractMultipartPart.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\Header\Headers; + +/** + * @author Fabien Potencier + */ +abstract class AbstractMultipartPart extends AbstractPart +{ + private ?string $boundary = null; + private array $parts = []; + + public function __construct(AbstractPart ...$parts) + { + parent::__construct(); + + foreach ($parts as $part) { + $this->parts[] = $part; + } + } + + /** + * @return AbstractPart[] + */ + public function getParts(): array + { + return $this->parts; + } + + public function getMediaType(): string + { + return 'multipart'; + } + + public function getPreparedHeaders(): Headers + { + $headers = parent::getPreparedHeaders(); + $headers->setHeaderParameter('Content-Type', 'boundary', $this->getBoundary()); + + return $headers; + } + + public function bodyToString(): string + { + $parts = $this->getParts(); + $string = ''; + foreach ($parts as $part) { + $string .= '--'.$this->getBoundary()."\r\n".$part->toString()."\r\n"; + } + $string .= '--'.$this->getBoundary()."--\r\n"; + + return $string; + } + + public function bodyToIterable(): iterable + { + $parts = $this->getParts(); + foreach ($parts as $part) { + yield '--'.$this->getBoundary()."\r\n"; + yield from $part->toIterable(); + yield "\r\n"; + } + yield '--'.$this->getBoundary()."--\r\n"; + } + + public function asDebugString(): string + { + $str = parent::asDebugString(); + foreach ($this->getParts() as $part) { + $lines = explode("\n", $part->asDebugString()); + $str .= "\n └ ".array_shift($lines); + foreach ($lines as $line) { + $str .= "\n |".$line; + } + } + + return $str; + } + + private function getBoundary(): string + { + return $this->boundary ??= strtr(base64_encode(random_bytes(6)), '+/', '-_'); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Part/AbstractPart.php b/lib/SymfonyMailer/vendor/symfony/mime/Part/AbstractPart.php new file mode 100644 index 0000000..130106d --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Part/AbstractPart.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\Header\Headers; + +/** + * @author Fabien Potencier + */ +abstract class AbstractPart +{ + private Headers $headers; + + public function __construct() + { + $this->headers = new Headers(); + } + + public function getHeaders(): Headers + { + return $this->headers; + } + + public function getPreparedHeaders(): Headers + { + $headers = clone $this->headers; + $headers->setHeaderBody('Parameterized', 'Content-Type', $this->getMediaType().'/'.$this->getMediaSubtype()); + + return $headers; + } + + public function toString(): string + { + return $this->getPreparedHeaders()->toString()."\r\n".$this->bodyToString(); + } + + public function toIterable(): iterable + { + yield $this->getPreparedHeaders()->toString(); + yield "\r\n"; + yield from $this->bodyToIterable(); + } + + public function asDebugString(): string + { + return $this->getMediaType().'/'.$this->getMediaSubtype(); + } + + abstract public function bodyToString(): string; + + abstract public function bodyToIterable(): iterable; + + abstract public function getMediaType(): string; + + abstract public function getMediaSubtype(): string; +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Part/DataPart.php b/lib/SymfonyMailer/vendor/symfony/mime/Part/DataPart.php new file mode 100644 index 0000000..8ae807c --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Part/DataPart.php @@ -0,0 +1,165 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Header\Headers; + +/** + * @author Fabien Potencier + */ +class DataPart extends TextPart +{ + /** @internal */ + protected array $_parent; + + private ?string $filename = null; + private string $mediaType; + private ?string $cid = null; + + /** + * @param resource|string|File $body Use a File instance to defer loading the file until rendering + */ + public function __construct($body, ?string $filename = null, ?string $contentType = null, ?string $encoding = null) + { + if ($body instanceof File && !$filename) { + $filename = $body->getFilename(); + } + + $contentType ??= $body instanceof File ? $body->getContentType() : 'application/octet-stream'; + [$this->mediaType, $subtype] = explode('/', $contentType); + + parent::__construct($body, null, $subtype, $encoding); + + if (null !== $filename) { + $this->filename = $filename; + $this->setName($filename); + } + $this->setDisposition('attachment'); + } + + public static function fromPath(string $path, ?string $name = null, ?string $contentType = null): self + { + return new self(new File($path), $name, $contentType); + } + + /** + * @return $this + */ + public function asInline(): static + { + return $this->setDisposition('inline'); + } + + /** + * @return $this + */ + public function setContentId(string $cid): static + { + if (!str_contains($cid, '@')) { + throw new InvalidArgumentException(\sprintf('The "%s" CID is invalid as it doesn\'t contain an "@".', $cid)); + } + + $this->cid = $cid; + + return $this; + } + + public function getContentId(): string + { + return $this->cid ?: $this->cid = $this->generateContentId(); + } + + public function hasContentId(): bool + { + return null !== $this->cid; + } + + public function getMediaType(): string + { + return $this->mediaType; + } + + public function getPreparedHeaders(): Headers + { + $headers = parent::getPreparedHeaders(); + + if (null !== $this->cid) { + $headers->setHeaderBody('Id', 'Content-ID', $this->cid); + } + + if (null !== $this->filename) { + $headers->setHeaderParameter('Content-Disposition', 'filename', $this->filename); + } + + return $headers; + } + + public function asDebugString(): string + { + $str = parent::asDebugString(); + if (null !== $this->filename) { + $str .= ' filename: '.$this->filename; + } + + return $str; + } + + public function getFilename(): ?string + { + return $this->filename; + } + + public function getContentType(): string + { + return implode('/', [$this->getMediaType(), $this->getMediaSubtype()]); + } + + private function generateContentId(): string + { + return bin2hex(random_bytes(16)).'@symfony'; + } + + public function __sleep(): array + { + // converts the body to a string + parent::__sleep(); + + $this->_parent = []; + foreach (['body', 'charset', 'subtype', 'disposition', 'name', 'encoding'] as $name) { + $r = new \ReflectionProperty(TextPart::class, $name); + $this->_parent[$name] = $r->getValue($this); + } + $this->_headers = $this->getHeaders(); + + return ['_headers', '_parent', 'filename', 'mediaType']; + } + + public function __wakeup(): void + { + $r = new \ReflectionProperty(AbstractPart::class, 'headers'); + $r->setValue($this, $this->_headers); + unset($this->_headers); + + if (!\is_array($this->_parent)) { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + foreach (['body', 'charset', 'subtype', 'disposition', 'name', 'encoding'] as $name) { + if (null !== $this->_parent[$name] && !\is_string($this->_parent[$name]) && !$this->_parent[$name] instanceof File) { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + $r = new \ReflectionProperty(TextPart::class, $name); + $r->setValue($this, $this->_parent[$name]); + } + unset($this->_parent); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Part/File.php b/lib/SymfonyMailer/vendor/symfony/mime/Part/File.php new file mode 100644 index 0000000..cd05a3d --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Part/File.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\MimeTypes; + +/** + * @author Fabien Potencier + */ +class File +{ + private static MimeTypes $mimeTypes; + + public function __construct( + private string $path, + private ?string $filename = null, + ) { + } + + public function getPath(): string + { + return $this->path; + } + + public function getContentType(): string + { + $ext = strtolower(pathinfo($this->path, \PATHINFO_EXTENSION)); + self::$mimeTypes ??= new MimeTypes(); + + return self::$mimeTypes->getMimeTypes($ext)[0] ?? 'application/octet-stream'; + } + + public function getSize(): int + { + return filesize($this->path); + } + + public function getFilename(): string + { + return $this->filename ??= basename($this->getPath()); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Part/MessagePart.php b/lib/SymfonyMailer/vendor/symfony/mime/Part/MessagePart.php new file mode 100644 index 0000000..8253623 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Part/MessagePart.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\Message; +use Symfony\Component\Mime\RawMessage; + +/** + * @final + * + * @author Fabien Potencier + */ +class MessagePart extends DataPart +{ + public function __construct( + private RawMessage $message, + ) { + if ($message instanceof Message) { + $name = $message->getHeaders()->getHeaderBody('Subject').'.eml'; + } else { + $name = 'email.eml'; + } + parent::__construct('', $name); + } + + public function getMediaType(): string + { + return 'message'; + } + + public function getMediaSubtype(): string + { + return 'rfc822'; + } + + public function getBody(): string + { + return $this->message->toString(); + } + + public function bodyToString(): string + { + return $this->getBody(); + } + + public function bodyToIterable(): iterable + { + return $this->message->toIterable(); + } + + public function __serialize(): array + { + return ['message' => $this->message]; + } + + public function __unserialize(array $data): void + { + $this->message = $data['message'] ?? $data["\0".self::class."\0message"]; + + $this->__construct($this->message); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/AlternativePart.php b/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/AlternativePart.php new file mode 100644 index 0000000..fd75423 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/AlternativePart.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part\Multipart; + +use Symfony\Component\Mime\Part\AbstractMultipartPart; + +/** + * @author Fabien Potencier + */ +final class AlternativePart extends AbstractMultipartPart +{ + public function getMediaSubtype(): string + { + return 'alternative'; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/DigestPart.php b/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/DigestPart.php new file mode 100644 index 0000000..27537f1 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/DigestPart.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part\Multipart; + +use Symfony\Component\Mime\Part\AbstractMultipartPart; +use Symfony\Component\Mime\Part\MessagePart; + +/** + * @author Fabien Potencier + */ +final class DigestPart extends AbstractMultipartPart +{ + public function __construct(MessagePart ...$parts) + { + parent::__construct(...$parts); + } + + public function getMediaSubtype(): string + { + return 'digest'; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/FormDataPart.php b/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/FormDataPart.php new file mode 100644 index 0000000..ca40801 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/FormDataPart.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part\Multipart; + +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Part\AbstractMultipartPart; +use Symfony\Component\Mime\Part\TextPart; + +/** + * Implements RFC 7578. + * + * @author Fabien Potencier + */ +final class FormDataPart extends AbstractMultipartPart +{ + /** + * @param array $fields + */ + public function __construct( + private array $fields = [], + ) { + parent::__construct(); + + // HTTP does not support \r\n in header values + $this->getHeaders()->setMaxLineLength(\PHP_INT_MAX); + } + + public function getMediaSubtype(): string + { + return 'form-data'; + } + + public function getParts(): array + { + return $this->prepareFields($this->fields); + } + + private function prepareFields(array $fields): array + { + $values = []; + + $prepare = function ($item, $key, $root = null) use (&$values, &$prepare) { + if (null === $root && \is_int($key) && \is_array($item)) { + if (1 !== \count($item)) { + throw new InvalidArgumentException(\sprintf('Form field values with integer keys can only have one array element, the key being the field name and the value being the field value, %d provided.', \count($item))); + } + + $key = key($item); + $item = $item[$key]; + } + + $fieldName = null !== $root ? \sprintf('%s[%s]', $root, $key) : $key; + + if (\is_array($item)) { + array_walk($item, $prepare, $fieldName); + + return; + } + + if (!\is_string($item) && !$item instanceof TextPart) { + throw new InvalidArgumentException(\sprintf('The value of the form field "%s" can only be a string, an array, or an instance of TextPart, "%s" given.', $fieldName, get_debug_type($item))); + } + + $values[] = $this->preparePart($fieldName, $item); + }; + + array_walk($fields, $prepare); + + return $values; + } + + private function preparePart(string $name, string|TextPart $value): TextPart + { + if (\is_string($value)) { + return $this->configurePart($name, new TextPart($value, 'utf-8', 'plain', '8bit')); + } + + return $this->configurePart($name, $value); + } + + private function configurePart(string $name, TextPart $part): TextPart + { + static $r; + + $r ??= new \ReflectionProperty(TextPart::class, 'encoding'); + + $part->setDisposition('form-data'); + $part->setName($name); + // HTTP does not support \r\n in header values + $part->getHeaders()->setMaxLineLength(\PHP_INT_MAX); + $r->setValue($part, '8bit'); + + return $part; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/MixedPart.php b/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/MixedPart.php new file mode 100644 index 0000000..c8d7028 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/MixedPart.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part\Multipart; + +use Symfony\Component\Mime\Part\AbstractMultipartPart; + +/** + * @author Fabien Potencier + */ +final class MixedPart extends AbstractMultipartPart +{ + public function getMediaSubtype(): string + { + return 'mixed'; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/RelatedPart.php b/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/RelatedPart.php new file mode 100644 index 0000000..18ca9f1 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Part/Multipart/RelatedPart.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part\Multipart; + +use Symfony\Component\Mime\Part\AbstractMultipartPart; +use Symfony\Component\Mime\Part\AbstractPart; + +/** + * @author Fabien Potencier + */ +final class RelatedPart extends AbstractMultipartPart +{ + public function __construct( + private AbstractPart $mainPart, + AbstractPart $part, + AbstractPart ...$parts, + ) { + $this->prepareParts($part, ...$parts); + + parent::__construct($part, ...$parts); + } + + public function getParts(): array + { + return array_merge([$this->mainPart], parent::getParts()); + } + + public function getMediaSubtype(): string + { + return 'related'; + } + + private function generateContentId(): string + { + return bin2hex(random_bytes(16)).'@symfony'; + } + + private function prepareParts(AbstractPart ...$parts): void + { + foreach ($parts as $part) { + if (!$part->getHeaders()->has('Content-ID')) { + $part->getHeaders()->setHeaderBody('Id', 'Content-ID', $this->generateContentId()); + } + } + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Part/SMimePart.php b/lib/SymfonyMailer/vendor/symfony/mime/Part/SMimePart.php new file mode 100644 index 0000000..6444d31 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Part/SMimePart.php @@ -0,0 +1,105 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\Header\Headers; + +/** + * @author Sebastiaan Stok + */ +class SMimePart extends AbstractPart +{ + /** @internal */ + protected Headers $_headers; + + public function __construct( + private iterable|string $body, + private string $type, + private string $subtype, + private array $parameters, + ) { + parent::__construct(); + } + + public function getMediaType(): string + { + return $this->type; + } + + public function getMediaSubtype(): string + { + return $this->subtype; + } + + public function bodyToString(): string + { + if (\is_string($this->body)) { + return $this->body; + } + + $body = ''; + foreach ($this->body as $chunk) { + $body .= $chunk; + } + $this->body = $body; + + return $body; + } + + public function bodyToIterable(): iterable + { + if (\is_string($this->body)) { + yield $this->body; + + return; + } + + $body = ''; + foreach ($this->body as $chunk) { + $body .= $chunk; + yield $chunk; + } + $this->body = $body; + } + + public function getPreparedHeaders(): Headers + { + $headers = clone parent::getHeaders(); + + $headers->setHeaderBody('Parameterized', 'Content-Type', $this->getMediaType().'/'.$this->getMediaSubtype()); + + foreach ($this->parameters as $name => $value) { + $headers->setHeaderParameter('Content-Type', $name, $value); + } + + return $headers; + } + + public function __sleep(): array + { + // convert iterables to strings for serialization + if (is_iterable($this->body)) { + $this->body = $this->bodyToString(); + } + + $this->_headers = $this->getHeaders(); + + return ['_headers', 'body', 'type', 'subtype', 'parameters']; + } + + public function __wakeup(): void + { + $r = new \ReflectionProperty(AbstractPart::class, 'headers'); + $r->setValue($this, $this->_headers); + unset($this->_headers); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Part/TextPart.php b/lib/SymfonyMailer/vendor/symfony/mime/Part/TextPart.php new file mode 100644 index 0000000..2b07d29 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Part/TextPart.php @@ -0,0 +1,260 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\Encoder\Base64ContentEncoder; +use Symfony\Component\Mime\Encoder\ContentEncoderInterface; +use Symfony\Component\Mime\Encoder\EightBitContentEncoder; +use Symfony\Component\Mime\Encoder\QpContentEncoder; +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Header\Headers; + +/** + * @author Fabien Potencier + */ +class TextPart extends AbstractPart +{ + private const DEFAULT_ENCODERS = ['quoted-printable', 'base64', '8bit']; + + /** @internal */ + protected Headers $_headers; + + private static array $encoders = []; + + /** @var resource|string|File */ + private $body; + private ?string $charset; + private string $subtype; + private ?string $disposition = null; + private ?string $name = null; + private string $encoding; + private ?bool $seekable = null; + + /** + * @param resource|string|File $body Use a File instance to defer loading the file until rendering + */ + public function __construct($body, ?string $charset = 'utf-8', string $subtype = 'plain', ?string $encoding = null) + { + parent::__construct(); + + if (!\is_string($body) && !\is_resource($body) && !$body instanceof File) { + throw new \TypeError(\sprintf('The body of "%s" must be a string, a resource, or an instance of "%s" (got "%s").', self::class, File::class, get_debug_type($body))); + } + + if ($body instanceof File) { + $path = $body->getPath(); + if ((is_file($path) && !is_readable($path)) || is_dir($path)) { + throw new InvalidArgumentException(\sprintf('Path "%s" is not readable.', $path)); + } + } + + $this->body = $body; + $this->charset = $charset; + $this->subtype = $subtype; + $this->seekable = \is_resource($body) ? stream_get_meta_data($body)['seekable'] && 0 === fseek($body, 0, \SEEK_CUR) : null; + + if (null === $encoding) { + $this->encoding = $this->chooseEncoding(); + } else { + if (!\in_array($encoding, self::DEFAULT_ENCODERS, true) && !\array_key_exists($encoding, self::$encoders)) { + throw new InvalidArgumentException(\sprintf('The encoding must be one of "%s" ("%s" given).', implode('", "', array_unique(array_merge(self::DEFAULT_ENCODERS, array_keys(self::$encoders)))), $encoding)); + } + $this->encoding = $encoding; + } + } + + public function getMediaType(): string + { + return 'text'; + } + + public function getMediaSubtype(): string + { + return $this->subtype; + } + + /** + * @param string $disposition one of attachment, inline, or form-data + * + * @return $this + */ + public function setDisposition(string $disposition): static + { + $this->disposition = $disposition; + + return $this; + } + + /** + * @return ?string null or one of attachment, inline, or form-data + */ + public function getDisposition(): ?string + { + return $this->disposition; + } + + /** + * Sets the name of the file (used by FormDataPart). + * + * @return $this + */ + public function setName(string $name): static + { + $this->name = $name; + + return $this; + } + + /** + * Gets the name of the file. + */ + public function getName(): ?string + { + return $this->name; + } + + public function getBody(): string + { + if ($this->body instanceof File) { + if (false === $ret = @file_get_contents($this->body->getPath())) { + throw new InvalidArgumentException(error_get_last()['message']); + } + + return $ret; + } + + if (null === $this->seekable) { + return $this->body; + } + + if ($this->seekable) { + rewind($this->body); + } + + return stream_get_contents($this->body) ?: ''; + } + + public function bodyToString(): string + { + return $this->getEncoder()->encodeString($this->getBody(), $this->charset); + } + + public function bodyToIterable(): iterable + { + if ($this->body instanceof File) { + $path = $this->body->getPath(); + if (false === $handle = @fopen($path, 'r', false)) { + throw new InvalidArgumentException(\sprintf('Unable to open path "%s".', $path)); + } + + yield from $this->getEncoder()->encodeByteStream($handle); + } elseif (null !== $this->seekable) { + if ($this->seekable) { + rewind($this->body); + } + yield from $this->getEncoder()->encodeByteStream($this->body); + } else { + yield $this->getEncoder()->encodeString($this->body); + } + } + + public function getPreparedHeaders(): Headers + { + $headers = parent::getPreparedHeaders(); + + $headers->setHeaderBody('Parameterized', 'Content-Type', $this->getMediaType().'/'.$this->getMediaSubtype()); + if ($this->charset) { + $headers->setHeaderParameter('Content-Type', 'charset', $this->charset); + } + if ($this->name && 'form-data' !== $this->disposition) { + $headers->setHeaderParameter('Content-Type', 'name', $this->name); + } + $headers->setHeaderBody('Text', 'Content-Transfer-Encoding', $this->encoding); + + if (!$headers->has('Content-Disposition') && null !== $this->disposition) { + $headers->setHeaderBody('Parameterized', 'Content-Disposition', $this->disposition); + if ($this->name) { + $headers->setHeaderParameter('Content-Disposition', 'name', $this->name); + } + } + + return $headers; + } + + public function asDebugString(): string + { + $str = parent::asDebugString(); + if (null !== $this->charset) { + $str .= ' charset: '.$this->charset; + } + if (null !== $this->disposition) { + $str .= ' disposition: '.$this->disposition; + } + + return $str; + } + + private function getEncoder(): ContentEncoderInterface + { + if ('8bit' === $this->encoding) { + return self::$encoders[$this->encoding] ??= new EightBitContentEncoder(); + } + + if ('quoted-printable' === $this->encoding) { + return self::$encoders[$this->encoding] ??= new QpContentEncoder(); + } + + if ('base64' === $this->encoding) { + return self::$encoders[$this->encoding] ??= new Base64ContentEncoder(); + } + + return self::$encoders[$this->encoding]; + } + + public static function addEncoder(ContentEncoderInterface $encoder): void + { + if (\in_array($encoder->getName(), self::DEFAULT_ENCODERS, true)) { + throw new InvalidArgumentException('You are not allowed to change the default encoders ("quoted-printable", "base64", and "8bit").'); + } + + self::$encoders[$encoder->getName()] = $encoder; + } + + private function chooseEncoding(): string + { + if (null === $this->charset) { + return 'base64'; + } + + return 'quoted-printable'; + } + + public function __sleep(): array + { + // convert resources to strings for serialization + if (null !== $this->seekable) { + $this->body = $this->getBody(); + $this->seekable = null; + } + + $this->_headers = $this->getHeaders(); + + return ['_headers', 'body', 'charset', 'subtype', 'disposition', 'name', 'encoding']; + } + + public function __wakeup(): void + { + $r = new \ReflectionProperty(AbstractPart::class, 'headers'); + $r->setValue($this, $this->_headers); + unset($this->_headers); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/README.md b/lib/SymfonyMailer/vendor/symfony/mime/README.md new file mode 100644 index 0000000..8e4d5c7 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/README.md @@ -0,0 +1,13 @@ +MIME Component +============== + +The MIME component allows manipulating MIME messages. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/mime.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/lib/SymfonyMailer/vendor/symfony/mime/RawMessage.php b/lib/SymfonyMailer/vendor/symfony/mime/RawMessage.php new file mode 100644 index 0000000..f791211 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/RawMessage.php @@ -0,0 +1,110 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\LogicException; + +/** + * @author Fabien Potencier + */ +class RawMessage +{ + private bool $isGeneratorClosed; + + /** + * @param iterable|string|resource $message + */ + public function __construct( + private $message, + ) { + } + + public function __destruct() + { + if (\is_resource($this->message)) { + fclose($this->message); + } + } + + public function toString(): string + { + if (\is_string($this->message)) { + return $this->message; + } + + if (\is_resource($this->message)) { + return stream_get_contents($this->message, -1, 0); + } + + $message = ''; + foreach ($this->message as $chunk) { + $message .= $chunk; + } + + return $this->message = $message; + } + + public function toIterable(): iterable + { + if ($this->isGeneratorClosed ?? false) { + throw new LogicException('Unable to send the email as its generator is already closed.'); + } + + if (\is_string($this->message)) { + yield $this->message; + + return; + } + + if (\is_resource($this->message)) { + rewind($this->message); + while ($line = fgets($this->message)) { + yield $line; + } + + return; + } + + if ($this->message instanceof \Generator) { + $message = fopen('php://temp', 'w+'); + foreach ($this->message as $chunk) { + fwrite($message, $chunk); + yield $chunk; + } + $this->isGeneratorClosed = !$this->message->valid(); + $this->message = $message; + + return; + } + + foreach ($this->message as $chunk) { + yield $chunk; + } + } + + /** + * @throws LogicException if the message is not valid + */ + public function ensureValidity(): void + { + } + + public function __serialize(): array + { + return [$this->toString()]; + } + + public function __unserialize(array $data): void + { + [$this->message] = $data; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailAddressContains.php b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailAddressContains.php new file mode 100644 index 0000000..5f0d8d8 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailAddressContains.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\Mime\Header\MailboxHeader; +use Symfony\Component\Mime\Header\MailboxListHeader; +use Symfony\Component\Mime\RawMessage; + +final class EmailAddressContains extends Constraint +{ + public function __construct( + private string $headerName, + private string $expectedValue, + ) { + } + + public function toString(): string + { + return \sprintf('contains address "%s" with value "%s"', $this->headerName, $this->expectedValue); + } + + /** + * @param RawMessage $message + */ + protected function matches($message): bool + { + if (RawMessage::class === $message::class) { + throw new \LogicException('Unable to test a message address on a RawMessage instance.'); + } + + $header = $message->getHeaders()->get($this->headerName); + if ($header instanceof MailboxHeader) { + return $this->expectedValue === $header->getAddress()->getAddress(); + } elseif ($header instanceof MailboxListHeader) { + foreach ($header->getAddresses() as $address) { + if ($this->expectedValue === $address->getAddress()) { + return true; + } + } + + return false; + } + + throw new \LogicException('Unable to test a message address on a non-address header.'); + } + + /** + * @param RawMessage $message + */ + protected function failureDescription($message): string + { + return \sprintf('the Email %s (value is %s)', $this->toString(), $message->getHeaders()->get($this->headerName)->getBodyAsString()); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailAttachmentCount.php b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailAttachmentCount.php new file mode 100644 index 0000000..340673c --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailAttachmentCount.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\Mime\Message; +use Symfony\Component\Mime\RawMessage; + +final class EmailAttachmentCount extends Constraint +{ + public function __construct( + private int $expectedValue, + ) { + } + + public function toString(): string + { + return \sprintf('has sent "%d" attachment(s)', $this->expectedValue); + } + + /** + * @param RawMessage $message + */ + protected function matches($message): bool + { + if (RawMessage::class === $message::class || Message::class === $message::class) { + throw new \LogicException('Unable to test a message attachment on a RawMessage or Message instance.'); + } + + return $this->expectedValue === \count($message->getAttachments()); + } + + /** + * @param RawMessage $message + */ + protected function failureDescription($message): string + { + return 'the Email '.$this->toString(); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailHasHeader.php b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailHasHeader.php new file mode 100644 index 0000000..7f324c2 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailHasHeader.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\Mime\RawMessage; + +final class EmailHasHeader extends Constraint +{ + public function __construct( + private string $headerName, + ) { + } + + public function toString(): string + { + return \sprintf('has header "%s"', $this->headerName); + } + + /** + * @param RawMessage $message + */ + protected function matches($message): bool + { + if (RawMessage::class === $message::class) { + throw new \LogicException('Unable to test a message header on a RawMessage instance.'); + } + + return $message->getHeaders()->has($this->headerName); + } + + /** + * @param RawMessage $message + */ + protected function failureDescription($message): string + { + return 'the Email '.$this->toString(); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailHeaderSame.php b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailHeaderSame.php new file mode 100644 index 0000000..3cdfb6d --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailHeaderSame.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\Mime\Header\UnstructuredHeader; +use Symfony\Component\Mime\RawMessage; + +final class EmailHeaderSame extends Constraint +{ + public function __construct( + private string $headerName, + private string $expectedValue, + ) { + } + + public function toString(): string + { + return \sprintf('has header "%s" with value "%s"', $this->headerName, $this->expectedValue); + } + + /** + * @param RawMessage $message + */ + protected function matches($message): bool + { + if (RawMessage::class === $message::class) { + throw new \LogicException('Unable to test a message header on a RawMessage instance.'); + } + + return $this->expectedValue === $this->getHeaderValue($message); + } + + /** + * @param RawMessage $message + */ + protected function failureDescription($message): string + { + return \sprintf('the Email %s (value is %s)', $this->toString(), $this->getHeaderValue($message) ?? 'null'); + } + + private function getHeaderValue($message): ?string + { + if (null === $header = $message->getHeaders()->get($this->headerName)) { + return null; + } + + return $header instanceof UnstructuredHeader ? $header->getValue() : $header->getBodyAsString(); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailHtmlBodyContains.php b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailHtmlBodyContains.php new file mode 100644 index 0000000..9f0ffa3 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailHtmlBodyContains.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\Mime\Message; +use Symfony\Component\Mime\RawMessage; + +final class EmailHtmlBodyContains extends Constraint +{ + public function __construct( + private string $expectedText, + ) { + } + + public function toString(): string + { + return \sprintf('contains "%s"', $this->expectedText); + } + + /** + * @param RawMessage $message + */ + protected function matches($message): bool + { + if (RawMessage::class === $message::class || Message::class === $message::class) { + throw new \LogicException('Unable to test a message HTML body on a RawMessage or Message instance.'); + } + + return str_contains($message->getHtmlBody(), $this->expectedText); + } + + /** + * @param RawMessage $message + */ + protected function failureDescription($message): string + { + return 'the Email HTML body '.$this->toString(); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailSubjectContains.php b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailSubjectContains.php new file mode 100644 index 0000000..d484bf6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailSubjectContains.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\Mime\Email; + +final class EmailSubjectContains extends Constraint +{ + public function __construct( + private readonly string $expectedSubjectValue, + ) { + } + + public function toString(): string + { + return \sprintf('contains subject with value "%s"', $this->expectedSubjectValue); + } + + protected function matches($other): bool + { + if (!$other instanceof Email) { + throw new \LogicException('Can only test a message subject on an Email instance.'); + } + + return str_contains((string) $other->getSubject(), $this->expectedSubjectValue); + } + + protected function failureDescription($other): string + { + $message = 'The email subject '.$this->toString(); + if ($other instanceof Email) { + $message .= \sprintf('. The subject was: "%s"', $other->getSubject() ?? ''); + } + + return $message; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailTextBodyContains.php b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailTextBodyContains.php new file mode 100644 index 0000000..c2a2383 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/Test/Constraint/EmailTextBodyContains.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\Mime\Message; +use Symfony\Component\Mime\RawMessage; + +final class EmailTextBodyContains extends Constraint +{ + public function __construct( + private string $expectedText, + ) { + } + + public function toString(): string + { + return \sprintf('contains "%s"', $this->expectedText); + } + + /** + * @param RawMessage $message + */ + protected function matches($message): bool + { + if (RawMessage::class === $message::class || Message::class === $message::class) { + throw new \LogicException('Unable to test a message text body on a RawMessage or Message instance.'); + } + + return str_contains($message->getTextBody(), $this->expectedText); + } + + /** + * @param RawMessage $message + */ + protected function failureDescription($message): string + { + return 'the Email text body '.$this->toString(); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/mime/composer.json b/lib/SymfonyMailer/vendor/symfony/mime/composer.json new file mode 100644 index 0000000..5304bdf --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/mime/composer.json @@ -0,0 +1,47 @@ +{ + "name": "symfony/mime", + "type": "library", + "description": "Allows manipulating MIME messages", + "keywords": ["mime", "mime-type"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=8.2", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<6.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Mime\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Idn.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Idn.php new file mode 100644 index 0000000..448f74c --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Idn.php @@ -0,0 +1,941 @@ + and Trevor Rowbotham + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Intl\Idn; + +use Symfony\Polyfill\Intl\Idn\Resources\unidata\DisallowedRanges; +use Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex; + +/** + * @see https://www.unicode.org/reports/tr46/ + * + * @internal + */ +final class Idn +{ + public const ERROR_EMPTY_LABEL = 1; + public const ERROR_LABEL_TOO_LONG = 2; + public const ERROR_DOMAIN_NAME_TOO_LONG = 4; + public const ERROR_LEADING_HYPHEN = 8; + public const ERROR_TRAILING_HYPHEN = 0x10; + public const ERROR_HYPHEN_3_4 = 0x20; + public const ERROR_LEADING_COMBINING_MARK = 0x40; + public const ERROR_DISALLOWED = 0x80; + public const ERROR_PUNYCODE = 0x100; + public const ERROR_LABEL_HAS_DOT = 0x200; + public const ERROR_INVALID_ACE_LABEL = 0x400; + public const ERROR_BIDI = 0x800; + public const ERROR_CONTEXTJ = 0x1000; + public const ERROR_CONTEXTO_PUNCTUATION = 0x2000; + public const ERROR_CONTEXTO_DIGITS = 0x4000; + + public const INTL_IDNA_VARIANT_2003 = 0; + public const INTL_IDNA_VARIANT_UTS46 = 1; + + public const IDNA_DEFAULT = 0; + public const IDNA_ALLOW_UNASSIGNED = 1; + public const IDNA_USE_STD3_RULES = 2; + public const IDNA_CHECK_BIDI = 4; + public const IDNA_CHECK_CONTEXTJ = 8; + public const IDNA_NONTRANSITIONAL_TO_ASCII = 16; + public const IDNA_NONTRANSITIONAL_TO_UNICODE = 32; + + public const MAX_DOMAIN_SIZE = 253; + public const MAX_LABEL_SIZE = 63; + + public const BASE = 36; + public const TMIN = 1; + public const TMAX = 26; + public const SKEW = 38; + public const DAMP = 700; + public const INITIAL_BIAS = 72; + public const INITIAL_N = 128; + public const DELIMITER = '-'; + public const MAX_INT = 2147483647; + + /** + * Contains the numeric value of a basic code point (for use in representing integers) in the + * range 0 to BASE-1, or -1 if b is does not represent a value. + * + * @var array + */ + private static $basicToDigit = [ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, + + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + ]; + + /** + * @var array + */ + private static $virama; + + /** + * @var array + */ + private static $mapped; + + /** + * @var array + */ + private static $ignored; + + /** + * @var array + */ + private static $deviation; + + /** + * @var array + */ + private static $disallowed; + + /** + * @var array + */ + private static $disallowed_STD3_mapped; + + /** + * @var array + */ + private static $disallowed_STD3_valid; + + /** + * @var bool + */ + private static $mappingTableLoaded = false; + + /** + * @see https://www.unicode.org/reports/tr46/#ToASCII + * + * @param string $domainName + * @param int $options + * @param int $variant + * @param array $idna_info + * + * @return string|false + */ + public static function idn_to_ascii($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = []) + { + if (\PHP_VERSION_ID > 80400 && '' === $domainName) { + throw new \ValueError('idn_to_ascii(): Argument #1 ($domain) cannot be empty'); + } + + if (self::INTL_IDNA_VARIANT_2003 === $variant) { + @trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED); + } + + $options = [ + 'CheckHyphens' => true, + 'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & self::IDNA_CHECK_BIDI), + 'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & self::IDNA_CHECK_CONTEXTJ), + 'UseSTD3ASCIIRules' => 0 !== ($options & self::IDNA_USE_STD3_RULES), + 'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & self::IDNA_NONTRANSITIONAL_TO_ASCII), + 'VerifyDnsLength' => true, + ]; + $info = new Info(); + $labels = self::process((string) $domainName, $options, $info); + + foreach ($labels as $i => $label) { + // Only convert labels to punycode that contain non-ASCII code points + if (1 === preg_match('/[^\x00-\x7F]/', $label)) { + try { + $label = 'xn--'.self::punycodeEncode($label); + } catch (\Exception $e) { + $info->errors |= self::ERROR_PUNYCODE; + } + + $labels[$i] = $label; + } + } + + if ($options['VerifyDnsLength']) { + self::validateDomainAndLabelLength($labels, $info); + } + + $idna_info = [ + 'result' => implode('.', $labels), + 'isTransitionalDifferent' => $info->transitionalDifferent, + 'errors' => $info->errors, + ]; + + return 0 === $info->errors ? $idna_info['result'] : false; + } + + /** + * @see https://www.unicode.org/reports/tr46/#ToUnicode + * + * @param string $domainName + * @param int $options + * @param int $variant + * @param array $idna_info + * + * @return string|false + */ + public static function idn_to_utf8($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = []) + { + if (\PHP_VERSION_ID > 80400 && '' === $domainName) { + throw new \ValueError('idn_to_utf8(): Argument #1 ($domain) cannot be empty'); + } + + if (self::INTL_IDNA_VARIANT_2003 === $variant) { + @trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED); + } + + $info = new Info(); + $labels = self::process((string) $domainName, [ + 'CheckHyphens' => true, + 'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & self::IDNA_CHECK_BIDI), + 'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & self::IDNA_CHECK_CONTEXTJ), + 'UseSTD3ASCIIRules' => 0 !== ($options & self::IDNA_USE_STD3_RULES), + 'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & self::IDNA_NONTRANSITIONAL_TO_UNICODE), + ], $info); + $idna_info = [ + 'result' => implode('.', $labels), + 'isTransitionalDifferent' => $info->transitionalDifferent, + 'errors' => $info->errors, + ]; + + return 0 === $info->errors ? $idna_info['result'] : false; + } + + /** + * @param string $label + * + * @return bool + */ + private static function isValidContextJ(array $codePoints, $label) + { + if (!isset(self::$virama)) { + self::$virama = require __DIR__.\DIRECTORY_SEPARATOR.'Resources'.\DIRECTORY_SEPARATOR.'unidata'.\DIRECTORY_SEPARATOR.'virama.php'; + } + + $offset = 0; + + foreach ($codePoints as $i => $codePoint) { + if (0x200C !== $codePoint && 0x200D !== $codePoint) { + continue; + } + + if (!isset($codePoints[$i - 1])) { + return false; + } + + // If Canonical_Combining_Class(Before(cp)) .eq. Virama Then True; + if (isset(self::$virama[$codePoints[$i - 1]])) { + continue; + } + + // If RegExpMatch((Joining_Type:{L,D})(Joining_Type:T)*\u200C(Joining_Type:T)*(Joining_Type:{R,D})) Then + // True; + // Generated RegExp = ([Joining_Type:{L,D}][Joining_Type:T]*\u200C[Joining_Type:T]*)[Joining_Type:{R,D}] + if (0x200C === $codePoint && 1 === preg_match(Regex::ZWNJ, $label, $matches, \PREG_OFFSET_CAPTURE, $offset)) { + $offset += \strlen($matches[1][0]); + + continue; + } + + return false; + } + + return true; + } + + /** + * @see https://www.unicode.org/reports/tr46/#ProcessingStepMap + * + * @param string $input + * @param array $options + * + * @return string + */ + private static function mapCodePoints($input, array $options, Info $info) + { + $str = ''; + $useSTD3ASCIIRules = $options['UseSTD3ASCIIRules']; + $transitional = $options['Transitional_Processing']; + + foreach (self::utf8Decode($input) as $codePoint) { + $data = self::lookupCodePointStatus($codePoint, $useSTD3ASCIIRules); + + switch ($data['status']) { + case 'disallowed': + case 'valid': + $str .= mb_chr($codePoint, 'utf-8'); + + break; + + case 'ignored': + // Do nothing. + break; + + case 'mapped': + $str .= $transitional && 0x1E9E === $codePoint ? 'ss' : $data['mapping']; + + break; + + case 'deviation': + $info->transitionalDifferent = true; + $str .= ($transitional ? $data['mapping'] : mb_chr($codePoint, 'utf-8')); + + break; + } + } + + return $str; + } + + /** + * @see https://www.unicode.org/reports/tr46/#Processing + * + * @param string $domain + * @param array $options + * + * @return array + */ + private static function process($domain, array $options, Info $info) + { + // If VerifyDnsLength is not set, we are doing ToUnicode otherwise we are doing ToASCII and + // we need to respect the VerifyDnsLength option. + $checkForEmptyLabels = !isset($options['VerifyDnsLength']) || $options['VerifyDnsLength']; + + if ($checkForEmptyLabels && '' === $domain) { + $info->errors |= self::ERROR_EMPTY_LABEL; + + return [$domain]; + } + + // Step 1. Map each code point in the domain name string + $domain = self::mapCodePoints($domain, $options, $info); + + // Step 2. Normalize the domain name string to Unicode Normalization Form C. + if (!\Normalizer::isNormalized($domain, \Normalizer::FORM_C)) { + $domain = \Normalizer::normalize($domain, \Normalizer::FORM_C); + } + + // Step 3. Break the string into labels at U+002E (.) FULL STOP. + $labels = explode('.', $domain); + $lastLabelIndex = \count($labels) - 1; + + // Step 4. Convert and validate each label in the domain name string. + foreach ($labels as $i => $label) { + $validationOptions = $options; + + if ('xn--' === substr($label, 0, 4)) { + // Step 4.1. If the label contains any non-ASCII code point (i.e., a code point greater than U+007F), + // record that there was an error, and continue with the next label. + if (preg_match('/[^\x00-\x7F]/', $label)) { + $info->errors |= self::ERROR_PUNYCODE; + + continue; + } + + // Step 4.2. Attempt to convert the rest of the label to Unicode according to Punycode [RFC3492]. If + // that conversion fails, record that there was an error, and continue + // with the next label. Otherwise replace the original label in the string by the results of the + // conversion. + try { + $label = self::punycodeDecode(substr($label, 4)); + } catch (\Exception $e) { + $info->errors |= self::ERROR_PUNYCODE; + + continue; + } + + $validationOptions['Transitional_Processing'] = false; + $labels[$i] = $label; + } + + self::validateLabel($label, $info, $validationOptions, $i > 0 && $i === $lastLabelIndex); + } + + if ($info->bidiDomain && !$info->validBidiDomain) { + $info->errors |= self::ERROR_BIDI; + } + + // Any input domain name string that does not record an error has been successfully + // processed according to this specification. Conversely, if an input domain_name string + // causes an error, then the processing of the input domain_name string fails. Determining + // what to do with error input is up to the caller, and not in the scope of this document. + return $labels; + } + + /** + * @see https://tools.ietf.org/html/rfc5893#section-2 + * + * @param string $label + */ + private static function validateBidiLabel($label, Info $info) + { + if (1 === preg_match(Regex::RTL_LABEL, $label)) { + $info->bidiDomain = true; + + // Step 1. The first character must be a character with Bidi property L, R, or AL. + // If it has the R or AL property, it is an RTL label + if (1 !== preg_match(Regex::BIDI_STEP_1_RTL, $label)) { + $info->validBidiDomain = false; + + return; + } + + // Step 2. In an RTL label, only characters with the Bidi properties R, AL, AN, EN, ES, + // CS, ET, ON, BN, or NSM are allowed. + if (1 === preg_match(Regex::BIDI_STEP_2, $label)) { + $info->validBidiDomain = false; + + return; + } + + // Step 3. In an RTL label, the end of the label must be a character with Bidi property + // R, AL, EN, or AN, followed by zero or more characters with Bidi property NSM. + if (1 !== preg_match(Regex::BIDI_STEP_3, $label)) { + $info->validBidiDomain = false; + + return; + } + + // Step 4. In an RTL label, if an EN is present, no AN may be present, and vice versa. + if (1 === preg_match(Regex::BIDI_STEP_4_AN, $label) && 1 === preg_match(Regex::BIDI_STEP_4_EN, $label)) { + $info->validBidiDomain = false; + + return; + } + + return; + } + + // We are a LTR label + // Step 1. The first character must be a character with Bidi property L, R, or AL. + // If it has the L property, it is an LTR label. + if (1 !== preg_match(Regex::BIDI_STEP_1_LTR, $label)) { + $info->validBidiDomain = false; + + return; + } + + // Step 5. In an LTR label, only characters with the Bidi properties L, EN, + // ES, CS, ET, ON, BN, or NSM are allowed. + if (1 === preg_match(Regex::BIDI_STEP_5, $label)) { + $info->validBidiDomain = false; + + return; + } + + // Step 6.In an LTR label, the end of the label must be a character with Bidi property L or + // EN, followed by zero or more characters with Bidi property NSM. + if (1 !== preg_match(Regex::BIDI_STEP_6, $label)) { + $info->validBidiDomain = false; + + return; + } + } + + /** + * @param array $labels + */ + private static function validateDomainAndLabelLength(array $labels, Info $info) + { + $maxDomainSize = self::MAX_DOMAIN_SIZE; + $length = \count($labels); + + // Number of "." delimiters. + $domainLength = $length - 1; + + // If the last label is empty and it is not the first label, then it is the root label. + // Increase the max size by 1, making it 254, to account for the root label's "." + // delimiter. This also means we don't need to check the last label's length for being too + // long. + if ($length > 1 && '' === $labels[$length - 1]) { + ++$maxDomainSize; + --$length; + } + + for ($i = 0; $i < $length; ++$i) { + $bytes = \strlen($labels[$i]); + $domainLength += $bytes; + + if ($bytes > self::MAX_LABEL_SIZE) { + $info->errors |= self::ERROR_LABEL_TOO_LONG; + } + } + + if ($domainLength > $maxDomainSize) { + $info->errors |= self::ERROR_DOMAIN_NAME_TOO_LONG; + } + } + + /** + * @see https://www.unicode.org/reports/tr46/#Validity_Criteria + * + * @param string $label + * @param array $options + * @param bool $canBeEmpty + */ + private static function validateLabel($label, Info $info, array $options, $canBeEmpty) + { + if ('' === $label) { + if (!$canBeEmpty && (!isset($options['VerifyDnsLength']) || $options['VerifyDnsLength'])) { + $info->errors |= self::ERROR_EMPTY_LABEL; + } + + return; + } + + // Step 1. The label must be in Unicode Normalization Form C. + if (!\Normalizer::isNormalized($label, \Normalizer::FORM_C)) { + $info->errors |= self::ERROR_INVALID_ACE_LABEL; + } + + $codePoints = self::utf8Decode($label); + + if ($options['CheckHyphens']) { + // Step 2. If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character + // in both the thrid and fourth positions. + if (isset($codePoints[2], $codePoints[3]) && 0x002D === $codePoints[2] && 0x002D === $codePoints[3]) { + $info->errors |= self::ERROR_HYPHEN_3_4; + } + + // Step 3. If CheckHyphens, the label must neither begin nor end with a U+002D + // HYPHEN-MINUS character. + if ('-' === substr($label, 0, 1)) { + $info->errors |= self::ERROR_LEADING_HYPHEN; + } + + if ('-' === substr($label, -1, 1)) { + $info->errors |= self::ERROR_TRAILING_HYPHEN; + } + } elseif ('xn--' === substr($label, 0, 4)) { + $info->errors |= self::ERROR_PUNYCODE; + } + + // Step 4. The label must not contain a U+002E (.) FULL STOP. + if (false !== strpos($label, '.')) { + $info->errors |= self::ERROR_LABEL_HAS_DOT; + } + + // Step 5. The label must not begin with a combining mark, that is: General_Category=Mark. + if (1 === preg_match(Regex::COMBINING_MARK, $label)) { + $info->errors |= self::ERROR_LEADING_COMBINING_MARK; + } + + // Step 6. Each code point in the label must only have certain status values according to + // Section 5, IDNA Mapping Table: + $transitional = $options['Transitional_Processing']; + $useSTD3ASCIIRules = $options['UseSTD3ASCIIRules']; + + foreach ($codePoints as $codePoint) { + $data = self::lookupCodePointStatus($codePoint, $useSTD3ASCIIRules); + $status = $data['status']; + + if ('valid' === $status || (!$transitional && 'deviation' === $status)) { + continue; + } + + $info->errors |= self::ERROR_DISALLOWED; + + break; + } + + // Step 7. If CheckJoiners, the label must satisify the ContextJ rules from Appendix A, in + // The Unicode Code Points and Internationalized Domain Names for Applications (IDNA) + // [IDNA2008]. + if ($options['CheckJoiners'] && !self::isValidContextJ($codePoints, $label)) { + $info->errors |= self::ERROR_CONTEXTJ; + } + + // Step 8. If CheckBidi, and if the domain name is a Bidi domain name, then the label must + // satisfy all six of the numbered conditions in [IDNA2008] RFC 5893, Section 2. + if ($options['CheckBidi'] && (!$info->bidiDomain || $info->validBidiDomain)) { + self::validateBidiLabel($label, $info); + } + } + + /** + * @see https://tools.ietf.org/html/rfc3492#section-6.2 + * + * @param string $input + * + * @return string + */ + private static function punycodeDecode($input) + { + $n = self::INITIAL_N; + $out = 0; + $i = 0; + $bias = self::INITIAL_BIAS; + $lastDelimIndex = strrpos($input, self::DELIMITER); + $b = false === $lastDelimIndex ? 0 : $lastDelimIndex; + $inputLength = \strlen($input); + $output = []; + $bytes = array_map('ord', str_split($input)); + + for ($j = 0; $j < $b; ++$j) { + if ($bytes[$j] > 0x7F) { + throw new \Exception('Invalid input'); + } + + $output[$out++] = $input[$j]; + } + + if ($b > 0) { + ++$b; + } + + for ($in = $b; $in < $inputLength; ++$out) { + $oldi = $i; + $w = 1; + + for ($k = self::BASE; /* no condition */; $k += self::BASE) { + if ($in >= $inputLength) { + throw new \Exception('Invalid input'); + } + + $digit = self::$basicToDigit[$bytes[$in++] & 0xFF]; + + if ($digit < 0) { + throw new \Exception('Invalid input'); + } + + if ($digit > intdiv(self::MAX_INT - $i, $w)) { + throw new \Exception('Integer overflow'); + } + + $i += $digit * $w; + + if ($k <= $bias) { + $t = self::TMIN; + } elseif ($k >= $bias + self::TMAX) { + $t = self::TMAX; + } else { + $t = $k - $bias; + } + + if ($digit < $t) { + break; + } + + $baseMinusT = self::BASE - $t; + + if ($w > intdiv(self::MAX_INT, $baseMinusT)) { + throw new \Exception('Integer overflow'); + } + + $w *= $baseMinusT; + } + + $outPlusOne = $out + 1; + $bias = self::adaptBias($i - $oldi, $outPlusOne, 0 === $oldi); + + if (intdiv($i, $outPlusOne) > self::MAX_INT - $n) { + throw new \Exception('Integer overflow'); + } + + $n += intdiv($i, $outPlusOne); + $i %= $outPlusOne; + array_splice($output, $i++, 0, [mb_chr($n, 'utf-8')]); + } + + return implode('', $output); + } + + /** + * @see https://tools.ietf.org/html/rfc3492#section-6.3 + * + * @param string $input + * + * @return string + */ + private static function punycodeEncode($input) + { + $n = self::INITIAL_N; + $delta = 0; + $out = 0; + $bias = self::INITIAL_BIAS; + $inputLength = 0; + $output = ''; + $iter = self::utf8Decode($input); + + foreach ($iter as $codePoint) { + ++$inputLength; + + if ($codePoint < 0x80) { + $output .= \chr($codePoint); + ++$out; + } + } + + $h = $out; + $b = $out; + + if ($b > 0) { + $output .= self::DELIMITER; + ++$out; + } + + while ($h < $inputLength) { + $m = self::MAX_INT; + + foreach ($iter as $codePoint) { + if ($codePoint >= $n && $codePoint < $m) { + $m = $codePoint; + } + } + + if ($m - $n > intdiv(self::MAX_INT - $delta, $h + 1)) { + throw new \Exception('Integer overflow'); + } + + $delta += ($m - $n) * ($h + 1); + $n = $m; + + foreach ($iter as $codePoint) { + if ($codePoint < $n && 0 === ++$delta) { + throw new \Exception('Integer overflow'); + } + + if ($codePoint === $n) { + $q = $delta; + + for ($k = self::BASE; /* no condition */; $k += self::BASE) { + if ($k <= $bias) { + $t = self::TMIN; + } elseif ($k >= $bias + self::TMAX) { + $t = self::TMAX; + } else { + $t = $k - $bias; + } + + if ($q < $t) { + break; + } + + $qMinusT = $q - $t; + $baseMinusT = self::BASE - $t; + $output .= self::encodeDigit($t + $qMinusT % $baseMinusT, false); + ++$out; + $q = intdiv($qMinusT, $baseMinusT); + } + + $output .= self::encodeDigit($q, false); + ++$out; + $bias = self::adaptBias($delta, $h + 1, $h === $b); + $delta = 0; + ++$h; + } + } + + ++$delta; + ++$n; + } + + return $output; + } + + /** + * @see https://tools.ietf.org/html/rfc3492#section-6.1 + * + * @param int $delta + * @param int $numPoints + * @param bool $firstTime + * + * @return int + */ + private static function adaptBias($delta, $numPoints, $firstTime) + { + // xxx >> 1 is a faster way of doing intdiv(xxx, 2) + $delta = $firstTime ? intdiv($delta, self::DAMP) : $delta >> 1; + $delta += intdiv($delta, $numPoints); + $k = 0; + + while ($delta > ((self::BASE - self::TMIN) * self::TMAX) >> 1) { + $delta = intdiv($delta, self::BASE - self::TMIN); + $k += self::BASE; + } + + return $k + intdiv((self::BASE - self::TMIN + 1) * $delta, $delta + self::SKEW); + } + + /** + * @param int $d + * @param bool $flag + * + * @return string + */ + private static function encodeDigit($d, $flag) + { + return \chr($d + 22 + 75 * ($d < 26 ? 1 : 0) - (($flag ? 1 : 0) << 5)); + } + + /** + * Takes a UTF-8 encoded string and converts it into a series of integer code points. Any + * invalid byte sequences will be replaced by a U+FFFD replacement code point. + * + * @see https://encoding.spec.whatwg.org/#utf-8-decoder + * + * @param string $input + * + * @return array + */ + private static function utf8Decode($input) + { + $bytesSeen = 0; + $bytesNeeded = 0; + $lowerBoundary = 0x80; + $upperBoundary = 0xBF; + $codePoint = 0; + $codePoints = []; + $length = \strlen($input); + + for ($i = 0; $i < $length; ++$i) { + $byte = \ord($input[$i]); + + if (0 === $bytesNeeded) { + if ($byte >= 0x00 && $byte <= 0x7F) { + $codePoints[] = $byte; + + continue; + } + + if ($byte >= 0xC2 && $byte <= 0xDF) { + $bytesNeeded = 1; + $codePoint = $byte & 0x1F; + } elseif ($byte >= 0xE0 && $byte <= 0xEF) { + if (0xE0 === $byte) { + $lowerBoundary = 0xA0; + } elseif (0xED === $byte) { + $upperBoundary = 0x9F; + } + + $bytesNeeded = 2; + $codePoint = $byte & 0xF; + } elseif ($byte >= 0xF0 && $byte <= 0xF4) { + if (0xF0 === $byte) { + $lowerBoundary = 0x90; + } elseif (0xF4 === $byte) { + $upperBoundary = 0x8F; + } + + $bytesNeeded = 3; + $codePoint = $byte & 0x7; + } else { + $codePoints[] = 0xFFFD; + } + + continue; + } + + if ($byte < $lowerBoundary || $byte > $upperBoundary) { + $codePoint = 0; + $bytesNeeded = 0; + $bytesSeen = 0; + $lowerBoundary = 0x80; + $upperBoundary = 0xBF; + --$i; + $codePoints[] = 0xFFFD; + + continue; + } + + $lowerBoundary = 0x80; + $upperBoundary = 0xBF; + $codePoint = ($codePoint << 6) | ($byte & 0x3F); + + if (++$bytesSeen !== $bytesNeeded) { + continue; + } + + $codePoints[] = $codePoint; + $codePoint = 0; + $bytesNeeded = 0; + $bytesSeen = 0; + } + + // String unexpectedly ended, so append a U+FFFD code point. + if (0 !== $bytesNeeded) { + $codePoints[] = 0xFFFD; + } + + return $codePoints; + } + + /** + * @param int $codePoint + * @param bool $useSTD3ASCIIRules + * + * @return array{status: string, mapping?: string} + */ + private static function lookupCodePointStatus($codePoint, $useSTD3ASCIIRules) + { + if (!self::$mappingTableLoaded) { + self::$mappingTableLoaded = true; + self::$mapped = require __DIR__.'/Resources/unidata/mapped.php'; + self::$ignored = require __DIR__.'/Resources/unidata/ignored.php'; + self::$deviation = require __DIR__.'/Resources/unidata/deviation.php'; + self::$disallowed = require __DIR__.'/Resources/unidata/disallowed.php'; + self::$disallowed_STD3_mapped = require __DIR__.'/Resources/unidata/disallowed_STD3_mapped.php'; + self::$disallowed_STD3_valid = require __DIR__.'/Resources/unidata/disallowed_STD3_valid.php'; + } + + if (isset(self::$mapped[$codePoint])) { + return ['status' => 'mapped', 'mapping' => self::$mapped[$codePoint]]; + } + + if (isset(self::$ignored[$codePoint])) { + return ['status' => 'ignored']; + } + + if (isset(self::$deviation[$codePoint])) { + return ['status' => 'deviation', 'mapping' => self::$deviation[$codePoint]]; + } + + if (isset(self::$disallowed[$codePoint]) || DisallowedRanges::inRange($codePoint)) { + return ['status' => 'disallowed']; + } + + $isDisallowedMapped = isset(self::$disallowed_STD3_mapped[$codePoint]); + + if ($isDisallowedMapped || isset(self::$disallowed_STD3_valid[$codePoint])) { + $status = 'disallowed'; + + if (!$useSTD3ASCIIRules) { + $status = $isDisallowedMapped ? 'mapped' : 'valid'; + } + + if ($isDisallowedMapped) { + return ['status' => $status, 'mapping' => self::$disallowed_STD3_mapped[$codePoint]]; + } + + return ['status' => $status]; + } + + return ['status' => 'valid']; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Info.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Info.php new file mode 100644 index 0000000..25c3582 --- /dev/null +++ b/lib/SymfonyMailer/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/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/LICENSE b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/LICENSE new file mode 100644 index 0000000..fd0a062 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-present Fabien Potencier and Trevor Rowbotham + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/README.md b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/README.md new file mode 100644 index 0000000..cae5517 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/README.md @@ -0,0 +1,12 @@ +Symfony Polyfill / Intl: Idn +============================ + +This component provides [`idn_to_ascii`](https://php.net/idn-to-ascii) and [`idn_to_utf8`](https://php.net/idn-to-utf8) functions to users who run php versions without the [Intl](https://php.net/intl) extension. + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php new file mode 100644 index 0000000..d285acd --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php @@ -0,0 +1,384 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Intl\Idn\Resources\unidata; + +/** + * @internal + */ +final class DisallowedRanges +{ + /** + * @param int $codePoint + * + * @return bool + */ + public static function inRange($codePoint) + { + if ($codePoint >= 128 && $codePoint <= 159) { + return true; + } + + if ($codePoint >= 2155 && $codePoint <= 2207) { + return true; + } + + if ($codePoint >= 3676 && $codePoint <= 3712) { + return true; + } + + if ($codePoint >= 3808 && $codePoint <= 3839) { + return true; + } + + if ($codePoint >= 4059 && $codePoint <= 4095) { + return true; + } + + if ($codePoint >= 4256 && $codePoint <= 4293) { + return true; + } + + if ($codePoint >= 6849 && $codePoint <= 6911) { + return true; + } + + if ($codePoint >= 11859 && $codePoint <= 11903) { + return true; + } + + if ($codePoint >= 42955 && $codePoint <= 42996) { + return true; + } + + if ($codePoint >= 55296 && $codePoint <= 57343) { + return true; + } + + if ($codePoint >= 57344 && $codePoint <= 63743) { + return true; + } + + if ($codePoint >= 64218 && $codePoint <= 64255) { + return true; + } + + if ($codePoint >= 64976 && $codePoint <= 65007) { + return true; + } + + if ($codePoint >= 65630 && $codePoint <= 65663) { + return true; + } + + if ($codePoint >= 65953 && $codePoint <= 65999) { + return true; + } + + if ($codePoint >= 66046 && $codePoint <= 66175) { + return true; + } + + if ($codePoint >= 66518 && $codePoint <= 66559) { + return true; + } + + if ($codePoint >= 66928 && $codePoint <= 67071) { + return true; + } + + if ($codePoint >= 67432 && $codePoint <= 67583) { + return true; + } + + if ($codePoint >= 67760 && $codePoint <= 67807) { + return true; + } + + if ($codePoint >= 67904 && $codePoint <= 67967) { + return true; + } + + if ($codePoint >= 68256 && $codePoint <= 68287) { + return true; + } + + if ($codePoint >= 68528 && $codePoint <= 68607) { + return true; + } + + if ($codePoint >= 68681 && $codePoint <= 68735) { + return true; + } + + if ($codePoint >= 68922 && $codePoint <= 69215) { + return true; + } + + if ($codePoint >= 69298 && $codePoint <= 69375) { + return true; + } + + if ($codePoint >= 69466 && $codePoint <= 69551) { + return true; + } + + if ($codePoint >= 70207 && $codePoint <= 70271) { + return true; + } + + if ($codePoint >= 70517 && $codePoint <= 70655) { + return true; + } + + if ($codePoint >= 70874 && $codePoint <= 71039) { + return true; + } + + if ($codePoint >= 71134 && $codePoint <= 71167) { + return true; + } + + if ($codePoint >= 71370 && $codePoint <= 71423) { + return true; + } + + if ($codePoint >= 71488 && $codePoint <= 71679) { + return true; + } + + if ($codePoint >= 71740 && $codePoint <= 71839) { + return true; + } + + if ($codePoint >= 72026 && $codePoint <= 72095) { + return true; + } + + if ($codePoint >= 72441 && $codePoint <= 72703) { + return true; + } + + if ($codePoint >= 72887 && $codePoint <= 72959) { + return true; + } + + if ($codePoint >= 73130 && $codePoint <= 73439) { + return true; + } + + if ($codePoint >= 73465 && $codePoint <= 73647) { + return true; + } + + if ($codePoint >= 74650 && $codePoint <= 74751) { + return true; + } + + if ($codePoint >= 75076 && $codePoint <= 77823) { + return true; + } + + if ($codePoint >= 78905 && $codePoint <= 82943) { + return true; + } + + if ($codePoint >= 83527 && $codePoint <= 92159) { + return true; + } + + if ($codePoint >= 92784 && $codePoint <= 92879) { + return true; + } + + if ($codePoint >= 93072 && $codePoint <= 93759) { + return true; + } + + if ($codePoint >= 93851 && $codePoint <= 93951) { + return true; + } + + if ($codePoint >= 94112 && $codePoint <= 94175) { + return true; + } + + if ($codePoint >= 101590 && $codePoint <= 101631) { + return true; + } + + if ($codePoint >= 101641 && $codePoint <= 110591) { + return true; + } + + if ($codePoint >= 110879 && $codePoint <= 110927) { + return true; + } + + if ($codePoint >= 111356 && $codePoint <= 113663) { + return true; + } + + if ($codePoint >= 113828 && $codePoint <= 118783) { + return true; + } + + if ($codePoint >= 119366 && $codePoint <= 119519) { + return true; + } + + if ($codePoint >= 119673 && $codePoint <= 119807) { + return true; + } + + if ($codePoint >= 121520 && $codePoint <= 122879) { + return true; + } + + if ($codePoint >= 122923 && $codePoint <= 123135) { + return true; + } + + if ($codePoint >= 123216 && $codePoint <= 123583) { + return true; + } + + if ($codePoint >= 123648 && $codePoint <= 124927) { + return true; + } + + if ($codePoint >= 125143 && $codePoint <= 125183) { + return true; + } + + if ($codePoint >= 125280 && $codePoint <= 126064) { + return true; + } + + if ($codePoint >= 126133 && $codePoint <= 126208) { + return true; + } + + if ($codePoint >= 126270 && $codePoint <= 126463) { + return true; + } + + if ($codePoint >= 126652 && $codePoint <= 126703) { + return true; + } + + if ($codePoint >= 126706 && $codePoint <= 126975) { + return true; + } + + if ($codePoint >= 127406 && $codePoint <= 127461) { + return true; + } + + if ($codePoint >= 127590 && $codePoint <= 127743) { + return true; + } + + if ($codePoint >= 129202 && $codePoint <= 129279) { + return true; + } + + if ($codePoint >= 129751 && $codePoint <= 129791) { + return true; + } + + if ($codePoint >= 129995 && $codePoint <= 130031) { + return true; + } + + if ($codePoint >= 130042 && $codePoint <= 131069) { + return true; + } + + if ($codePoint >= 173790 && $codePoint <= 173823) { + return true; + } + + if ($codePoint >= 191457 && $codePoint <= 194559) { + return true; + } + + if ($codePoint >= 195102 && $codePoint <= 196605) { + return true; + } + + if ($codePoint >= 201547 && $codePoint <= 262141) { + return true; + } + + if ($codePoint >= 262144 && $codePoint <= 327677) { + return true; + } + + if ($codePoint >= 327680 && $codePoint <= 393213) { + return true; + } + + if ($codePoint >= 393216 && $codePoint <= 458749) { + return true; + } + + if ($codePoint >= 458752 && $codePoint <= 524285) { + return true; + } + + if ($codePoint >= 524288 && $codePoint <= 589821) { + return true; + } + + if ($codePoint >= 589824 && $codePoint <= 655357) { + return true; + } + + if ($codePoint >= 655360 && $codePoint <= 720893) { + return true; + } + + if ($codePoint >= 720896 && $codePoint <= 786429) { + return true; + } + + if ($codePoint >= 786432 && $codePoint <= 851965) { + return true; + } + + if ($codePoint >= 851968 && $codePoint <= 917501) { + return true; + } + + if ($codePoint >= 917536 && $codePoint <= 917631) { + return true; + } + + if ($codePoint >= 917632 && $codePoint <= 917759) { + return true; + } + + if ($codePoint >= 918000 && $codePoint <= 983037) { + return true; + } + + if ($codePoint >= 983040 && $codePoint <= 1048573) { + return true; + } + + if ($codePoint >= 1048576 && $codePoint <= 1114109) { + return true; + } + + return false; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php new file mode 100644 index 0000000..3c6af0c --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Intl\Idn\Resources\unidata; + +/** + * @internal + */ +final class Regex +{ + const COMBINING_MARK = '/^[\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{0903}\x{093A}\x{093B}\x{093C}\x{093E}-\x{0940}\x{0941}-\x{0948}\x{0949}-\x{094C}\x{094D}\x{094E}-\x{094F}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{0982}-\x{0983}\x{09BC}\x{09BE}-\x{09C0}\x{09C1}-\x{09C4}\x{09C7}-\x{09C8}\x{09CB}-\x{09CC}\x{09CD}\x{09D7}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A03}\x{0A3C}\x{0A3E}-\x{0A40}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0A83}\x{0ABC}\x{0ABE}-\x{0AC0}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0AC9}\x{0ACB}-\x{0ACC}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B02}-\x{0B03}\x{0B3C}\x{0B3E}\x{0B3F}\x{0B40}\x{0B41}-\x{0B44}\x{0B47}-\x{0B48}\x{0B4B}-\x{0B4C}\x{0B4D}\x{0B55}-\x{0B56}\x{0B57}\x{0B62}-\x{0B63}\x{0B82}\x{0BBE}-\x{0BBF}\x{0BC0}\x{0BC1}-\x{0BC2}\x{0BC6}-\x{0BC8}\x{0BCA}-\x{0BCC}\x{0BCD}\x{0BD7}\x{0C00}\x{0C01}-\x{0C03}\x{0C04}\x{0C3E}-\x{0C40}\x{0C41}-\x{0C44}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0C82}-\x{0C83}\x{0CBC}\x{0CBE}\x{0CBF}\x{0CC0}-\x{0CC4}\x{0CC6}\x{0CC7}-\x{0CC8}\x{0CCA}-\x{0CCB}\x{0CCC}-\x{0CCD}\x{0CD5}-\x{0CD6}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D02}-\x{0D03}\x{0D3B}-\x{0D3C}\x{0D3E}-\x{0D40}\x{0D41}-\x{0D44}\x{0D46}-\x{0D48}\x{0D4A}-\x{0D4C}\x{0D4D}\x{0D57}\x{0D62}-\x{0D63}\x{0D81}\x{0D82}-\x{0D83}\x{0DCA}\x{0DCF}-\x{0DD1}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0DD8}-\x{0DDF}\x{0DF2}-\x{0DF3}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3E}-\x{0F3F}\x{0F71}-\x{0F7E}\x{0F7F}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102B}-\x{102C}\x{102D}-\x{1030}\x{1031}\x{1032}-\x{1037}\x{1038}\x{1039}-\x{103A}\x{103B}-\x{103C}\x{103D}-\x{103E}\x{1056}-\x{1057}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1062}-\x{1064}\x{1067}-\x{106D}\x{1071}-\x{1074}\x{1082}\x{1083}-\x{1084}\x{1085}-\x{1086}\x{1087}-\x{108C}\x{108D}\x{108F}\x{109A}-\x{109C}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B6}\x{17B7}-\x{17BD}\x{17BE}-\x{17C5}\x{17C6}\x{17C7}-\x{17C8}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1923}-\x{1926}\x{1927}-\x{1928}\x{1929}-\x{192B}\x{1930}-\x{1931}\x{1932}\x{1933}-\x{1938}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A19}-\x{1A1A}\x{1A1B}\x{1A55}\x{1A56}\x{1A57}\x{1A58}-\x{1A5E}\x{1A60}\x{1A61}\x{1A62}\x{1A63}-\x{1A64}\x{1A65}-\x{1A6C}\x{1A6D}-\x{1A72}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B04}\x{1B34}\x{1B35}\x{1B36}-\x{1B3A}\x{1B3B}\x{1B3C}\x{1B3D}-\x{1B41}\x{1B42}\x{1B43}-\x{1B44}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1B82}\x{1BA1}\x{1BA2}-\x{1BA5}\x{1BA6}-\x{1BA7}\x{1BA8}-\x{1BA9}\x{1BAA}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE7}\x{1BE8}-\x{1BE9}\x{1BEA}-\x{1BEC}\x{1BED}\x{1BEE}\x{1BEF}-\x{1BF1}\x{1BF2}-\x{1BF3}\x{1C24}-\x{1C2B}\x{1C2C}-\x{1C33}\x{1C34}-\x{1C35}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE1}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF7}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{302E}-\x{302F}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A823}-\x{A824}\x{A825}-\x{A826}\x{A827}\x{A82C}\x{A880}-\x{A881}\x{A8B4}-\x{A8C3}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A952}-\x{A953}\x{A980}-\x{A982}\x{A983}\x{A9B3}\x{A9B4}-\x{A9B5}\x{A9B6}-\x{A9B9}\x{A9BA}-\x{A9BB}\x{A9BC}-\x{A9BD}\x{A9BE}-\x{A9C0}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA2F}-\x{AA30}\x{AA31}-\x{AA32}\x{AA33}-\x{AA34}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA4D}\x{AA7B}\x{AA7C}\x{AA7D}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEB}\x{AAEC}-\x{AAED}\x{AAEE}-\x{AAEF}\x{AAF5}\x{AAF6}\x{ABE3}-\x{ABE4}\x{ABE5}\x{ABE6}-\x{ABE7}\x{ABE8}\x{ABE9}-\x{ABEA}\x{ABEC}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11000}\x{11001}\x{11002}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{11082}\x{110B0}-\x{110B2}\x{110B3}-\x{110B6}\x{110B7}-\x{110B8}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112C}\x{1112D}-\x{11134}\x{11145}-\x{11146}\x{11173}\x{11180}-\x{11181}\x{11182}\x{111B3}-\x{111B5}\x{111B6}-\x{111BE}\x{111BF}-\x{111C0}\x{111C9}-\x{111CC}\x{111CE}\x{111CF}\x{1122C}-\x{1122E}\x{1122F}-\x{11231}\x{11232}-\x{11233}\x{11234}\x{11235}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E0}-\x{112E2}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{11302}-\x{11303}\x{1133B}-\x{1133C}\x{1133E}-\x{1133F}\x{11340}\x{11341}-\x{11344}\x{11347}-\x{11348}\x{1134B}-\x{1134D}\x{11357}\x{11362}-\x{11363}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11435}-\x{11437}\x{11438}-\x{1143F}\x{11440}-\x{11441}\x{11442}-\x{11444}\x{11445}\x{11446}\x{1145E}\x{114B0}-\x{114B2}\x{114B3}-\x{114B8}\x{114B9}\x{114BA}\x{114BB}-\x{114BE}\x{114BF}-\x{114C0}\x{114C1}\x{114C2}-\x{114C3}\x{115AF}-\x{115B1}\x{115B2}-\x{115B5}\x{115B8}-\x{115BB}\x{115BC}-\x{115BD}\x{115BE}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11630}-\x{11632}\x{11633}-\x{1163A}\x{1163B}-\x{1163C}\x{1163D}\x{1163E}\x{1163F}-\x{11640}\x{116AB}\x{116AC}\x{116AD}\x{116AE}-\x{116AF}\x{116B0}-\x{116B5}\x{116B6}\x{116B7}\x{1171D}-\x{1171F}\x{11720}-\x{11721}\x{11722}-\x{11725}\x{11726}\x{11727}-\x{1172B}\x{1182C}-\x{1182E}\x{1182F}-\x{11837}\x{11838}\x{11839}-\x{1183A}\x{11930}-\x{11935}\x{11937}-\x{11938}\x{1193B}-\x{1193C}\x{1193D}\x{1193E}\x{11940}\x{11942}\x{11943}\x{119D1}-\x{119D3}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119DC}-\x{119DF}\x{119E0}\x{119E4}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A39}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A57}-\x{11A58}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A97}\x{11A98}-\x{11A99}\x{11C2F}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3E}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CA9}\x{11CAA}-\x{11CB0}\x{11CB1}\x{11CB2}-\x{11CB3}\x{11CB4}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D8A}-\x{11D8E}\x{11D90}-\x{11D91}\x{11D93}-\x{11D94}\x{11D95}\x{11D96}\x{11D97}\x{11EF3}-\x{11EF4}\x{11EF5}-\x{11EF6}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F51}-\x{16F87}\x{16F8F}-\x{16F92}\x{16FE4}\x{16FF0}-\x{16FF1}\x{1BC9D}-\x{1BC9E}\x{1D165}-\x{1D166}\x{1D167}-\x{1D169}\x{1D16D}-\x{1D172}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]/u'; + + const RTL_LABEL = '/[\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{200F}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u'; + + const BIDI_STEP_1_LTR = '/^[^\x{0000}-\x{0008}\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{000E}-\x{001B}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{0030}-\x{0039}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0085}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B2}-\x{00B3}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00B9}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{1680}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{2000}-\x{200A}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{205F}\x{2060}-\x{2064}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}\x{206A}-\x{206F}\x{2070}\x{2074}-\x{2079}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{2080}-\x{2089}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{2488}-\x{249B}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3000}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF10}-\x{FF19}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{102E1}-\x{102FB}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1D7CE}-\x{1D7FF}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F100}-\x{1F10A}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FBF0}-\x{1FBF9}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}]/u'; + const BIDI_STEP_1_RTL = '/^[\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{200F}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u'; + const BIDI_STEP_2 = '/[^\x{0000}-\x{0008}\x{000E}-\x{001B}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{0030}-\x{0039}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B2}-\x{00B3}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00B9}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{2060}-\x{2064}\x{2065}\x{206A}-\x{206F}\x{2070}\x{2074}-\x{2079}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{2080}-\x{2089}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{2488}-\x{249B}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF10}-\x{FF19}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{102E1}-\x{102FB}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1D7CE}-\x{1D7FF}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F100}-\x{1F10A}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FBF0}-\x{1FBF9}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}]/u'; + const BIDI_STEP_3 = '/[\x{0030}-\x{0039}\x{00B2}-\x{00B3}\x{00B9}\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{200F}\x{2070}\x{2074}-\x{2079}\x{2080}-\x{2089}\x{2488}-\x{249B}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FF10}-\x{FF19}\x{102E1}-\x{102FB}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1D7CE}-\x{1D7FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F100}-\x{1F10A}\x{1FBF0}-\x{1FBF9}][\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1D167}-\x{1D169}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]*$/u'; + const BIDI_STEP_4_AN = '/[\x{0600}-\x{0605}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{06DD}\x{08E2}\x{10D30}-\x{10D39}\x{10E60}-\x{10E7E}]/u'; + const BIDI_STEP_4_EN = '/[\x{0030}-\x{0039}\x{00B2}-\x{00B3}\x{00B9}\x{06F0}-\x{06F9}\x{2070}\x{2074}-\x{2079}\x{2080}-\x{2089}\x{2488}-\x{249B}\x{FF10}-\x{FF19}\x{102E1}-\x{102FB}\x{1D7CE}-\x{1D7FF}\x{1F100}-\x{1F10A}\x{1FBF0}-\x{1FBF9}]/u'; + const BIDI_STEP_5 = '/[\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0085}\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{1680}\x{2000}-\x{200A}\x{200F}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{205F}\x{2066}\x{2067}\x{2068}\x{2069}\x{3000}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u'; + const BIDI_STEP_6 = '/[^\x{0000}-\x{0008}\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{000E}-\x{001B}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0085}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{1680}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{2000}-\x{200A}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{205F}\x{2060}-\x{2064}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}\x{206A}-\x{206F}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3000}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}][\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1D167}-\x{1D169}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]*$/u'; + + const ZWNJ = '/([\x{A872}\x{10ACD}\x{10AD7}\x{10D00}\x{10FCB}\x{0620}\x{0626}\x{0628}\x{062A}-\x{062E}\x{0633}-\x{063F}\x{0641}-\x{0647}\x{0649}-\x{064A}\x{066E}-\x{066F}\x{0678}-\x{0687}\x{069A}-\x{06BF}\x{06C1}-\x{06C2}\x{06CC}\x{06CE}\x{06D0}-\x{06D1}\x{06FA}-\x{06FC}\x{06FF}\x{0712}-\x{0714}\x{071A}-\x{071D}\x{071F}-\x{0727}\x{0729}\x{072B}\x{072D}-\x{072E}\x{074E}-\x{0758}\x{075C}-\x{076A}\x{076D}-\x{0770}\x{0772}\x{0775}-\x{0777}\x{077A}-\x{077F}\x{07CA}-\x{07EA}\x{0841}-\x{0845}\x{0848}\x{084A}-\x{0853}\x{0855}\x{0860}\x{0862}-\x{0865}\x{0868}\x{08A0}-\x{08A9}\x{08AF}-\x{08B0}\x{08B3}-\x{08B4}\x{08B6}-\x{08B8}\x{08BA}-\x{08C7}\x{1807}\x{1820}-\x{1842}\x{1843}\x{1844}-\x{1878}\x{1887}-\x{18A8}\x{18AA}\x{A840}-\x{A871}\x{10AC0}-\x{10AC4}\x{10AD3}-\x{10AD6}\x{10AD8}-\x{10ADC}\x{10ADE}-\x{10AE0}\x{10AEB}-\x{10AEE}\x{10B80}\x{10B82}\x{10B86}-\x{10B88}\x{10B8A}-\x{10B8B}\x{10B8D}\x{10B90}\x{10BAD}-\x{10BAE}\x{10D01}-\x{10D21}\x{10D23}\x{10F30}-\x{10F32}\x{10F34}-\x{10F44}\x{10F51}-\x{10F53}\x{10FB0}\x{10FB2}-\x{10FB3}\x{10FB8}\x{10FBB}-\x{10FBC}\x{10FBE}-\x{10FBF}\x{10FC1}\x{10FC4}\x{10FCA}\x{1E900}-\x{1E943}][\x{00AD}\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{061C}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{200B}\x{200E}-\x{200F}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{206A}-\x{206F}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{FEFF}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{13430}-\x{13438}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1E94B}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}]*\x{200C}[\x{00AD}\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{061C}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{200B}\x{200E}-\x{200F}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{206A}-\x{206F}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{FEFF}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{13430}-\x{13438}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1E94B}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}]*)[\x{0622}-\x{0625}\x{0627}\x{0629}\x{062F}-\x{0632}\x{0648}\x{0671}-\x{0673}\x{0675}-\x{0677}\x{0688}-\x{0699}\x{06C0}\x{06C3}-\x{06CB}\x{06CD}\x{06CF}\x{06D2}-\x{06D3}\x{06D5}\x{06EE}-\x{06EF}\x{0710}\x{0715}-\x{0719}\x{071E}\x{0728}\x{072A}\x{072C}\x{072F}\x{074D}\x{0759}-\x{075B}\x{076B}-\x{076C}\x{0771}\x{0773}-\x{0774}\x{0778}-\x{0779}\x{0840}\x{0846}-\x{0847}\x{0849}\x{0854}\x{0856}-\x{0858}\x{0867}\x{0869}-\x{086A}\x{08AA}-\x{08AC}\x{08AE}\x{08B1}-\x{08B2}\x{08B9}\x{10AC5}\x{10AC7}\x{10AC9}-\x{10ACA}\x{10ACE}-\x{10AD2}\x{10ADD}\x{10AE1}\x{10AE4}\x{10AEF}\x{10B81}\x{10B83}-\x{10B85}\x{10B89}\x{10B8C}\x{10B8E}-\x{10B8F}\x{10B91}\x{10BA9}-\x{10BAC}\x{10D22}\x{10F33}\x{10F54}\x{10FB4}-\x{10FB6}\x{10FB9}-\x{10FBA}\x{10FBD}\x{10FC2}-\x{10FC3}\x{10FC9}\x{0620}\x{0626}\x{0628}\x{062A}-\x{062E}\x{0633}-\x{063F}\x{0641}-\x{0647}\x{0649}-\x{064A}\x{066E}-\x{066F}\x{0678}-\x{0687}\x{069A}-\x{06BF}\x{06C1}-\x{06C2}\x{06CC}\x{06CE}\x{06D0}-\x{06D1}\x{06FA}-\x{06FC}\x{06FF}\x{0712}-\x{0714}\x{071A}-\x{071D}\x{071F}-\x{0727}\x{0729}\x{072B}\x{072D}-\x{072E}\x{074E}-\x{0758}\x{075C}-\x{076A}\x{076D}-\x{0770}\x{0772}\x{0775}-\x{0777}\x{077A}-\x{077F}\x{07CA}-\x{07EA}\x{0841}-\x{0845}\x{0848}\x{084A}-\x{0853}\x{0855}\x{0860}\x{0862}-\x{0865}\x{0868}\x{08A0}-\x{08A9}\x{08AF}-\x{08B0}\x{08B3}-\x{08B4}\x{08B6}-\x{08B8}\x{08BA}-\x{08C7}\x{1807}\x{1820}-\x{1842}\x{1843}\x{1844}-\x{1878}\x{1887}-\x{18A8}\x{18AA}\x{A840}-\x{A871}\x{10AC0}-\x{10AC4}\x{10AD3}-\x{10AD6}\x{10AD8}-\x{10ADC}\x{10ADE}-\x{10AE0}\x{10AEB}-\x{10AEE}\x{10B80}\x{10B82}\x{10B86}-\x{10B88}\x{10B8A}-\x{10B8B}\x{10B8D}\x{10B90}\x{10BAD}-\x{10BAE}\x{10D01}-\x{10D21}\x{10D23}\x{10F30}-\x{10F32}\x{10F34}-\x{10F44}\x{10F51}-\x{10F53}\x{10FB0}\x{10FB2}-\x{10FB3}\x{10FB8}\x{10FBB}-\x{10FBC}\x{10FBE}-\x{10FBF}\x{10FC1}\x{10FC4}\x{10FCA}\x{1E900}-\x{1E943}]/u'; +} diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/deviation.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/deviation.php new file mode 100644 index 0000000..0bbd335 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/deviation.php @@ -0,0 +1,8 @@ + 'ss', + 962 => 'σ', + 8204 => '', + 8205 => '', +); diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php new file mode 100644 index 0000000..25a5f56 --- /dev/null +++ b/lib/SymfonyMailer/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/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php new file mode 100644 index 0000000..54f21cc --- /dev/null +++ b/lib/SymfonyMailer/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/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php new file mode 100644 index 0000000..223396e --- /dev/null +++ b/lib/SymfonyMailer/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/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/ignored.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/ignored.php new file mode 100644 index 0000000..b377844 --- /dev/null +++ b/lib/SymfonyMailer/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/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/mapped.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/mapped.php new file mode 100644 index 0000000..9b85fe9 --- /dev/null +++ b/lib/SymfonyMailer/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/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/virama.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/Resources/unidata/virama.php new file mode 100644 index 0000000..1958e37 --- /dev/null +++ b/lib/SymfonyMailer/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/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/bootstrap.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/bootstrap.php new file mode 100644 index 0000000..57c7835 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/bootstrap.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Intl\Idn as p; + +if (extension_loaded('intl')) { + return; +} + +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (!defined('U_IDNA_PROHIBITED_ERROR')) { + define('U_IDNA_PROHIBITED_ERROR', 66560); +} +if (!defined('U_IDNA_ERROR_START')) { + define('U_IDNA_ERROR_START', 66560); +} +if (!defined('U_IDNA_UNASSIGNED_ERROR')) { + define('U_IDNA_UNASSIGNED_ERROR', 66561); +} +if (!defined('U_IDNA_CHECK_BIDI_ERROR')) { + define('U_IDNA_CHECK_BIDI_ERROR', 66562); +} +if (!defined('U_IDNA_STD3_ASCII_RULES_ERROR')) { + define('U_IDNA_STD3_ASCII_RULES_ERROR', 66563); +} +if (!defined('U_IDNA_ACE_PREFIX_ERROR')) { + define('U_IDNA_ACE_PREFIX_ERROR', 66564); +} +if (!defined('U_IDNA_VERIFICATION_ERROR')) { + define('U_IDNA_VERIFICATION_ERROR', 66565); +} +if (!defined('U_IDNA_LABEL_TOO_LONG_ERROR')) { + define('U_IDNA_LABEL_TOO_LONG_ERROR', 66566); +} +if (!defined('U_IDNA_ZERO_LENGTH_LABEL_ERROR')) { + define('U_IDNA_ZERO_LENGTH_LABEL_ERROR', 66567); +} +if (!defined('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR')) { + define('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR', 66568); +} +if (!defined('U_IDNA_ERROR_LIMIT')) { + define('U_IDNA_ERROR_LIMIT', 66569); +} +if (!defined('U_STRINGPREP_PROHIBITED_ERROR')) { + define('U_STRINGPREP_PROHIBITED_ERROR', 66560); +} +if (!defined('U_STRINGPREP_UNASSIGNED_ERROR')) { + define('U_STRINGPREP_UNASSIGNED_ERROR', 66561); +} +if (!defined('U_STRINGPREP_CHECK_BIDI_ERROR')) { + define('U_STRINGPREP_CHECK_BIDI_ERROR', 66562); +} +if (!defined('IDNA_DEFAULT')) { + define('IDNA_DEFAULT', 0); +} +if (!defined('IDNA_ALLOW_UNASSIGNED')) { + define('IDNA_ALLOW_UNASSIGNED', 1); +} +if (!defined('IDNA_USE_STD3_RULES')) { + define('IDNA_USE_STD3_RULES', 2); +} +if (!defined('IDNA_CHECK_BIDI')) { + define('IDNA_CHECK_BIDI', 4); +} +if (!defined('IDNA_CHECK_CONTEXTJ')) { + define('IDNA_CHECK_CONTEXTJ', 8); +} +if (!defined('IDNA_NONTRANSITIONAL_TO_ASCII')) { + define('IDNA_NONTRANSITIONAL_TO_ASCII', 16); +} +if (!defined('IDNA_NONTRANSITIONAL_TO_UNICODE')) { + define('IDNA_NONTRANSITIONAL_TO_UNICODE', 32); +} +if (!defined('INTL_IDNA_VARIANT_2003')) { + define('INTL_IDNA_VARIANT_2003', 0); +} +if (!defined('INTL_IDNA_VARIANT_UTS46')) { + define('INTL_IDNA_VARIANT_UTS46', 1); +} +if (!defined('IDNA_ERROR_EMPTY_LABEL')) { + define('IDNA_ERROR_EMPTY_LABEL', 1); +} +if (!defined('IDNA_ERROR_LABEL_TOO_LONG')) { + define('IDNA_ERROR_LABEL_TOO_LONG', 2); +} +if (!defined('IDNA_ERROR_DOMAIN_NAME_TOO_LONG')) { + define('IDNA_ERROR_DOMAIN_NAME_TOO_LONG', 4); +} +if (!defined('IDNA_ERROR_LEADING_HYPHEN')) { + define('IDNA_ERROR_LEADING_HYPHEN', 8); +} +if (!defined('IDNA_ERROR_TRAILING_HYPHEN')) { + define('IDNA_ERROR_TRAILING_HYPHEN', 16); +} +if (!defined('IDNA_ERROR_HYPHEN_3_4')) { + define('IDNA_ERROR_HYPHEN_3_4', 32); +} +if (!defined('IDNA_ERROR_LEADING_COMBINING_MARK')) { + define('IDNA_ERROR_LEADING_COMBINING_MARK', 64); +} +if (!defined('IDNA_ERROR_DISALLOWED')) { + define('IDNA_ERROR_DISALLOWED', 128); +} +if (!defined('IDNA_ERROR_PUNYCODE')) { + define('IDNA_ERROR_PUNYCODE', 256); +} +if (!defined('IDNA_ERROR_LABEL_HAS_DOT')) { + define('IDNA_ERROR_LABEL_HAS_DOT', 512); +} +if (!defined('IDNA_ERROR_INVALID_ACE_LABEL')) { + define('IDNA_ERROR_INVALID_ACE_LABEL', 1024); +} +if (!defined('IDNA_ERROR_BIDI')) { + define('IDNA_ERROR_BIDI', 2048); +} +if (!defined('IDNA_ERROR_CONTEXTJ')) { + define('IDNA_ERROR_CONTEXTJ', 4096); +} + +if (\PHP_VERSION_ID < 70400) { + if (!function_exists('idn_to_ascii')) { + function idn_to_ascii($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_2003, &$idna_info = null) { return p\Idn::idn_to_ascii($domain, $flags, $variant, $idna_info); } + } + if (!function_exists('idn_to_utf8')) { + function idn_to_utf8($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_2003, &$idna_info = null) { return p\Idn::idn_to_utf8($domain, $flags, $variant, $idna_info); } + } +} else { + if (!function_exists('idn_to_ascii')) { + function idn_to_ascii($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_UTS46, &$idna_info = null) { return p\Idn::idn_to_ascii($domain, $flags, $variant, $idna_info); } + } + if (!function_exists('idn_to_utf8')) { + function idn_to_utf8($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_UTS46, &$idna_info = null) { return p\Idn::idn_to_utf8($domain, $flags, $variant, $idna_info); } + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/bootstrap80.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/bootstrap80.php new file mode 100644 index 0000000..a62c2d6 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/bootstrap80.php @@ -0,0 +1,125 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Intl\Idn as p; + +if (!defined('U_IDNA_PROHIBITED_ERROR')) { + define('U_IDNA_PROHIBITED_ERROR', 66560); +} +if (!defined('U_IDNA_ERROR_START')) { + define('U_IDNA_ERROR_START', 66560); +} +if (!defined('U_IDNA_UNASSIGNED_ERROR')) { + define('U_IDNA_UNASSIGNED_ERROR', 66561); +} +if (!defined('U_IDNA_CHECK_BIDI_ERROR')) { + define('U_IDNA_CHECK_BIDI_ERROR', 66562); +} +if (!defined('U_IDNA_STD3_ASCII_RULES_ERROR')) { + define('U_IDNA_STD3_ASCII_RULES_ERROR', 66563); +} +if (!defined('U_IDNA_ACE_PREFIX_ERROR')) { + define('U_IDNA_ACE_PREFIX_ERROR', 66564); +} +if (!defined('U_IDNA_VERIFICATION_ERROR')) { + define('U_IDNA_VERIFICATION_ERROR', 66565); +} +if (!defined('U_IDNA_LABEL_TOO_LONG_ERROR')) { + define('U_IDNA_LABEL_TOO_LONG_ERROR', 66566); +} +if (!defined('U_IDNA_ZERO_LENGTH_LABEL_ERROR')) { + define('U_IDNA_ZERO_LENGTH_LABEL_ERROR', 66567); +} +if (!defined('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR')) { + define('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR', 66568); +} +if (!defined('U_IDNA_ERROR_LIMIT')) { + define('U_IDNA_ERROR_LIMIT', 66569); +} +if (!defined('U_STRINGPREP_PROHIBITED_ERROR')) { + define('U_STRINGPREP_PROHIBITED_ERROR', 66560); +} +if (!defined('U_STRINGPREP_UNASSIGNED_ERROR')) { + define('U_STRINGPREP_UNASSIGNED_ERROR', 66561); +} +if (!defined('U_STRINGPREP_CHECK_BIDI_ERROR')) { + define('U_STRINGPREP_CHECK_BIDI_ERROR', 66562); +} +if (!defined('IDNA_DEFAULT')) { + define('IDNA_DEFAULT', 0); +} +if (!defined('IDNA_ALLOW_UNASSIGNED')) { + define('IDNA_ALLOW_UNASSIGNED', 1); +} +if (!defined('IDNA_USE_STD3_RULES')) { + define('IDNA_USE_STD3_RULES', 2); +} +if (!defined('IDNA_CHECK_BIDI')) { + define('IDNA_CHECK_BIDI', 4); +} +if (!defined('IDNA_CHECK_CONTEXTJ')) { + define('IDNA_CHECK_CONTEXTJ', 8); +} +if (!defined('IDNA_NONTRANSITIONAL_TO_ASCII')) { + define('IDNA_NONTRANSITIONAL_TO_ASCII', 16); +} +if (!defined('IDNA_NONTRANSITIONAL_TO_UNICODE')) { + define('IDNA_NONTRANSITIONAL_TO_UNICODE', 32); +} +if (!defined('INTL_IDNA_VARIANT_UTS46')) { + define('INTL_IDNA_VARIANT_UTS46', 1); +} +if (!defined('IDNA_ERROR_EMPTY_LABEL')) { + define('IDNA_ERROR_EMPTY_LABEL', 1); +} +if (!defined('IDNA_ERROR_LABEL_TOO_LONG')) { + define('IDNA_ERROR_LABEL_TOO_LONG', 2); +} +if (!defined('IDNA_ERROR_DOMAIN_NAME_TOO_LONG')) { + define('IDNA_ERROR_DOMAIN_NAME_TOO_LONG', 4); +} +if (!defined('IDNA_ERROR_LEADING_HYPHEN')) { + define('IDNA_ERROR_LEADING_HYPHEN', 8); +} +if (!defined('IDNA_ERROR_TRAILING_HYPHEN')) { + define('IDNA_ERROR_TRAILING_HYPHEN', 16); +} +if (!defined('IDNA_ERROR_HYPHEN_3_4')) { + define('IDNA_ERROR_HYPHEN_3_4', 32); +} +if (!defined('IDNA_ERROR_LEADING_COMBINING_MARK')) { + define('IDNA_ERROR_LEADING_COMBINING_MARK', 64); +} +if (!defined('IDNA_ERROR_DISALLOWED')) { + define('IDNA_ERROR_DISALLOWED', 128); +} +if (!defined('IDNA_ERROR_PUNYCODE')) { + define('IDNA_ERROR_PUNYCODE', 256); +} +if (!defined('IDNA_ERROR_LABEL_HAS_DOT')) { + define('IDNA_ERROR_LABEL_HAS_DOT', 512); +} +if (!defined('IDNA_ERROR_INVALID_ACE_LABEL')) { + define('IDNA_ERROR_INVALID_ACE_LABEL', 1024); +} +if (!defined('IDNA_ERROR_BIDI')) { + define('IDNA_ERROR_BIDI', 2048); +} +if (!defined('IDNA_ERROR_CONTEXTJ')) { + define('IDNA_ERROR_CONTEXTJ', 4096); +} + +if (!function_exists('idn_to_ascii')) { + function idn_to_ascii(?string $domain, ?int $flags = IDNA_DEFAULT, ?int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_ascii((string) $domain, (int) $flags, (int) $variant, $idna_info); } +} +if (!function_exists('idn_to_utf8')) { + function idn_to_utf8(?string $domain, ?int $flags = IDNA_DEFAULT, ?int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_utf8((string) $domain, (int) $flags, (int) $variant, $idna_info); } +} diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/composer.json b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/composer.json new file mode 100644 index 0000000..760debc --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-idn/composer.json @@ -0,0 +1,40 @@ +{ + "name": "symfony/polyfill-intl-idn", + "type": "library", + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "keywords": ["polyfill", "shim", "compatibility", "portable", "intl", "idn"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Intl\\Idn\\": "" }, + "files": [ "bootstrap.php" ] + }, + "suggest": { + "ext-intl": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/LICENSE b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/LICENSE new file mode 100644 index 0000000..6e3afce --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Normalizer.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Normalizer.php new file mode 100644 index 0000000..81704ab --- /dev/null +++ b/lib/SymfonyMailer/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/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/README.md b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/README.md new file mode 100644 index 0000000..b9b762e --- /dev/null +++ b/lib/SymfonyMailer/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/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php new file mode 100644 index 0000000..0fdfc89 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php @@ -0,0 +1,17 @@ + 'À', + 'Á' => 'Á', + 'Â' => 'Â', + 'Ã' => 'Ã', + 'Ä' => 'Ä', + 'Å' => 'Å', + 'Ç' => 'Ç', + 'È' => 'È', + 'É' => 'É', + 'Ê' => 'Ê', + 'Ë' => 'Ë', + 'Ì' => 'Ì', + 'Í' => 'Í', + 'Î' => 'Î', + 'Ï' => 'Ï', + 'Ñ' => 'Ñ', + 'Ò' => 'Ò', + 'Ó' => 'Ó', + 'Ô' => 'Ô', + 'Õ' => 'Õ', + 'Ö' => 'Ö', + 'Ù' => 'Ù', + 'Ú' => 'Ú', + 'Û' => 'Û', + 'Ü' => 'Ü', + 'Ý' => 'Ý', + 'à' => 'à', + 'á' => 'á', + 'â' => 'â', + 'ã' => 'ã', + 'ä' => 'ä', + 'å' => 'å', + 'ç' => 'ç', + 'è' => 'è', + 'é' => 'é', + 'ê' => 'ê', + 'ë' => 'ë', + 'ì' => 'ì', + 'í' => 'í', + 'î' => 'î', + 'ï' => 'ï', + 'ñ' => 'ñ', + 'ò' => 'ò', + 'ó' => 'ó', + 'ô' => 'ô', + 'õ' => 'õ', + 'ö' => 'ö', + 'ù' => 'ù', + 'ú' => 'ú', + 'û' => 'û', + 'ü' => 'ü', + 'ý' => 'ý', + 'ÿ' => 'ÿ', + 'Ā' => 'Ā', + 'ā' => 'ā', + 'Ă' => 'Ă', + 'ă' => 'ă', + 'Ą' => 'Ą', + 'ą' => 'ą', + 'Ć' => 'Ć', + 'ć' => 'ć', + 'Ĉ' => 'Ĉ', + 'ĉ' => 'ĉ', + 'Ċ' => 'Ċ', + 'ċ' => 'ċ', + 'Č' => 'Č', + 'č' => 'č', + 'Ď' => 'Ď', + 'ď' => 'ď', + 'Ē' => 'Ē', + 'ē' => 'ē', + 'Ĕ' => 'Ĕ', + 'ĕ' => 'ĕ', + 'Ė' => 'Ė', + 'ė' => 'ė', + 'Ę' => 'Ę', + 'ę' => 'ę', + 'Ě' => 'Ě', + 'ě' => 'ě', + 'Ĝ' => 'Ĝ', + 'ĝ' => 'ĝ', + 'Ğ' => 'Ğ', + 'ğ' => 'ğ', + 'Ġ' => 'Ġ', + 'ġ' => 'ġ', + 'Ģ' => 'Ģ', + 'ģ' => 'ģ', + 'Ĥ' => 'Ĥ', + 'ĥ' => 'ĥ', + 'Ĩ' => 'Ĩ', + 'ĩ' => 'ĩ', + 'Ī' => 'Ī', + 'ī' => 'ī', + 'Ĭ' => 'Ĭ', + 'ĭ' => 'ĭ', + 'Į' => 'Į', + 'į' => 'į', + 'İ' => 'İ', + 'Ĵ' => 'Ĵ', + 'ĵ' => 'ĵ', + 'Ķ' => 'Ķ', + 'ķ' => 'ķ', + 'Ĺ' => 'Ĺ', + 'ĺ' => 'ĺ', + 'Ļ' => 'Ļ', + 'ļ' => 'ļ', + 'Ľ' => 'Ľ', + 'ľ' => 'ľ', + 'Ń' => 'Ń', + 'ń' => 'ń', + 'Ņ' => 'Ņ', + 'ņ' => 'ņ', + 'Ň' => 'Ň', + 'ň' => 'ň', + 'Ō' => 'Ō', + 'ō' => 'ō', + 'Ŏ' => 'Ŏ', + 'ŏ' => 'ŏ', + 'Ő' => 'Ő', + 'ő' => 'ő', + 'Ŕ' => 'Ŕ', + 'ŕ' => 'ŕ', + 'Ŗ' => 'Ŗ', + 'ŗ' => 'ŗ', + 'Ř' => 'Ř', + 'ř' => 'ř', + 'Ś' => 'Ś', + 'ś' => 'ś', + 'Ŝ' => 'Ŝ', + 'ŝ' => 'ŝ', + 'Ş' => 'Ş', + 'ş' => 'ş', + 'Š' => 'Š', + 'š' => 'š', + 'Ţ' => 'Ţ', + 'ţ' => 'ţ', + 'Ť' => 'Ť', + 'ť' => 'ť', + 'Ũ' => 'Ũ', + 'ũ' => 'ũ', + 'Ū' => 'Ū', + 'ū' => 'ū', + 'Ŭ' => 'Ŭ', + 'ŭ' => 'ŭ', + 'Ů' => 'Ů', + 'ů' => 'ů', + 'Ű' => 'Ű', + 'ű' => 'ű', + 'Ų' => 'Ų', + 'ų' => 'ų', + 'Ŵ' => 'Ŵ', + 'ŵ' => 'ŵ', + 'Ŷ' => 'Ŷ', + 'ŷ' => 'ŷ', + 'Ÿ' => 'Ÿ', + 'Ź' => 'Ź', + 'ź' => 'ź', + 'Ż' => 'Ż', + 'ż' => 'ż', + 'Ž' => 'Ž', + 'ž' => 'ž', + 'Ơ' => 'Ơ', + 'ơ' => 'ơ', + 'Ư' => 'Ư', + 'ư' => 'ư', + 'Ǎ' => 'Ǎ', + 'ǎ' => 'ǎ', + 'Ǐ' => 'Ǐ', + 'ǐ' => 'ǐ', + 'Ǒ' => 'Ǒ', + 'ǒ' => 'ǒ', + 'Ǔ' => 'Ǔ', + 'ǔ' => 'ǔ', + 'Ǖ' => 'Ǖ', + 'ǖ' => 'ǖ', + 'Ǘ' => 'Ǘ', + 'ǘ' => 'ǘ', + 'Ǚ' => 'Ǚ', + 'ǚ' => 'ǚ', + 'Ǜ' => 'Ǜ', + 'ǜ' => 'ǜ', + 'Ǟ' => 'Ǟ', + 'ǟ' => 'ǟ', + 'Ǡ' => 'Ǡ', + 'ǡ' => 'ǡ', + 'Ǣ' => 'Ǣ', + 'ǣ' => 'ǣ', + 'Ǧ' => 'Ǧ', + 'ǧ' => 'ǧ', + 'Ǩ' => 'Ǩ', + 'ǩ' => 'ǩ', + 'Ǫ' => 'Ǫ', + 'ǫ' => 'ǫ', + 'Ǭ' => 'Ǭ', + 'ǭ' => 'ǭ', + 'Ǯ' => 'Ǯ', + 'ǯ' => 'ǯ', + 'ǰ' => 'ǰ', + 'Ǵ' => 'Ǵ', + 'ǵ' => 'ǵ', + 'Ǹ' => 'Ǹ', + 'ǹ' => 'ǹ', + 'Ǻ' => 'Ǻ', + 'ǻ' => 'ǻ', + 'Ǽ' => 'Ǽ', + 'ǽ' => 'ǽ', + 'Ǿ' => 'Ǿ', + 'ǿ' => 'ǿ', + 'Ȁ' => 'Ȁ', + 'ȁ' => 'ȁ', + 'Ȃ' => 'Ȃ', + 'ȃ' => 'ȃ', + 'Ȅ' => 'Ȅ', + 'ȅ' => 'ȅ', + 'Ȇ' => 'Ȇ', + 'ȇ' => 'ȇ', + 'Ȉ' => 'Ȉ', + 'ȉ' => 'ȉ', + 'Ȋ' => 'Ȋ', + 'ȋ' => 'ȋ', + 'Ȍ' => 'Ȍ', + 'ȍ' => 'ȍ', + 'Ȏ' => 'Ȏ', + 'ȏ' => 'ȏ', + 'Ȑ' => 'Ȑ', + 'ȑ' => 'ȑ', + 'Ȓ' => 'Ȓ', + 'ȓ' => 'ȓ', + 'Ȕ' => 'Ȕ', + 'ȕ' => 'ȕ', + 'Ȗ' => 'Ȗ', + 'ȗ' => 'ȗ', + 'Ș' => 'Ș', + 'ș' => 'ș', + 'Ț' => 'Ț', + 'ț' => 'ț', + 'Ȟ' => 'Ȟ', + 'ȟ' => 'ȟ', + 'Ȧ' => 'Ȧ', + 'ȧ' => 'ȧ', + 'Ȩ' => 'Ȩ', + 'ȩ' => 'ȩ', + 'Ȫ' => 'Ȫ', + 'ȫ' => 'ȫ', + 'Ȭ' => 'Ȭ', + 'ȭ' => 'ȭ', + 'Ȯ' => 'Ȯ', + 'ȯ' => 'ȯ', + 'Ȱ' => 'Ȱ', + 'ȱ' => 'ȱ', + 'Ȳ' => 'Ȳ', + 'ȳ' => 'ȳ', + '΅' => '΅', + 'Ά' => 'Ά', + 'Έ' => 'Έ', + 'Ή' => 'Ή', + 'Ί' => 'Ί', + 'Ό' => 'Ό', + 'Ύ' => 'Ύ', + 'Ώ' => 'Ώ', + 'ΐ' => 'ΐ', + 'Ϊ' => 'Ϊ', + 'Ϋ' => 'Ϋ', + 'ά' => 'ά', + 'έ' => 'έ', + 'ή' => 'ή', + 'ί' => 'ί', + 'ΰ' => 'ΰ', + 'ϊ' => 'ϊ', + 'ϋ' => 'ϋ', + 'ό' => 'ό', + 'ύ' => 'ύ', + 'ώ' => 'ώ', + 'ϓ' => 'ϓ', + 'ϔ' => 'ϔ', + 'Ѐ' => 'Ѐ', + 'Ё' => 'Ё', + 'Ѓ' => 'Ѓ', + 'Ї' => 'Ї', + 'Ќ' => 'Ќ', + 'Ѝ' => 'Ѝ', + 'Ў' => 'Ў', + 'Й' => 'Й', + 'й' => 'й', + 'ѐ' => 'ѐ', + 'ё' => 'ё', + 'ѓ' => 'ѓ', + 'ї' => 'ї', + 'ќ' => 'ќ', + 'ѝ' => 'ѝ', + 'ў' => 'ў', + 'Ѷ' => 'Ѷ', + 'ѷ' => 'ѷ', + 'Ӂ' => 'Ӂ', + 'ӂ' => 'ӂ', + 'Ӑ' => 'Ӑ', + 'ӑ' => 'ӑ', + 'Ӓ' => 'Ӓ', + 'ӓ' => 'ӓ', + 'Ӗ' => 'Ӗ', + 'ӗ' => 'ӗ', + 'Ӛ' => 'Ӛ', + 'ӛ' => 'ӛ', + 'Ӝ' => 'Ӝ', + 'ӝ' => 'ӝ', + 'Ӟ' => 'Ӟ', + 'ӟ' => 'ӟ', + 'Ӣ' => 'Ӣ', + 'ӣ' => 'ӣ', + 'Ӥ' => 'Ӥ', + 'ӥ' => 'ӥ', + 'Ӧ' => 'Ӧ', + 'ӧ' => 'ӧ', + 'Ӫ' => 'Ӫ', + 'ӫ' => 'ӫ', + 'Ӭ' => 'Ӭ', + 'ӭ' => 'ӭ', + 'Ӯ' => 'Ӯ', + 'ӯ' => 'ӯ', + 'Ӱ' => 'Ӱ', + 'ӱ' => 'ӱ', + 'Ӳ' => 'Ӳ', + 'ӳ' => 'ӳ', + 'Ӵ' => 'Ӵ', + 'ӵ' => 'ӵ', + 'Ӹ' => 'Ӹ', + 'ӹ' => 'ӹ', + 'آ' => 'آ', + 'أ' => 'أ', + 'ؤ' => 'ؤ', + 'إ' => 'إ', + 'ئ' => 'ئ', + 'ۀ' => 'ۀ', + 'ۂ' => 'ۂ', + 'ۓ' => 'ۓ', + 'ऩ' => 'ऩ', + 'ऱ' => 'ऱ', + 'ऴ' => 'ऴ', + 'ো' => 'ো', + 'ৌ' => 'ৌ', + 'ୈ' => 'ୈ', + 'ୋ' => 'ୋ', + 'ୌ' => 'ୌ', + 'ஔ' => 'ஔ', + 'ொ' => 'ொ', + 'ோ' => 'ோ', + 'ௌ' => 'ௌ', + 'ై' => 'ై', + 'ೀ' => 'ೀ', + 'ೇ' => 'ೇ', + 'ೈ' => 'ೈ', + 'ೊ' => 'ೊ', + 'ೋ' => 'ೋ', + 'ൊ' => 'ൊ', + 'ോ' => 'ോ', + 'ൌ' => 'ൌ', + 'ේ' => 'ේ', + 'ො' => 'ො', + 'ෝ' => 'ෝ', + 'ෞ' => 'ෞ', + 'ဦ' => 'ဦ', + 'ᬆ' => 'ᬆ', + 'ᬈ' => 'ᬈ', + 'ᬊ' => 'ᬊ', + 'ᬌ' => 'ᬌ', + 'ᬎ' => 'ᬎ', + 'ᬒ' => 'ᬒ', + 'ᬻ' => 'ᬻ', + 'ᬽ' => 'ᬽ', + 'ᭀ' => 'ᭀ', + 'ᭁ' => 'ᭁ', + 'ᭃ' => 'ᭃ', + 'Ḁ' => 'Ḁ', + 'ḁ' => 'ḁ', + 'Ḃ' => 'Ḃ', + 'ḃ' => 'ḃ', + 'Ḅ' => 'Ḅ', + 'ḅ' => 'ḅ', + 'Ḇ' => 'Ḇ', + 'ḇ' => 'ḇ', + 'Ḉ' => 'Ḉ', + 'ḉ' => 'ḉ', + 'Ḋ' => 'Ḋ', + 'ḋ' => 'ḋ', + 'Ḍ' => 'Ḍ', + 'ḍ' => 'ḍ', + 'Ḏ' => 'Ḏ', + 'ḏ' => 'ḏ', + 'Ḑ' => 'Ḑ', + 'ḑ' => 'ḑ', + 'Ḓ' => 'Ḓ', + 'ḓ' => 'ḓ', + 'Ḕ' => 'Ḕ', + 'ḕ' => 'ḕ', + 'Ḗ' => 'Ḗ', + 'ḗ' => 'ḗ', + 'Ḙ' => 'Ḙ', + 'ḙ' => 'ḙ', + 'Ḛ' => 'Ḛ', + 'ḛ' => 'ḛ', + 'Ḝ' => 'Ḝ', + 'ḝ' => 'ḝ', + 'Ḟ' => 'Ḟ', + 'ḟ' => 'ḟ', + 'Ḡ' => 'Ḡ', + 'ḡ' => 'ḡ', + 'Ḣ' => 'Ḣ', + 'ḣ' => 'ḣ', + 'Ḥ' => 'Ḥ', + 'ḥ' => 'ḥ', + 'Ḧ' => 'Ḧ', + 'ḧ' => 'ḧ', + 'Ḩ' => 'Ḩ', + 'ḩ' => 'ḩ', + 'Ḫ' => 'Ḫ', + 'ḫ' => 'ḫ', + 'Ḭ' => 'Ḭ', + 'ḭ' => 'ḭ', + 'Ḯ' => 'Ḯ', + 'ḯ' => 'ḯ', + 'Ḱ' => 'Ḱ', + 'ḱ' => 'ḱ', + 'Ḳ' => 'Ḳ', + 'ḳ' => 'ḳ', + 'Ḵ' => 'Ḵ', + 'ḵ' => 'ḵ', + 'Ḷ' => 'Ḷ', + 'ḷ' => 'ḷ', + 'Ḹ' => 'Ḹ', + 'ḹ' => 'ḹ', + 'Ḻ' => 'Ḻ', + 'ḻ' => 'ḻ', + 'Ḽ' => 'Ḽ', + 'ḽ' => 'ḽ', + 'Ḿ' => 'Ḿ', + 'ḿ' => 'ḿ', + 'Ṁ' => 'Ṁ', + 'ṁ' => 'ṁ', + 'Ṃ' => 'Ṃ', + 'ṃ' => 'ṃ', + 'Ṅ' => 'Ṅ', + 'ṅ' => 'ṅ', + 'Ṇ' => 'Ṇ', + 'ṇ' => 'ṇ', + 'Ṉ' => 'Ṉ', + 'ṉ' => 'ṉ', + 'Ṋ' => 'Ṋ', + 'ṋ' => 'ṋ', + 'Ṍ' => 'Ṍ', + 'ṍ' => 'ṍ', + 'Ṏ' => 'Ṏ', + 'ṏ' => 'ṏ', + 'Ṑ' => 'Ṑ', + 'ṑ' => 'ṑ', + 'Ṓ' => 'Ṓ', + 'ṓ' => 'ṓ', + 'Ṕ' => 'Ṕ', + 'ṕ' => 'ṕ', + 'Ṗ' => 'Ṗ', + 'ṗ' => 'ṗ', + 'Ṙ' => 'Ṙ', + 'ṙ' => 'ṙ', + 'Ṛ' => 'Ṛ', + 'ṛ' => 'ṛ', + 'Ṝ' => 'Ṝ', + 'ṝ' => 'ṝ', + 'Ṟ' => 'Ṟ', + 'ṟ' => 'ṟ', + 'Ṡ' => 'Ṡ', + 'ṡ' => 'ṡ', + 'Ṣ' => 'Ṣ', + 'ṣ' => 'ṣ', + 'Ṥ' => 'Ṥ', + 'ṥ' => 'ṥ', + 'Ṧ' => 'Ṧ', + 'ṧ' => 'ṧ', + 'Ṩ' => 'Ṩ', + 'ṩ' => 'ṩ', + 'Ṫ' => 'Ṫ', + 'ṫ' => 'ṫ', + 'Ṭ' => 'Ṭ', + 'ṭ' => 'ṭ', + 'Ṯ' => 'Ṯ', + 'ṯ' => 'ṯ', + 'Ṱ' => 'Ṱ', + 'ṱ' => 'ṱ', + 'Ṳ' => 'Ṳ', + 'ṳ' => 'ṳ', + 'Ṵ' => 'Ṵ', + 'ṵ' => 'ṵ', + 'Ṷ' => 'Ṷ', + 'ṷ' => 'ṷ', + 'Ṹ' => 'Ṹ', + 'ṹ' => 'ṹ', + 'Ṻ' => 'Ṻ', + 'ṻ' => 'ṻ', + 'Ṽ' => 'Ṽ', + 'ṽ' => 'ṽ', + 'Ṿ' => 'Ṿ', + 'ṿ' => 'ṿ', + 'Ẁ' => 'Ẁ', + 'ẁ' => 'ẁ', + 'Ẃ' => 'Ẃ', + 'ẃ' => 'ẃ', + 'Ẅ' => 'Ẅ', + 'ẅ' => 'ẅ', + 'Ẇ' => 'Ẇ', + 'ẇ' => 'ẇ', + 'Ẉ' => 'Ẉ', + 'ẉ' => 'ẉ', + 'Ẋ' => 'Ẋ', + 'ẋ' => 'ẋ', + 'Ẍ' => 'Ẍ', + 'ẍ' => 'ẍ', + 'Ẏ' => 'Ẏ', + 'ẏ' => 'ẏ', + 'Ẑ' => 'Ẑ', + 'ẑ' => 'ẑ', + 'Ẓ' => 'Ẓ', + 'ẓ' => 'ẓ', + 'Ẕ' => 'Ẕ', + 'ẕ' => 'ẕ', + 'ẖ' => 'ẖ', + 'ẗ' => 'ẗ', + 'ẘ' => 'ẘ', + 'ẙ' => 'ẙ', + 'ẛ' => 'ẛ', + 'Ạ' => 'Ạ', + 'ạ' => 'ạ', + 'Ả' => 'Ả', + 'ả' => 'ả', + 'Ấ' => 'Ấ', + 'ấ' => 'ấ', + 'Ầ' => 'Ầ', + 'ầ' => 'ầ', + 'Ẩ' => 'Ẩ', + 'ẩ' => 'ẩ', + 'Ẫ' => 'Ẫ', + 'ẫ' => 'ẫ', + 'Ậ' => 'Ậ', + 'ậ' => 'ậ', + 'Ắ' => 'Ắ', + 'ắ' => 'ắ', + 'Ằ' => 'Ằ', + 'ằ' => 'ằ', + 'Ẳ' => 'Ẳ', + 'ẳ' => 'ẳ', + 'Ẵ' => 'Ẵ', + 'ẵ' => 'ẵ', + 'Ặ' => 'Ặ', + 'ặ' => 'ặ', + 'Ẹ' => 'Ẹ', + 'ẹ' => 'ẹ', + 'Ẻ' => 'Ẻ', + 'ẻ' => 'ẻ', + 'Ẽ' => 'Ẽ', + 'ẽ' => 'ẽ', + 'Ế' => 'Ế', + 'ế' => 'ế', + 'Ề' => 'Ề', + 'ề' => 'ề', + 'Ể' => 'Ể', + 'ể' => 'ể', + 'Ễ' => 'Ễ', + 'ễ' => 'ễ', + 'Ệ' => 'Ệ', + 'ệ' => 'ệ', + 'Ỉ' => 'Ỉ', + 'ỉ' => 'ỉ', + 'Ị' => 'Ị', + 'ị' => 'ị', + 'Ọ' => 'Ọ', + 'ọ' => 'ọ', + 'Ỏ' => 'Ỏ', + 'ỏ' => 'ỏ', + 'Ố' => 'Ố', + 'ố' => 'ố', + 'Ồ' => 'Ồ', + 'ồ' => 'ồ', + 'Ổ' => 'Ổ', + 'ổ' => 'ổ', + 'Ỗ' => 'Ỗ', + 'ỗ' => 'ỗ', + 'Ộ' => 'Ộ', + 'ộ' => 'ộ', + 'Ớ' => 'Ớ', + 'ớ' => 'ớ', + 'Ờ' => 'Ờ', + 'ờ' => 'ờ', + 'Ở' => 'Ở', + 'ở' => 'ở', + 'Ỡ' => 'Ỡ', + 'ỡ' => 'ỡ', + 'Ợ' => 'Ợ', + 'ợ' => 'ợ', + 'Ụ' => 'Ụ', + 'ụ' => 'ụ', + 'Ủ' => 'Ủ', + 'ủ' => 'ủ', + 'Ứ' => 'Ứ', + 'ứ' => 'ứ', + 'Ừ' => 'Ừ', + 'ừ' => 'ừ', + 'Ử' => 'Ử', + 'ử' => 'ử', + 'Ữ' => 'Ữ', + 'ữ' => 'ữ', + 'Ự' => 'Ự', + 'ự' => 'ự', + 'Ỳ' => 'Ỳ', + 'ỳ' => 'ỳ', + 'Ỵ' => 'Ỵ', + 'ỵ' => 'ỵ', + 'Ỷ' => 'Ỷ', + 'ỷ' => 'ỷ', + 'Ỹ' => 'Ỹ', + 'ỹ' => 'ỹ', + 'ἀ' => 'ἀ', + 'ἁ' => 'ἁ', + 'ἂ' => 'ἂ', + 'ἃ' => 'ἃ', + 'ἄ' => 'ἄ', + 'ἅ' => 'ἅ', + 'ἆ' => 'ἆ', + 'ἇ' => 'ἇ', + 'Ἀ' => 'Ἀ', + 'Ἁ' => 'Ἁ', + 'Ἂ' => 'Ἂ', + 'Ἃ' => 'Ἃ', + 'Ἄ' => 'Ἄ', + 'Ἅ' => 'Ἅ', + 'Ἆ' => 'Ἆ', + 'Ἇ' => 'Ἇ', + 'ἐ' => 'ἐ', + 'ἑ' => 'ἑ', + 'ἒ' => 'ἒ', + 'ἓ' => 'ἓ', + 'ἔ' => 'ἔ', + 'ἕ' => 'ἕ', + 'Ἐ' => 'Ἐ', + 'Ἑ' => 'Ἑ', + 'Ἒ' => 'Ἒ', + 'Ἓ' => 'Ἓ', + 'Ἔ' => 'Ἔ', + 'Ἕ' => 'Ἕ', + 'ἠ' => 'ἠ', + 'ἡ' => 'ἡ', + 'ἢ' => 'ἢ', + 'ἣ' => 'ἣ', + 'ἤ' => 'ἤ', + 'ἥ' => 'ἥ', + 'ἦ' => 'ἦ', + 'ἧ' => 'ἧ', + 'Ἠ' => 'Ἠ', + 'Ἡ' => 'Ἡ', + 'Ἢ' => 'Ἢ', + 'Ἣ' => 'Ἣ', + 'Ἤ' => 'Ἤ', + 'Ἥ' => 'Ἥ', + 'Ἦ' => 'Ἦ', + 'Ἧ' => 'Ἧ', + 'ἰ' => 'ἰ', + 'ἱ' => 'ἱ', + 'ἲ' => 'ἲ', + 'ἳ' => 'ἳ', + 'ἴ' => 'ἴ', + 'ἵ' => 'ἵ', + 'ἶ' => 'ἶ', + 'ἷ' => 'ἷ', + 'Ἰ' => 'Ἰ', + 'Ἱ' => 'Ἱ', + 'Ἲ' => 'Ἲ', + 'Ἳ' => 'Ἳ', + 'Ἴ' => 'Ἴ', + 'Ἵ' => 'Ἵ', + 'Ἶ' => 'Ἶ', + 'Ἷ' => 'Ἷ', + 'ὀ' => 'ὀ', + 'ὁ' => 'ὁ', + 'ὂ' => 'ὂ', + 'ὃ' => 'ὃ', + 'ὄ' => 'ὄ', + 'ὅ' => 'ὅ', + 'Ὀ' => 'Ὀ', + 'Ὁ' => 'Ὁ', + 'Ὂ' => 'Ὂ', + 'Ὃ' => 'Ὃ', + 'Ὄ' => 'Ὄ', + 'Ὅ' => 'Ὅ', + 'ὐ' => 'ὐ', + 'ὑ' => 'ὑ', + 'ὒ' => 'ὒ', + 'ὓ' => 'ὓ', + 'ὔ' => 'ὔ', + 'ὕ' => 'ὕ', + 'ὖ' => 'ὖ', + 'ὗ' => 'ὗ', + 'Ὑ' => 'Ὑ', + 'Ὓ' => 'Ὓ', + 'Ὕ' => 'Ὕ', + 'Ὗ' => 'Ὗ', + 'ὠ' => 'ὠ', + 'ὡ' => 'ὡ', + 'ὢ' => 'ὢ', + 'ὣ' => 'ὣ', + 'ὤ' => 'ὤ', + 'ὥ' => 'ὥ', + 'ὦ' => 'ὦ', + 'ὧ' => 'ὧ', + 'Ὠ' => 'Ὠ', + 'Ὡ' => 'Ὡ', + 'Ὢ' => 'Ὢ', + 'Ὣ' => 'Ὣ', + 'Ὤ' => 'Ὤ', + 'Ὥ' => 'Ὥ', + 'Ὦ' => 'Ὦ', + 'Ὧ' => 'Ὧ', + 'ὰ' => 'ὰ', + 'ὲ' => 'ὲ', + 'ὴ' => 'ὴ', + 'ὶ' => 'ὶ', + 'ὸ' => 'ὸ', + 'ὺ' => 'ὺ', + 'ὼ' => 'ὼ', + 'ᾀ' => 'ᾀ', + 'ᾁ' => 'ᾁ', + 'ᾂ' => 'ᾂ', + 'ᾃ' => 'ᾃ', + 'ᾄ' => 'ᾄ', + 'ᾅ' => 'ᾅ', + 'ᾆ' => 'ᾆ', + 'ᾇ' => 'ᾇ', + 'ᾈ' => 'ᾈ', + 'ᾉ' => 'ᾉ', + 'ᾊ' => 'ᾊ', + 'ᾋ' => 'ᾋ', + 'ᾌ' => 'ᾌ', + 'ᾍ' => 'ᾍ', + 'ᾎ' => 'ᾎ', + 'ᾏ' => 'ᾏ', + 'ᾐ' => 'ᾐ', + 'ᾑ' => 'ᾑ', + 'ᾒ' => 'ᾒ', + 'ᾓ' => 'ᾓ', + 'ᾔ' => 'ᾔ', + 'ᾕ' => 'ᾕ', + 'ᾖ' => 'ᾖ', + 'ᾗ' => 'ᾗ', + 'ᾘ' => 'ᾘ', + 'ᾙ' => 'ᾙ', + 'ᾚ' => 'ᾚ', + 'ᾛ' => 'ᾛ', + 'ᾜ' => 'ᾜ', + 'ᾝ' => 'ᾝ', + 'ᾞ' => 'ᾞ', + 'ᾟ' => 'ᾟ', + 'ᾠ' => 'ᾠ', + 'ᾡ' => 'ᾡ', + 'ᾢ' => 'ᾢ', + 'ᾣ' => 'ᾣ', + 'ᾤ' => 'ᾤ', + 'ᾥ' => 'ᾥ', + 'ᾦ' => 'ᾦ', + 'ᾧ' => 'ᾧ', + 'ᾨ' => 'ᾨ', + 'ᾩ' => 'ᾩ', + 'ᾪ' => 'ᾪ', + 'ᾫ' => 'ᾫ', + 'ᾬ' => 'ᾬ', + 'ᾭ' => 'ᾭ', + 'ᾮ' => 'ᾮ', + 'ᾯ' => 'ᾯ', + 'ᾰ' => 'ᾰ', + 'ᾱ' => 'ᾱ', + 'ᾲ' => 'ᾲ', + 'ᾳ' => 'ᾳ', + 'ᾴ' => 'ᾴ', + 'ᾶ' => 'ᾶ', + 'ᾷ' => 'ᾷ', + 'Ᾰ' => 'Ᾰ', + 'Ᾱ' => 'Ᾱ', + 'Ὰ' => 'Ὰ', + 'ᾼ' => 'ᾼ', + '῁' => '῁', + 'ῂ' => 'ῂ', + 'ῃ' => 'ῃ', + 'ῄ' => 'ῄ', + 'ῆ' => 'ῆ', + 'ῇ' => 'ῇ', + 'Ὲ' => 'Ὲ', + 'Ὴ' => 'Ὴ', + 'ῌ' => 'ῌ', + '῍' => '῍', + '῎' => '῎', + '῏' => '῏', + 'ῐ' => 'ῐ', + 'ῑ' => 'ῑ', + 'ῒ' => 'ῒ', + 'ῖ' => 'ῖ', + 'ῗ' => 'ῗ', + 'Ῐ' => 'Ῐ', + 'Ῑ' => 'Ῑ', + 'Ὶ' => 'Ὶ', + '῝' => '῝', + '῞' => '῞', + '῟' => '῟', + 'ῠ' => 'ῠ', + 'ῡ' => 'ῡ', + 'ῢ' => 'ῢ', + 'ῤ' => 'ῤ', + 'ῥ' => 'ῥ', + 'ῦ' => 'ῦ', + 'ῧ' => 'ῧ', + 'Ῠ' => 'Ῠ', + 'Ῡ' => 'Ῡ', + 'Ὺ' => 'Ὺ', + 'Ῥ' => 'Ῥ', + '῭' => '῭', + 'ῲ' => 'ῲ', + 'ῳ' => 'ῳ', + 'ῴ' => 'ῴ', + 'ῶ' => 'ῶ', + 'ῷ' => 'ῷ', + 'Ὸ' => 'Ὸ', + 'Ὼ' => 'Ὼ', + 'ῼ' => 'ῼ', + '↚' => '↚', + '↛' => '↛', + '↮' => '↮', + '⇍' => '⇍', + '⇎' => '⇎', + '⇏' => '⇏', + '∄' => '∄', + '∉' => '∉', + '∌' => '∌', + '∤' => '∤', + '∦' => '∦', + '≁' => '≁', + '≄' => '≄', + '≇' => '≇', + '≉' => '≉', + '≠' => '≠', + '≢' => '≢', + '≭' => '≭', + '≮' => '≮', + '≯' => '≯', + '≰' => '≰', + '≱' => '≱', + '≴' => '≴', + '≵' => '≵', + '≸' => '≸', + '≹' => '≹', + '⊀' => '⊀', + '⊁' => '⊁', + '⊄' => '⊄', + '⊅' => '⊅', + '⊈' => '⊈', + '⊉' => '⊉', + '⊬' => '⊬', + '⊭' => '⊭', + '⊮' => '⊮', + '⊯' => '⊯', + '⋠' => '⋠', + '⋡' => '⋡', + '⋢' => '⋢', + '⋣' => '⋣', + '⋪' => '⋪', + '⋫' => '⋫', + '⋬' => '⋬', + '⋭' => '⋭', + 'が' => 'が', + 'ぎ' => 'ぎ', + 'ぐ' => 'ぐ', + 'げ' => 'げ', + 'ご' => 'ご', + 'ざ' => 'ざ', + 'じ' => 'じ', + 'ず' => 'ず', + 'ぜ' => 'ぜ', + 'ぞ' => 'ぞ', + 'だ' => 'だ', + 'ぢ' => 'ぢ', + 'づ' => 'づ', + 'で' => 'で', + 'ど' => 'ど', + 'ば' => 'ば', + 'ぱ' => 'ぱ', + 'び' => 'び', + 'ぴ' => 'ぴ', + 'ぶ' => 'ぶ', + 'ぷ' => 'ぷ', + 'べ' => 'べ', + 'ぺ' => 'ぺ', + 'ぼ' => 'ぼ', + 'ぽ' => 'ぽ', + 'ゔ' => 'ゔ', + 'ゞ' => 'ゞ', + 'ガ' => 'ガ', + 'ギ' => 'ギ', + 'グ' => 'グ', + 'ゲ' => 'ゲ', + 'ゴ' => 'ゴ', + 'ザ' => 'ザ', + 'ジ' => 'ジ', + 'ズ' => 'ズ', + 'ゼ' => 'ゼ', + 'ゾ' => 'ゾ', + 'ダ' => 'ダ', + 'ヂ' => 'ヂ', + 'ヅ' => 'ヅ', + 'デ' => 'デ', + 'ド' => 'ド', + 'バ' => 'バ', + 'パ' => 'パ', + 'ビ' => 'ビ', + 'ピ' => 'ピ', + 'ブ' => 'ブ', + 'プ' => 'プ', + 'ベ' => 'ベ', + 'ペ' => 'ペ', + 'ボ' => 'ボ', + 'ポ' => 'ポ', + 'ヴ' => 'ヴ', + 'ヷ' => 'ヷ', + 'ヸ' => 'ヸ', + 'ヹ' => 'ヹ', + 'ヺ' => 'ヺ', + 'ヾ' => 'ヾ', + '𑂚' => '𑂚', + '𑂜' => '𑂜', + '𑂫' => '𑂫', + '𑄮' => '𑄮', + '𑄯' => '𑄯', + '𑍋' => '𑍋', + '𑍌' => '𑍌', + '𑒻' => '𑒻', + '𑒼' => '𑒼', + '𑒾' => '𑒾', + '𑖺' => '𑖺', + '𑖻' => '𑖻', + '𑤸' => '𑤸', +); diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php new file mode 100644 index 0000000..5a3e8e0 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php @@ -0,0 +1,2065 @@ + 'À', + 'Á' => 'Á', + 'Â' => 'Â', + 'Ã' => 'Ã', + 'Ä' => 'Ä', + 'Å' => 'Å', + 'Ç' => 'Ç', + 'È' => 'È', + 'É' => 'É', + 'Ê' => 'Ê', + 'Ë' => 'Ë', + 'Ì' => 'Ì', + 'Í' => 'Í', + 'Î' => 'Î', + 'Ï' => 'Ï', + 'Ñ' => 'Ñ', + 'Ò' => 'Ò', + 'Ó' => 'Ó', + 'Ô' => 'Ô', + 'Õ' => 'Õ', + 'Ö' => 'Ö', + 'Ù' => 'Ù', + 'Ú' => 'Ú', + 'Û' => 'Û', + 'Ü' => 'Ü', + 'Ý' => 'Ý', + 'à' => 'à', + 'á' => 'á', + 'â' => 'â', + 'ã' => 'ã', + 'ä' => 'ä', + 'å' => 'å', + 'ç' => 'ç', + 'è' => 'è', + 'é' => 'é', + 'ê' => 'ê', + 'ë' => 'ë', + 'ì' => 'ì', + 'í' => 'í', + 'î' => 'î', + 'ï' => 'ï', + 'ñ' => 'ñ', + 'ò' => 'ò', + 'ó' => 'ó', + 'ô' => 'ô', + 'õ' => 'õ', + 'ö' => 'ö', + 'ù' => 'ù', + 'ú' => 'ú', + 'û' => 'û', + 'ü' => 'ü', + 'ý' => 'ý', + 'ÿ' => 'ÿ', + 'Ā' => 'Ā', + 'ā' => 'ā', + 'Ă' => 'Ă', + 'ă' => 'ă', + 'Ą' => 'Ą', + 'ą' => 'ą', + 'Ć' => 'Ć', + 'ć' => 'ć', + 'Ĉ' => 'Ĉ', + 'ĉ' => 'ĉ', + 'Ċ' => 'Ċ', + 'ċ' => 'ċ', + 'Č' => 'Č', + 'č' => 'č', + 'Ď' => 'Ď', + 'ď' => 'ď', + 'Ē' => 'Ē', + 'ē' => 'ē', + 'Ĕ' => 'Ĕ', + 'ĕ' => 'ĕ', + 'Ė' => 'Ė', + 'ė' => 'ė', + 'Ę' => 'Ę', + 'ę' => 'ę', + 'Ě' => 'Ě', + 'ě' => 'ě', + 'Ĝ' => 'Ĝ', + 'ĝ' => 'ĝ', + 'Ğ' => 'Ğ', + 'ğ' => 'ğ', + 'Ġ' => 'Ġ', + 'ġ' => 'ġ', + 'Ģ' => 'Ģ', + 'ģ' => 'ģ', + 'Ĥ' => 'Ĥ', + 'ĥ' => 'ĥ', + 'Ĩ' => 'Ĩ', + 'ĩ' => 'ĩ', + 'Ī' => 'Ī', + 'ī' => 'ī', + 'Ĭ' => 'Ĭ', + 'ĭ' => 'ĭ', + 'Į' => 'Į', + 'į' => 'į', + 'İ' => 'İ', + 'Ĵ' => 'Ĵ', + 'ĵ' => 'ĵ', + 'Ķ' => 'Ķ', + 'ķ' => 'ķ', + 'Ĺ' => 'Ĺ', + 'ĺ' => 'ĺ', + 'Ļ' => 'Ļ', + 'ļ' => 'ļ', + 'Ľ' => 'Ľ', + 'ľ' => 'ľ', + 'Ń' => 'Ń', + 'ń' => 'ń', + 'Ņ' => 'Ņ', + 'ņ' => 'ņ', + 'Ň' => 'Ň', + 'ň' => 'ň', + 'Ō' => 'Ō', + 'ō' => 'ō', + 'Ŏ' => 'Ŏ', + 'ŏ' => 'ŏ', + 'Ő' => 'Ő', + 'ő' => 'ő', + 'Ŕ' => 'Ŕ', + 'ŕ' => 'ŕ', + 'Ŗ' => 'Ŗ', + 'ŗ' => 'ŗ', + 'Ř' => 'Ř', + 'ř' => 'ř', + 'Ś' => 'Ś', + 'ś' => 'ś', + 'Ŝ' => 'Ŝ', + 'ŝ' => 'ŝ', + 'Ş' => 'Ş', + 'ş' => 'ş', + 'Š' => 'Š', + 'š' => 'š', + 'Ţ' => 'Ţ', + 'ţ' => 'ţ', + 'Ť' => 'Ť', + 'ť' => 'ť', + 'Ũ' => 'Ũ', + 'ũ' => 'ũ', + 'Ū' => 'Ū', + 'ū' => 'ū', + 'Ŭ' => 'Ŭ', + 'ŭ' => 'ŭ', + 'Ů' => 'Ů', + 'ů' => 'ů', + 'Ű' => 'Ű', + 'ű' => 'ű', + 'Ų' => 'Ų', + 'ų' => 'ų', + 'Ŵ' => 'Ŵ', + 'ŵ' => 'ŵ', + 'Ŷ' => 'Ŷ', + 'ŷ' => 'ŷ', + 'Ÿ' => 'Ÿ', + 'Ź' => 'Ź', + 'ź' => 'ź', + 'Ż' => 'Ż', + 'ż' => 'ż', + 'Ž' => 'Ž', + 'ž' => 'ž', + 'Ơ' => 'Ơ', + 'ơ' => 'ơ', + 'Ư' => 'Ư', + 'ư' => 'ư', + 'Ǎ' => 'Ǎ', + 'ǎ' => 'ǎ', + 'Ǐ' => 'Ǐ', + 'ǐ' => 'ǐ', + 'Ǒ' => 'Ǒ', + 'ǒ' => 'ǒ', + 'Ǔ' => 'Ǔ', + 'ǔ' => 'ǔ', + 'Ǖ' => 'Ǖ', + 'ǖ' => 'ǖ', + 'Ǘ' => 'Ǘ', + 'ǘ' => 'ǘ', + 'Ǚ' => 'Ǚ', + 'ǚ' => 'ǚ', + 'Ǜ' => 'Ǜ', + 'ǜ' => 'ǜ', + 'Ǟ' => 'Ǟ', + 'ǟ' => 'ǟ', + 'Ǡ' => 'Ǡ', + 'ǡ' => 'ǡ', + 'Ǣ' => 'Ǣ', + 'ǣ' => 'ǣ', + 'Ǧ' => 'Ǧ', + 'ǧ' => 'ǧ', + 'Ǩ' => 'Ǩ', + 'ǩ' => 'ǩ', + 'Ǫ' => 'Ǫ', + 'ǫ' => 'ǫ', + 'Ǭ' => 'Ǭ', + 'ǭ' => 'ǭ', + 'Ǯ' => 'Ǯ', + 'ǯ' => 'ǯ', + 'ǰ' => 'ǰ', + 'Ǵ' => 'Ǵ', + 'ǵ' => 'ǵ', + 'Ǹ' => 'Ǹ', + 'ǹ' => 'ǹ', + 'Ǻ' => 'Ǻ', + 'ǻ' => 'ǻ', + 'Ǽ' => 'Ǽ', + 'ǽ' => 'ǽ', + 'Ǿ' => 'Ǿ', + 'ǿ' => 'ǿ', + 'Ȁ' => 'Ȁ', + 'ȁ' => 'ȁ', + 'Ȃ' => 'Ȃ', + 'ȃ' => 'ȃ', + 'Ȅ' => 'Ȅ', + 'ȅ' => 'ȅ', + 'Ȇ' => 'Ȇ', + 'ȇ' => 'ȇ', + 'Ȉ' => 'Ȉ', + 'ȉ' => 'ȉ', + 'Ȋ' => 'Ȋ', + 'ȋ' => 'ȋ', + 'Ȍ' => 'Ȍ', + 'ȍ' => 'ȍ', + 'Ȏ' => 'Ȏ', + 'ȏ' => 'ȏ', + 'Ȑ' => 'Ȑ', + 'ȑ' => 'ȑ', + 'Ȓ' => 'Ȓ', + 'ȓ' => 'ȓ', + 'Ȕ' => 'Ȕ', + 'ȕ' => 'ȕ', + 'Ȗ' => 'Ȗ', + 'ȗ' => 'ȗ', + 'Ș' => 'Ș', + 'ș' => 'ș', + 'Ț' => 'Ț', + 'ț' => 'ț', + 'Ȟ' => 'Ȟ', + 'ȟ' => 'ȟ', + 'Ȧ' => 'Ȧ', + 'ȧ' => 'ȧ', + 'Ȩ' => 'Ȩ', + 'ȩ' => 'ȩ', + 'Ȫ' => 'Ȫ', + 'ȫ' => 'ȫ', + 'Ȭ' => 'Ȭ', + 'ȭ' => 'ȭ', + 'Ȯ' => 'Ȯ', + 'ȯ' => 'ȯ', + 'Ȱ' => 'Ȱ', + 'ȱ' => 'ȱ', + 'Ȳ' => 'Ȳ', + 'ȳ' => 'ȳ', + '̀' => '̀', + '́' => '́', + '̓' => '̓', + '̈́' => '̈́', + 'ʹ' => 'ʹ', + ';' => ';', + '΅' => '΅', + 'Ά' => 'Ά', + '·' => '·', + 'Έ' => 'Έ', + 'Ή' => 'Ή', + 'Ί' => 'Ί', + 'Ό' => 'Ό', + 'Ύ' => 'Ύ', + 'Ώ' => 'Ώ', + 'ΐ' => 'ΐ', + 'Ϊ' => 'Ϊ', + 'Ϋ' => 'Ϋ', + 'ά' => 'ά', + 'έ' => 'έ', + 'ή' => 'ή', + 'ί' => 'ί', + 'ΰ' => 'ΰ', + 'ϊ' => 'ϊ', + 'ϋ' => 'ϋ', + 'ό' => 'ό', + 'ύ' => 'ύ', + 'ώ' => 'ώ', + 'ϓ' => 'ϓ', + 'ϔ' => 'ϔ', + 'Ѐ' => 'Ѐ', + 'Ё' => 'Ё', + 'Ѓ' => 'Ѓ', + 'Ї' => 'Ї', + 'Ќ' => 'Ќ', + 'Ѝ' => 'Ѝ', + 'Ў' => 'Ў', + 'Й' => 'Й', + 'й' => 'й', + 'ѐ' => 'ѐ', + 'ё' => 'ё', + 'ѓ' => 'ѓ', + 'ї' => 'ї', + 'ќ' => 'ќ', + 'ѝ' => 'ѝ', + 'ў' => 'ў', + 'Ѷ' => 'Ѷ', + 'ѷ' => 'ѷ', + 'Ӂ' => 'Ӂ', + 'ӂ' => 'ӂ', + 'Ӑ' => 'Ӑ', + 'ӑ' => 'ӑ', + 'Ӓ' => 'Ӓ', + 'ӓ' => 'ӓ', + 'Ӗ' => 'Ӗ', + 'ӗ' => 'ӗ', + 'Ӛ' => 'Ӛ', + 'ӛ' => 'ӛ', + 'Ӝ' => 'Ӝ', + 'ӝ' => 'ӝ', + 'Ӟ' => 'Ӟ', + 'ӟ' => 'ӟ', + 'Ӣ' => 'Ӣ', + 'ӣ' => 'ӣ', + 'Ӥ' => 'Ӥ', + 'ӥ' => 'ӥ', + 'Ӧ' => 'Ӧ', + 'ӧ' => 'ӧ', + 'Ӫ' => 'Ӫ', + 'ӫ' => 'ӫ', + 'Ӭ' => 'Ӭ', + 'ӭ' => 'ӭ', + 'Ӯ' => 'Ӯ', + 'ӯ' => 'ӯ', + 'Ӱ' => 'Ӱ', + 'ӱ' => 'ӱ', + 'Ӳ' => 'Ӳ', + 'ӳ' => 'ӳ', + 'Ӵ' => 'Ӵ', + 'ӵ' => 'ӵ', + 'Ӹ' => 'Ӹ', + 'ӹ' => 'ӹ', + 'آ' => 'آ', + 'أ' => 'أ', + 'ؤ' => 'ؤ', + 'إ' => 'إ', + 'ئ' => 'ئ', + 'ۀ' => 'ۀ', + 'ۂ' => 'ۂ', + 'ۓ' => 'ۓ', + 'ऩ' => 'ऩ', + 'ऱ' => 'ऱ', + 'ऴ' => 'ऴ', + 'क़' => 'क़', + 'ख़' => 'ख़', + 'ग़' => 'ग़', + 'ज़' => 'ज़', + 'ड़' => 'ड़', + 'ढ़' => 'ढ़', + 'फ़' => 'फ़', + 'य़' => 'य़', + 'ো' => 'ো', + 'ৌ' => 'ৌ', + 'ড়' => 'ড়', + 'ঢ়' => 'ঢ়', + 'য়' => 'য়', + 'ਲ਼' => 'ਲ਼', + 'ਸ਼' => 'ਸ਼', + 'ਖ਼' => 'ਖ਼', + 'ਗ਼' => 'ਗ਼', + 'ਜ਼' => 'ਜ਼', + 'ਫ਼' => 'ਫ਼', + 'ୈ' => 'ୈ', + 'ୋ' => 'ୋ', + 'ୌ' => 'ୌ', + 'ଡ଼' => 'ଡ଼', + 'ଢ଼' => 'ଢ଼', + 'ஔ' => 'ஔ', + 'ொ' => 'ொ', + 'ோ' => 'ோ', + 'ௌ' => 'ௌ', + 'ై' => 'ై', + 'ೀ' => 'ೀ', + 'ೇ' => 'ೇ', + 'ೈ' => 'ೈ', + 'ೊ' => 'ೊ', + 'ೋ' => 'ೋ', + 'ൊ' => 'ൊ', + 'ോ' => 'ോ', + 'ൌ' => 'ൌ', + 'ේ' => 'ේ', + 'ො' => 'ො', + 'ෝ' => 'ෝ', + 'ෞ' => 'ෞ', + 'གྷ' => 'གྷ', + 'ཌྷ' => 'ཌྷ', + 'དྷ' => 'དྷ', + 'བྷ' => 'བྷ', + 'ཛྷ' => 'ཛྷ', + 'ཀྵ' => 'ཀྵ', + 'ཱི' => 'ཱི', + 'ཱུ' => 'ཱུ', + 'ྲྀ' => 'ྲྀ', + 'ླྀ' => 'ླྀ', + 'ཱྀ' => 'ཱྀ', + 'ྒྷ' => 'ྒྷ', + 'ྜྷ' => 'ྜྷ', + 'ྡྷ' => 'ྡྷ', + 'ྦྷ' => 'ྦྷ', + 'ྫྷ' => 'ྫྷ', + 'ྐྵ' => 'ྐྵ', + 'ဦ' => 'ဦ', + 'ᬆ' => 'ᬆ', + 'ᬈ' => 'ᬈ', + 'ᬊ' => 'ᬊ', + 'ᬌ' => 'ᬌ', + 'ᬎ' => 'ᬎ', + 'ᬒ' => 'ᬒ', + 'ᬻ' => 'ᬻ', + 'ᬽ' => 'ᬽ', + 'ᭀ' => 'ᭀ', + 'ᭁ' => 'ᭁ', + 'ᭃ' => 'ᭃ', + 'Ḁ' => 'Ḁ', + 'ḁ' => 'ḁ', + 'Ḃ' => 'Ḃ', + 'ḃ' => 'ḃ', + 'Ḅ' => 'Ḅ', + 'ḅ' => 'ḅ', + 'Ḇ' => 'Ḇ', + 'ḇ' => 'ḇ', + 'Ḉ' => 'Ḉ', + 'ḉ' => 'ḉ', + 'Ḋ' => 'Ḋ', + 'ḋ' => 'ḋ', + 'Ḍ' => 'Ḍ', + 'ḍ' => 'ḍ', + 'Ḏ' => 'Ḏ', + 'ḏ' => 'ḏ', + 'Ḑ' => 'Ḑ', + 'ḑ' => 'ḑ', + 'Ḓ' => 'Ḓ', + 'ḓ' => 'ḓ', + 'Ḕ' => 'Ḕ', + 'ḕ' => 'ḕ', + 'Ḗ' => 'Ḗ', + 'ḗ' => 'ḗ', + 'Ḙ' => 'Ḙ', + 'ḙ' => 'ḙ', + 'Ḛ' => 'Ḛ', + 'ḛ' => 'ḛ', + 'Ḝ' => 'Ḝ', + 'ḝ' => 'ḝ', + 'Ḟ' => 'Ḟ', + 'ḟ' => 'ḟ', + 'Ḡ' => 'Ḡ', + 'ḡ' => 'ḡ', + 'Ḣ' => 'Ḣ', + 'ḣ' => 'ḣ', + 'Ḥ' => 'Ḥ', + 'ḥ' => 'ḥ', + 'Ḧ' => 'Ḧ', + 'ḧ' => 'ḧ', + 'Ḩ' => 'Ḩ', + 'ḩ' => 'ḩ', + 'Ḫ' => 'Ḫ', + 'ḫ' => 'ḫ', + 'Ḭ' => 'Ḭ', + 'ḭ' => 'ḭ', + 'Ḯ' => 'Ḯ', + 'ḯ' => 'ḯ', + 'Ḱ' => 'Ḱ', + 'ḱ' => 'ḱ', + 'Ḳ' => 'Ḳ', + 'ḳ' => 'ḳ', + 'Ḵ' => 'Ḵ', + 'ḵ' => 'ḵ', + 'Ḷ' => 'Ḷ', + 'ḷ' => 'ḷ', + 'Ḹ' => 'Ḹ', + 'ḹ' => 'ḹ', + 'Ḻ' => 'Ḻ', + 'ḻ' => 'ḻ', + 'Ḽ' => 'Ḽ', + 'ḽ' => 'ḽ', + 'Ḿ' => 'Ḿ', + 'ḿ' => 'ḿ', + 'Ṁ' => 'Ṁ', + 'ṁ' => 'ṁ', + 'Ṃ' => 'Ṃ', + 'ṃ' => 'ṃ', + 'Ṅ' => 'Ṅ', + 'ṅ' => 'ṅ', + 'Ṇ' => 'Ṇ', + 'ṇ' => 'ṇ', + 'Ṉ' => 'Ṉ', + 'ṉ' => 'ṉ', + 'Ṋ' => 'Ṋ', + 'ṋ' => 'ṋ', + 'Ṍ' => 'Ṍ', + 'ṍ' => 'ṍ', + 'Ṏ' => 'Ṏ', + 'ṏ' => 'ṏ', + 'Ṑ' => 'Ṑ', + 'ṑ' => 'ṑ', + 'Ṓ' => 'Ṓ', + 'ṓ' => 'ṓ', + 'Ṕ' => 'Ṕ', + 'ṕ' => 'ṕ', + 'Ṗ' => 'Ṗ', + 'ṗ' => 'ṗ', + 'Ṙ' => 'Ṙ', + 'ṙ' => 'ṙ', + 'Ṛ' => 'Ṛ', + 'ṛ' => 'ṛ', + 'Ṝ' => 'Ṝ', + 'ṝ' => 'ṝ', + 'Ṟ' => 'Ṟ', + 'ṟ' => 'ṟ', + 'Ṡ' => 'Ṡ', + 'ṡ' => 'ṡ', + 'Ṣ' => 'Ṣ', + 'ṣ' => 'ṣ', + 'Ṥ' => 'Ṥ', + 'ṥ' => 'ṥ', + 'Ṧ' => 'Ṧ', + 'ṧ' => 'ṧ', + 'Ṩ' => 'Ṩ', + 'ṩ' => 'ṩ', + 'Ṫ' => 'Ṫ', + 'ṫ' => 'ṫ', + 'Ṭ' => 'Ṭ', + 'ṭ' => 'ṭ', + 'Ṯ' => 'Ṯ', + 'ṯ' => 'ṯ', + 'Ṱ' => 'Ṱ', + 'ṱ' => 'ṱ', + 'Ṳ' => 'Ṳ', + 'ṳ' => 'ṳ', + 'Ṵ' => 'Ṵ', + 'ṵ' => 'ṵ', + 'Ṷ' => 'Ṷ', + 'ṷ' => 'ṷ', + 'Ṹ' => 'Ṹ', + 'ṹ' => 'ṹ', + 'Ṻ' => 'Ṻ', + 'ṻ' => 'ṻ', + 'Ṽ' => 'Ṽ', + 'ṽ' => 'ṽ', + 'Ṿ' => 'Ṿ', + 'ṿ' => 'ṿ', + 'Ẁ' => 'Ẁ', + 'ẁ' => 'ẁ', + 'Ẃ' => 'Ẃ', + 'ẃ' => 'ẃ', + 'Ẅ' => 'Ẅ', + 'ẅ' => 'ẅ', + 'Ẇ' => 'Ẇ', + 'ẇ' => 'ẇ', + 'Ẉ' => 'Ẉ', + 'ẉ' => 'ẉ', + 'Ẋ' => 'Ẋ', + 'ẋ' => 'ẋ', + 'Ẍ' => 'Ẍ', + 'ẍ' => 'ẍ', + 'Ẏ' => 'Ẏ', + 'ẏ' => 'ẏ', + 'Ẑ' => 'Ẑ', + 'ẑ' => 'ẑ', + 'Ẓ' => 'Ẓ', + 'ẓ' => 'ẓ', + 'Ẕ' => 'Ẕ', + 'ẕ' => 'ẕ', + 'ẖ' => 'ẖ', + 'ẗ' => 'ẗ', + 'ẘ' => 'ẘ', + 'ẙ' => 'ẙ', + 'ẛ' => 'ẛ', + 'Ạ' => 'Ạ', + 'ạ' => 'ạ', + 'Ả' => 'Ả', + 'ả' => 'ả', + 'Ấ' => 'Ấ', + 'ấ' => 'ấ', + 'Ầ' => 'Ầ', + 'ầ' => 'ầ', + 'Ẩ' => 'Ẩ', + 'ẩ' => 'ẩ', + 'Ẫ' => 'Ẫ', + 'ẫ' => 'ẫ', + 'Ậ' => 'Ậ', + 'ậ' => 'ậ', + 'Ắ' => 'Ắ', + 'ắ' => 'ắ', + 'Ằ' => 'Ằ', + 'ằ' => 'ằ', + 'Ẳ' => 'Ẳ', + 'ẳ' => 'ẳ', + 'Ẵ' => 'Ẵ', + 'ẵ' => 'ẵ', + 'Ặ' => 'Ặ', + 'ặ' => 'ặ', + 'Ẹ' => 'Ẹ', + 'ẹ' => 'ẹ', + 'Ẻ' => 'Ẻ', + 'ẻ' => 'ẻ', + 'Ẽ' => 'Ẽ', + 'ẽ' => 'ẽ', + 'Ế' => 'Ế', + 'ế' => 'ế', + 'Ề' => 'Ề', + 'ề' => 'ề', + 'Ể' => 'Ể', + 'ể' => 'ể', + 'Ễ' => 'Ễ', + 'ễ' => 'ễ', + 'Ệ' => 'Ệ', + 'ệ' => 'ệ', + 'Ỉ' => 'Ỉ', + 'ỉ' => 'ỉ', + 'Ị' => 'Ị', + 'ị' => 'ị', + 'Ọ' => 'Ọ', + 'ọ' => 'ọ', + 'Ỏ' => 'Ỏ', + 'ỏ' => 'ỏ', + 'Ố' => 'Ố', + 'ố' => 'ố', + 'Ồ' => 'Ồ', + 'ồ' => 'ồ', + 'Ổ' => 'Ổ', + 'ổ' => 'ổ', + 'Ỗ' => 'Ỗ', + 'ỗ' => 'ỗ', + 'Ộ' => 'Ộ', + 'ộ' => 'ộ', + 'Ớ' => 'Ớ', + 'ớ' => 'ớ', + 'Ờ' => 'Ờ', + 'ờ' => 'ờ', + 'Ở' => 'Ở', + 'ở' => 'ở', + 'Ỡ' => 'Ỡ', + 'ỡ' => 'ỡ', + 'Ợ' => 'Ợ', + 'ợ' => 'ợ', + 'Ụ' => 'Ụ', + 'ụ' => 'ụ', + 'Ủ' => 'Ủ', + 'ủ' => 'ủ', + 'Ứ' => 'Ứ', + 'ứ' => 'ứ', + 'Ừ' => 'Ừ', + 'ừ' => 'ừ', + 'Ử' => 'Ử', + 'ử' => 'ử', + 'Ữ' => 'Ữ', + 'ữ' => 'ữ', + 'Ự' => 'Ự', + 'ự' => 'ự', + 'Ỳ' => 'Ỳ', + 'ỳ' => 'ỳ', + 'Ỵ' => 'Ỵ', + 'ỵ' => 'ỵ', + 'Ỷ' => 'Ỷ', + 'ỷ' => 'ỷ', + 'Ỹ' => 'Ỹ', + 'ỹ' => 'ỹ', + 'ἀ' => 'ἀ', + 'ἁ' => 'ἁ', + 'ἂ' => 'ἂ', + 'ἃ' => 'ἃ', + 'ἄ' => 'ἄ', + 'ἅ' => 'ἅ', + 'ἆ' => 'ἆ', + 'ἇ' => 'ἇ', + 'Ἀ' => 'Ἀ', + 'Ἁ' => 'Ἁ', + 'Ἂ' => 'Ἂ', + 'Ἃ' => 'Ἃ', + 'Ἄ' => 'Ἄ', + 'Ἅ' => 'Ἅ', + 'Ἆ' => 'Ἆ', + 'Ἇ' => 'Ἇ', + 'ἐ' => 'ἐ', + 'ἑ' => 'ἑ', + 'ἒ' => 'ἒ', + 'ἓ' => 'ἓ', + 'ἔ' => 'ἔ', + 'ἕ' => 'ἕ', + 'Ἐ' => 'Ἐ', + 'Ἑ' => 'Ἑ', + 'Ἒ' => 'Ἒ', + 'Ἓ' => 'Ἓ', + 'Ἔ' => 'Ἔ', + 'Ἕ' => 'Ἕ', + 'ἠ' => 'ἠ', + 'ἡ' => 'ἡ', + 'ἢ' => 'ἢ', + 'ἣ' => 'ἣ', + 'ἤ' => 'ἤ', + 'ἥ' => 'ἥ', + 'ἦ' => 'ἦ', + 'ἧ' => 'ἧ', + 'Ἠ' => 'Ἠ', + 'Ἡ' => 'Ἡ', + 'Ἢ' => 'Ἢ', + 'Ἣ' => 'Ἣ', + 'Ἤ' => 'Ἤ', + 'Ἥ' => 'Ἥ', + 'Ἦ' => 'Ἦ', + 'Ἧ' => 'Ἧ', + 'ἰ' => 'ἰ', + 'ἱ' => 'ἱ', + 'ἲ' => 'ἲ', + 'ἳ' => 'ἳ', + 'ἴ' => 'ἴ', + 'ἵ' => 'ἵ', + 'ἶ' => 'ἶ', + 'ἷ' => 'ἷ', + 'Ἰ' => 'Ἰ', + 'Ἱ' => 'Ἱ', + 'Ἲ' => 'Ἲ', + 'Ἳ' => 'Ἳ', + 'Ἴ' => 'Ἴ', + 'Ἵ' => 'Ἵ', + 'Ἶ' => 'Ἶ', + 'Ἷ' => 'Ἷ', + 'ὀ' => 'ὀ', + 'ὁ' => 'ὁ', + 'ὂ' => 'ὂ', + 'ὃ' => 'ὃ', + 'ὄ' => 'ὄ', + 'ὅ' => 'ὅ', + 'Ὀ' => 'Ὀ', + 'Ὁ' => 'Ὁ', + 'Ὂ' => 'Ὂ', + 'Ὃ' => 'Ὃ', + 'Ὄ' => 'Ὄ', + 'Ὅ' => 'Ὅ', + 'ὐ' => 'ὐ', + 'ὑ' => 'ὑ', + 'ὒ' => 'ὒ', + 'ὓ' => 'ὓ', + 'ὔ' => 'ὔ', + 'ὕ' => 'ὕ', + 'ὖ' => 'ὖ', + 'ὗ' => 'ὗ', + 'Ὑ' => 'Ὑ', + 'Ὓ' => 'Ὓ', + 'Ὕ' => 'Ὕ', + 'Ὗ' => 'Ὗ', + 'ὠ' => 'ὠ', + 'ὡ' => 'ὡ', + 'ὢ' => 'ὢ', + 'ὣ' => 'ὣ', + 'ὤ' => 'ὤ', + 'ὥ' => 'ὥ', + 'ὦ' => 'ὦ', + 'ὧ' => 'ὧ', + 'Ὠ' => 'Ὠ', + 'Ὡ' => 'Ὡ', + 'Ὢ' => 'Ὢ', + 'Ὣ' => 'Ὣ', + 'Ὤ' => 'Ὤ', + 'Ὥ' => 'Ὥ', + 'Ὦ' => 'Ὦ', + 'Ὧ' => 'Ὧ', + 'ὰ' => 'ὰ', + 'ά' => 'ά', + 'ὲ' => 'ὲ', + 'έ' => 'έ', + 'ὴ' => 'ὴ', + 'ή' => 'ή', + 'ὶ' => 'ὶ', + 'ί' => 'ί', + 'ὸ' => 'ὸ', + 'ό' => 'ό', + 'ὺ' => 'ὺ', + 'ύ' => 'ύ', + 'ὼ' => 'ὼ', + 'ώ' => 'ώ', + 'ᾀ' => 'ᾀ', + 'ᾁ' => 'ᾁ', + 'ᾂ' => 'ᾂ', + 'ᾃ' => 'ᾃ', + 'ᾄ' => 'ᾄ', + 'ᾅ' => 'ᾅ', + 'ᾆ' => 'ᾆ', + 'ᾇ' => 'ᾇ', + 'ᾈ' => 'ᾈ', + 'ᾉ' => 'ᾉ', + 'ᾊ' => 'ᾊ', + 'ᾋ' => 'ᾋ', + 'ᾌ' => 'ᾌ', + 'ᾍ' => 'ᾍ', + 'ᾎ' => 'ᾎ', + 'ᾏ' => 'ᾏ', + 'ᾐ' => 'ᾐ', + 'ᾑ' => 'ᾑ', + 'ᾒ' => 'ᾒ', + 'ᾓ' => 'ᾓ', + 'ᾔ' => 'ᾔ', + 'ᾕ' => 'ᾕ', + 'ᾖ' => 'ᾖ', + 'ᾗ' => 'ᾗ', + 'ᾘ' => 'ᾘ', + 'ᾙ' => 'ᾙ', + 'ᾚ' => 'ᾚ', + 'ᾛ' => 'ᾛ', + 'ᾜ' => 'ᾜ', + 'ᾝ' => 'ᾝ', + 'ᾞ' => 'ᾞ', + 'ᾟ' => 'ᾟ', + 'ᾠ' => 'ᾠ', + 'ᾡ' => 'ᾡ', + 'ᾢ' => 'ᾢ', + 'ᾣ' => 'ᾣ', + 'ᾤ' => 'ᾤ', + 'ᾥ' => 'ᾥ', + 'ᾦ' => 'ᾦ', + 'ᾧ' => 'ᾧ', + 'ᾨ' => 'ᾨ', + 'ᾩ' => 'ᾩ', + 'ᾪ' => 'ᾪ', + 'ᾫ' => 'ᾫ', + 'ᾬ' => 'ᾬ', + 'ᾭ' => 'ᾭ', + 'ᾮ' => 'ᾮ', + 'ᾯ' => 'ᾯ', + 'ᾰ' => 'ᾰ', + 'ᾱ' => 'ᾱ', + 'ᾲ' => 'ᾲ', + 'ᾳ' => 'ᾳ', + 'ᾴ' => 'ᾴ', + 'ᾶ' => 'ᾶ', + 'ᾷ' => 'ᾷ', + 'Ᾰ' => 'Ᾰ', + 'Ᾱ' => 'Ᾱ', + 'Ὰ' => 'Ὰ', + 'Ά' => 'Ά', + 'ᾼ' => 'ᾼ', + 'ι' => 'ι', + '῁' => '῁', + 'ῂ' => 'ῂ', + 'ῃ' => 'ῃ', + 'ῄ' => 'ῄ', + 'ῆ' => 'ῆ', + 'ῇ' => 'ῇ', + 'Ὲ' => 'Ὲ', + 'Έ' => 'Έ', + 'Ὴ' => 'Ὴ', + 'Ή' => 'Ή', + 'ῌ' => 'ῌ', + '῍' => '῍', + '῎' => '῎', + '῏' => '῏', + 'ῐ' => 'ῐ', + 'ῑ' => 'ῑ', + 'ῒ' => 'ῒ', + 'ΐ' => 'ΐ', + 'ῖ' => 'ῖ', + 'ῗ' => 'ῗ', + 'Ῐ' => 'Ῐ', + 'Ῑ' => 'Ῑ', + 'Ὶ' => 'Ὶ', + 'Ί' => 'Ί', + '῝' => '῝', + '῞' => '῞', + '῟' => '῟', + 'ῠ' => 'ῠ', + 'ῡ' => 'ῡ', + 'ῢ' => 'ῢ', + 'ΰ' => 'ΰ', + 'ῤ' => 'ῤ', + 'ῥ' => 'ῥ', + 'ῦ' => 'ῦ', + 'ῧ' => 'ῧ', + 'Ῠ' => 'Ῠ', + 'Ῡ' => 'Ῡ', + 'Ὺ' => 'Ὺ', + 'Ύ' => 'Ύ', + 'Ῥ' => 'Ῥ', + '῭' => '῭', + '΅' => '΅', + '`' => '`', + 'ῲ' => 'ῲ', + 'ῳ' => 'ῳ', + 'ῴ' => 'ῴ', + 'ῶ' => 'ῶ', + 'ῷ' => 'ῷ', + 'Ὸ' => 'Ὸ', + 'Ό' => 'Ό', + 'Ὼ' => 'Ὼ', + 'Ώ' => 'Ώ', + 'ῼ' => 'ῼ', + '´' => '´', + ' ' => ' ', + ' ' => ' ', + 'Ω' => 'Ω', + 'K' => 'K', + 'Å' => 'Å', + '↚' => '↚', + '↛' => '↛', + '↮' => '↮', + '⇍' => '⇍', + '⇎' => '⇎', + '⇏' => '⇏', + '∄' => '∄', + '∉' => '∉', + '∌' => '∌', + '∤' => '∤', + '∦' => '∦', + '≁' => '≁', + '≄' => '≄', + '≇' => '≇', + '≉' => '≉', + '≠' => '≠', + '≢' => '≢', + '≭' => '≭', + '≮' => '≮', + '≯' => '≯', + '≰' => '≰', + '≱' => '≱', + '≴' => '≴', + '≵' => '≵', + '≸' => '≸', + '≹' => '≹', + '⊀' => '⊀', + '⊁' => '⊁', + '⊄' => '⊄', + '⊅' => '⊅', + '⊈' => '⊈', + '⊉' => '⊉', + '⊬' => '⊬', + '⊭' => '⊭', + '⊮' => '⊮', + '⊯' => '⊯', + '⋠' => '⋠', + '⋡' => '⋡', + '⋢' => '⋢', + '⋣' => '⋣', + '⋪' => '⋪', + '⋫' => '⋫', + '⋬' => '⋬', + '⋭' => '⋭', + '〈' => '〈', + '〉' => '〉', + '⫝̸' => '⫝̸', + 'が' => 'が', + 'ぎ' => 'ぎ', + 'ぐ' => 'ぐ', + 'げ' => 'げ', + 'ご' => 'ご', + 'ざ' => 'ざ', + 'じ' => 'じ', + 'ず' => 'ず', + 'ぜ' => 'ぜ', + 'ぞ' => 'ぞ', + 'だ' => 'だ', + 'ぢ' => 'ぢ', + 'づ' => 'づ', + 'で' => 'で', + 'ど' => 'ど', + 'ば' => 'ば', + 'ぱ' => 'ぱ', + 'び' => 'び', + 'ぴ' => 'ぴ', + 'ぶ' => 'ぶ', + 'ぷ' => 'ぷ', + 'べ' => 'べ', + 'ぺ' => 'ぺ', + 'ぼ' => 'ぼ', + 'ぽ' => 'ぽ', + 'ゔ' => 'ゔ', + 'ゞ' => 'ゞ', + 'ガ' => 'ガ', + 'ギ' => 'ギ', + 'グ' => 'グ', + 'ゲ' => 'ゲ', + 'ゴ' => 'ゴ', + 'ザ' => 'ザ', + 'ジ' => 'ジ', + 'ズ' => 'ズ', + 'ゼ' => 'ゼ', + 'ゾ' => 'ゾ', + 'ダ' => 'ダ', + 'ヂ' => 'ヂ', + 'ヅ' => 'ヅ', + 'デ' => 'デ', + 'ド' => 'ド', + 'バ' => 'バ', + 'パ' => 'パ', + 'ビ' => 'ビ', + 'ピ' => 'ピ', + 'ブ' => 'ブ', + 'プ' => 'プ', + 'ベ' => 'ベ', + 'ペ' => 'ペ', + 'ボ' => 'ボ', + 'ポ' => 'ポ', + 'ヴ' => 'ヴ', + 'ヷ' => 'ヷ', + 'ヸ' => 'ヸ', + 'ヹ' => 'ヹ', + 'ヺ' => 'ヺ', + 'ヾ' => 'ヾ', + '豈' => '豈', + '更' => '更', + '車' => '車', + '賈' => '賈', + '滑' => '滑', + '串' => '串', + '句' => '句', + '龜' => '龜', + '龜' => '龜', + '契' => '契', + '金' => '金', + '喇' => '喇', + '奈' => '奈', + '懶' => '懶', + '癩' => '癩', + '羅' => '羅', + '蘿' => '蘿', + '螺' => '螺', + '裸' => '裸', + '邏' => '邏', + '樂' => '樂', + '洛' => '洛', + '烙' => '烙', + '珞' => '珞', + '落' => '落', + '酪' => '酪', + '駱' => '駱', + '亂' => '亂', + '卵' => '卵', + '欄' => '欄', + '爛' => '爛', + '蘭' => '蘭', + '鸞' => '鸞', + '嵐' => '嵐', + '濫' => '濫', + '藍' => '藍', + '襤' => '襤', + '拉' => '拉', + '臘' => '臘', + '蠟' => '蠟', + '廊' => '廊', + '朗' => '朗', + '浪' => '浪', + '狼' => '狼', + '郎' => '郎', + '來' => '來', + '冷' => '冷', + '勞' => '勞', + '擄' => '擄', + '櫓' => '櫓', + '爐' => '爐', + '盧' => '盧', + '老' => '老', + '蘆' => '蘆', + '虜' => '虜', + '路' => '路', + '露' => '露', + '魯' => '魯', + '鷺' => '鷺', + '碌' => '碌', + '祿' => '祿', + '綠' => '綠', + '菉' => '菉', + '錄' => '錄', + '鹿' => '鹿', + '論' => '論', + '壟' => '壟', + '弄' => '弄', + '籠' => '籠', + '聾' => '聾', + '牢' => '牢', + '磊' => '磊', + '賂' => '賂', + '雷' => '雷', + '壘' => '壘', + '屢' => '屢', + '樓' => '樓', + '淚' => '淚', + '漏' => '漏', + '累' => '累', + '縷' => '縷', + '陋' => '陋', + '勒' => '勒', + '肋' => '肋', + '凜' => '凜', + '凌' => '凌', + '稜' => '稜', + '綾' => '綾', + '菱' => '菱', + '陵' => '陵', + '讀' => '讀', + '拏' => '拏', + '樂' => '樂', + '諾' => '諾', + '丹' => '丹', + '寧' => '寧', + '怒' => '怒', + '率' => '率', + '異' => '異', + '北' => '北', + '磻' => '磻', + '便' => '便', + '復' => '復', + '不' => '不', + '泌' => '泌', + '數' => '數', + '索' => '索', + '參' => '參', + '塞' => '塞', + '省' => '省', + '葉' => '葉', + '說' => '說', + '殺' => '殺', + '辰' => '辰', + '沈' => '沈', + '拾' => '拾', + '若' => '若', + '掠' => '掠', + '略' => '略', + '亮' => '亮', + '兩' => '兩', + '凉' => '凉', + '梁' => '梁', + '糧' => '糧', + '良' => '良', + '諒' => '諒', + '量' => '量', + '勵' => '勵', + '呂' => '呂', + '女' => '女', + '廬' => '廬', + '旅' => '旅', + '濾' => '濾', + '礪' => '礪', + '閭' => '閭', + '驪' => '驪', + '麗' => '麗', + '黎' => '黎', + '力' => '力', + '曆' => '曆', + '歷' => '歷', + '轢' => '轢', + '年' => '年', + '憐' => '憐', + '戀' => '戀', + '撚' => '撚', + '漣' => '漣', + '煉' => '煉', + '璉' => '璉', + '秊' => '秊', + '練' => '練', + '聯' => '聯', + '輦' => '輦', + '蓮' => '蓮', + '連' => '連', + '鍊' => '鍊', + '列' => '列', + '劣' => '劣', + '咽' => '咽', + '烈' => '烈', + '裂' => '裂', + '說' => '說', + '廉' => '廉', + '念' => '念', + '捻' => '捻', + '殮' => '殮', + '簾' => '簾', + '獵' => '獵', + '令' => '令', + '囹' => '囹', + '寧' => '寧', + '嶺' => '嶺', + '怜' => '怜', + '玲' => '玲', + '瑩' => '瑩', + '羚' => '羚', + '聆' => '聆', + '鈴' => '鈴', + '零' => '零', + '靈' => '靈', + '領' => '領', + '例' => '例', + '禮' => '禮', + '醴' => '醴', + '隸' => '隸', + '惡' => '惡', + '了' => '了', + '僚' => '僚', + '寮' => '寮', + '尿' => '尿', + '料' => '料', + '樂' => '樂', + '燎' => '燎', + '療' => '療', + '蓼' => '蓼', + '遼' => '遼', + '龍' => '龍', + '暈' => '暈', + '阮' => '阮', + '劉' => '劉', + '杻' => '杻', + '柳' => '柳', + '流' => '流', + '溜' => '溜', + '琉' => '琉', + '留' => '留', + '硫' => '硫', + '紐' => '紐', + '類' => '類', + '六' => '六', + '戮' => '戮', + '陸' => '陸', + '倫' => '倫', + '崙' => '崙', + '淪' => '淪', + '輪' => '輪', + '律' => '律', + '慄' => '慄', + '栗' => '栗', + '率' => '率', + '隆' => '隆', + '利' => '利', + '吏' => '吏', + '履' => '履', + '易' => '易', + '李' => '李', + '梨' => '梨', + '泥' => '泥', + '理' => '理', + '痢' => '痢', + '罹' => '罹', + '裏' => '裏', + '裡' => '裡', + '里' => '里', + '離' => '離', + '匿' => '匿', + '溺' => '溺', + '吝' => '吝', + '燐' => '燐', + '璘' => '璘', + '藺' => '藺', + '隣' => '隣', + '鱗' => '鱗', + '麟' => '麟', + '林' => '林', + '淋' => '淋', + '臨' => '臨', + '立' => '立', + '笠' => '笠', + '粒' => '粒', + '狀' => '狀', + '炙' => '炙', + '識' => '識', + '什' => '什', + '茶' => '茶', + '刺' => '刺', + '切' => '切', + '度' => '度', + '拓' => '拓', + '糖' => '糖', + '宅' => '宅', + '洞' => '洞', + '暴' => '暴', + '輻' => '輻', + '行' => '行', + '降' => '降', + '見' => '見', + '廓' => '廓', + '兀' => '兀', + '嗀' => '嗀', + '塚' => '塚', + '晴' => '晴', + '凞' => '凞', + '猪' => '猪', + '益' => '益', + '礼' => '礼', + '神' => '神', + '祥' => '祥', + '福' => '福', + '靖' => '靖', + '精' => '精', + '羽' => '羽', + '蘒' => '蘒', + '諸' => '諸', + '逸' => '逸', + '都' => '都', + '飯' => '飯', + '飼' => '飼', + '館' => '館', + '鶴' => '鶴', + '郞' => '郞', + '隷' => '隷', + '侮' => '侮', + '僧' => '僧', + '免' => '免', + '勉' => '勉', + '勤' => '勤', + '卑' => '卑', + '喝' => '喝', + '嘆' => '嘆', + '器' => '器', + '塀' => '塀', + '墨' => '墨', + '層' => '層', + '屮' => '屮', + '悔' => '悔', + '慨' => '慨', + '憎' => '憎', + '懲' => '懲', + '敏' => '敏', + '既' => '既', + '暑' => '暑', + '梅' => '梅', + '海' => '海', + '渚' => '渚', + '漢' => '漢', + '煮' => '煮', + '爫' => '爫', + '琢' => '琢', + '碑' => '碑', + '社' => '社', + '祉' => '祉', + '祈' => '祈', + '祐' => '祐', + '祖' => '祖', + '祝' => '祝', + '禍' => '禍', + '禎' => '禎', + '穀' => '穀', + '突' => '突', + '節' => '節', + '練' => '練', + '縉' => '縉', + '繁' => '繁', + '署' => '署', + '者' => '者', + '臭' => '臭', + '艹' => '艹', + '艹' => '艹', + '著' => '著', + '褐' => '褐', + '視' => '視', + '謁' => '謁', + '謹' => '謹', + '賓' => '賓', + '贈' => '贈', + '辶' => '辶', + '逸' => '逸', + '難' => '難', + '響' => '響', + '頻' => '頻', + '恵' => '恵', + '𤋮' => '𤋮', + '舘' => '舘', + '並' => '並', + '况' => '况', + '全' => '全', + '侀' => '侀', + '充' => '充', + '冀' => '冀', + '勇' => '勇', + '勺' => '勺', + '喝' => '喝', + '啕' => '啕', + '喙' => '喙', + '嗢' => '嗢', + '塚' => '塚', + '墳' => '墳', + '奄' => '奄', + '奔' => '奔', + '婢' => '婢', + '嬨' => '嬨', + '廒' => '廒', + '廙' => '廙', + '彩' => '彩', + '徭' => '徭', + '惘' => '惘', + '慎' => '慎', + '愈' => '愈', + '憎' => '憎', + '慠' => '慠', + '懲' => '懲', + '戴' => '戴', + '揄' => '揄', + '搜' => '搜', + '摒' => '摒', + '敖' => '敖', + '晴' => '晴', + '朗' => '朗', + '望' => '望', + '杖' => '杖', + '歹' => '歹', + '殺' => '殺', + '流' => '流', + '滛' => '滛', + '滋' => '滋', + '漢' => '漢', + '瀞' => '瀞', + '煮' => '煮', + '瞧' => '瞧', + '爵' => '爵', + '犯' => '犯', + '猪' => '猪', + '瑱' => '瑱', + '甆' => '甆', + '画' => '画', + '瘝' => '瘝', + '瘟' => '瘟', + '益' => '益', + '盛' => '盛', + '直' => '直', + '睊' => '睊', + '着' => '着', + '磌' => '磌', + '窱' => '窱', + '節' => '節', + '类' => '类', + '絛' => '絛', + '練' => '練', + '缾' => '缾', + '者' => '者', + '荒' => '荒', + '華' => '華', + '蝹' => '蝹', + '襁' => '襁', + '覆' => '覆', + '視' => '視', + '調' => '調', + '諸' => '諸', + '請' => '請', + '謁' => '謁', + '諾' => '諾', + '諭' => '諭', + '謹' => '謹', + '變' => '變', + '贈' => '贈', + '輸' => '輸', + '遲' => '遲', + '醙' => '醙', + '鉶' => '鉶', + '陼' => '陼', + '難' => '難', + '靖' => '靖', + '韛' => '韛', + '響' => '響', + '頋' => '頋', + '頻' => '頻', + '鬒' => '鬒', + '龜' => '龜', + '𢡊' => '𢡊', + '𢡄' => '𢡄', + '𣏕' => '𣏕', + '㮝' => '㮝', + '䀘' => '䀘', + '䀹' => '䀹', + '𥉉' => '𥉉', + '𥳐' => '𥳐', + '𧻓' => '𧻓', + '齃' => '齃', + '龎' => '龎', + 'יִ' => 'יִ', + 'ײַ' => 'ײַ', + 'שׁ' => 'שׁ', + 'שׂ' => 'שׂ', + 'שּׁ' => 'שּׁ', + 'שּׂ' => 'שּׂ', + 'אַ' => 'אַ', + 'אָ' => 'אָ', + 'אּ' => 'אּ', + 'בּ' => 'בּ', + 'גּ' => 'גּ', + 'דּ' => 'דּ', + 'הּ' => 'הּ', + 'וּ' => 'וּ', + 'זּ' => 'זּ', + 'טּ' => 'טּ', + 'יּ' => 'יּ', + 'ךּ' => 'ךּ', + 'כּ' => 'כּ', + 'לּ' => 'לּ', + 'מּ' => 'מּ', + 'נּ' => 'נּ', + 'סּ' => 'סּ', + 'ףּ' => 'ףּ', + 'פּ' => 'פּ', + 'צּ' => 'צּ', + 'קּ' => 'קּ', + 'רּ' => 'רּ', + 'שּ' => 'שּ', + 'תּ' => 'תּ', + 'וֹ' => 'וֹ', + 'בֿ' => 'בֿ', + 'כֿ' => 'כֿ', + 'פֿ' => 'פֿ', + '𑂚' => '𑂚', + '𑂜' => '𑂜', + '𑂫' => '𑂫', + '𑄮' => '𑄮', + '𑄯' => '𑄯', + '𑍋' => '𑍋', + '𑍌' => '𑍌', + '𑒻' => '𑒻', + '𑒼' => '𑒼', + '𑒾' => '𑒾', + '𑖺' => '𑖺', + '𑖻' => '𑖻', + '𑤸' => '𑤸', + '𝅗𝅥' => '𝅗𝅥', + '𝅘𝅥' => '𝅘𝅥', + '𝅘𝅥𝅮' => '𝅘𝅥𝅮', + '𝅘𝅥𝅯' => '𝅘𝅥𝅯', + '𝅘𝅥𝅰' => '𝅘𝅥𝅰', + '𝅘𝅥𝅱' => '𝅘𝅥𝅱', + '𝅘𝅥𝅲' => '𝅘𝅥𝅲', + '𝆹𝅥' => '𝆹𝅥', + '𝆺𝅥' => '𝆺𝅥', + '𝆹𝅥𝅮' => '𝆹𝅥𝅮', + '𝆺𝅥𝅮' => '𝆺𝅥𝅮', + '𝆹𝅥𝅯' => '𝆹𝅥𝅯', + '𝆺𝅥𝅯' => '𝆺𝅥𝅯', + '丽' => '丽', + '丸' => '丸', + '乁' => '乁', + '𠄢' => '𠄢', + '你' => '你', + '侮' => '侮', + '侻' => '侻', + '倂' => '倂', + '偺' => '偺', + '備' => '備', + '僧' => '僧', + '像' => '像', + '㒞' => '㒞', + '𠘺' => '𠘺', + '免' => '免', + '兔' => '兔', + '兤' => '兤', + '具' => '具', + '𠔜' => '𠔜', + '㒹' => '㒹', + '內' => '內', + '再' => '再', + '𠕋' => '𠕋', + '冗' => '冗', + '冤' => '冤', + '仌' => '仌', + '冬' => '冬', + '况' => '况', + '𩇟' => '𩇟', + '凵' => '凵', + '刃' => '刃', + '㓟' => '㓟', + '刻' => '刻', + '剆' => '剆', + '割' => '割', + '剷' => '剷', + '㔕' => '㔕', + '勇' => '勇', + '勉' => '勉', + '勤' => '勤', + '勺' => '勺', + '包' => '包', + '匆' => '匆', + '北' => '北', + '卉' => '卉', + '卑' => '卑', + '博' => '博', + '即' => '即', + '卽' => '卽', + '卿' => '卿', + '卿' => '卿', + '卿' => '卿', + '𠨬' => '𠨬', + '灰' => '灰', + '及' => '及', + '叟' => '叟', + '𠭣' => '𠭣', + '叫' => '叫', + '叱' => '叱', + '吆' => '吆', + '咞' => '咞', + '吸' => '吸', + '呈' => '呈', + '周' => '周', + '咢' => '咢', + '哶' => '哶', + '唐' => '唐', + '啓' => '啓', + '啣' => '啣', + '善' => '善', + '善' => '善', + '喙' => '喙', + '喫' => '喫', + '喳' => '喳', + '嗂' => '嗂', + '圖' => '圖', + '嘆' => '嘆', + '圗' => '圗', + '噑' => '噑', + '噴' => '噴', + '切' => '切', + '壮' => '壮', + '城' => '城', + '埴' => '埴', + '堍' => '堍', + '型' => '型', + '堲' => '堲', + '報' => '報', + '墬' => '墬', + '𡓤' => '𡓤', + '売' => '売', + '壷' => '壷', + '夆' => '夆', + '多' => '多', + '夢' => '夢', + '奢' => '奢', + '𡚨' => '𡚨', + '𡛪' => '𡛪', + '姬' => '姬', + '娛' => '娛', + '娧' => '娧', + '姘' => '姘', + '婦' => '婦', + '㛮' => '㛮', + '㛼' => '㛼', + '嬈' => '嬈', + '嬾' => '嬾', + '嬾' => '嬾', + '𡧈' => '𡧈', + '寃' => '寃', + '寘' => '寘', + '寧' => '寧', + '寳' => '寳', + '𡬘' => '𡬘', + '寿' => '寿', + '将' => '将', + '当' => '当', + '尢' => '尢', + '㞁' => '㞁', + '屠' => '屠', + '屮' => '屮', + '峀' => '峀', + '岍' => '岍', + '𡷤' => '𡷤', + '嵃' => '嵃', + '𡷦' => '𡷦', + '嵮' => '嵮', + '嵫' => '嵫', + '嵼' => '嵼', + '巡' => '巡', + '巢' => '巢', + '㠯' => '㠯', + '巽' => '巽', + '帨' => '帨', + '帽' => '帽', + '幩' => '幩', + '㡢' => '㡢', + '𢆃' => '𢆃', + '㡼' => '㡼', + '庰' => '庰', + '庳' => '庳', + '庶' => '庶', + '廊' => '廊', + '𪎒' => '𪎒', + '廾' => '廾', + '𢌱' => '𢌱', + '𢌱' => '𢌱', + '舁' => '舁', + '弢' => '弢', + '弢' => '弢', + '㣇' => '㣇', + '𣊸' => '𣊸', + '𦇚' => '𦇚', + '形' => '形', + '彫' => '彫', + '㣣' => '㣣', + '徚' => '徚', + '忍' => '忍', + '志' => '志', + '忹' => '忹', + '悁' => '悁', + '㤺' => '㤺', + '㤜' => '㤜', + '悔' => '悔', + '𢛔' => '𢛔', + '惇' => '惇', + '慈' => '慈', + '慌' => '慌', + '慎' => '慎', + '慌' => '慌', + '慺' => '慺', + '憎' => '憎', + '憲' => '憲', + '憤' => '憤', + '憯' => '憯', + '懞' => '懞', + '懲' => '懲', + '懶' => '懶', + '成' => '成', + '戛' => '戛', + '扝' => '扝', + '抱' => '抱', + '拔' => '拔', + '捐' => '捐', + '𢬌' => '𢬌', + '挽' => '挽', + '拼' => '拼', + '捨' => '捨', + '掃' => '掃', + '揤' => '揤', + '𢯱' => '𢯱', + '搢' => '搢', + '揅' => '揅', + '掩' => '掩', + '㨮' => '㨮', + '摩' => '摩', + '摾' => '摾', + '撝' => '撝', + '摷' => '摷', + '㩬' => '㩬', + '敏' => '敏', + '敬' => '敬', + '𣀊' => '𣀊', + '旣' => '旣', + '書' => '書', + '晉' => '晉', + '㬙' => '㬙', + '暑' => '暑', + '㬈' => '㬈', + '㫤' => '㫤', + '冒' => '冒', + '冕' => '冕', + '最' => '最', + '暜' => '暜', + '肭' => '肭', + '䏙' => '䏙', + '朗' => '朗', + '望' => '望', + '朡' => '朡', + '杞' => '杞', + '杓' => '杓', + '𣏃' => '𣏃', + '㭉' => '㭉', + '柺' => '柺', + '枅' => '枅', + '桒' => '桒', + '梅' => '梅', + '𣑭' => '𣑭', + '梎' => '梎', + '栟' => '栟', + '椔' => '椔', + '㮝' => '㮝', + '楂' => '楂', + '榣' => '榣', + '槪' => '槪', + '檨' => '檨', + '𣚣' => '𣚣', + '櫛' => '櫛', + '㰘' => '㰘', + '次' => '次', + '𣢧' => '𣢧', + '歔' => '歔', + '㱎' => '㱎', + '歲' => '歲', + '殟' => '殟', + '殺' => '殺', + '殻' => '殻', + '𣪍' => '𣪍', + '𡴋' => '𡴋', + '𣫺' => '𣫺', + '汎' => '汎', + '𣲼' => '𣲼', + '沿' => '沿', + '泍' => '泍', + '汧' => '汧', + '洖' => '洖', + '派' => '派', + '海' => '海', + '流' => '流', + '浩' => '浩', + '浸' => '浸', + '涅' => '涅', + '𣴞' => '𣴞', + '洴' => '洴', + '港' => '港', + '湮' => '湮', + '㴳' => '㴳', + '滋' => '滋', + '滇' => '滇', + '𣻑' => '𣻑', + '淹' => '淹', + '潮' => '潮', + '𣽞' => '𣽞', + '𣾎' => '𣾎', + '濆' => '濆', + '瀹' => '瀹', + '瀞' => '瀞', + '瀛' => '瀛', + '㶖' => '㶖', + '灊' => '灊', + '災' => '災', + '灷' => '灷', + '炭' => '炭', + '𠔥' => '𠔥', + '煅' => '煅', + '𤉣' => '𤉣', + '熜' => '熜', + '𤎫' => '𤎫', + '爨' => '爨', + '爵' => '爵', + '牐' => '牐', + '𤘈' => '𤘈', + '犀' => '犀', + '犕' => '犕', + '𤜵' => '𤜵', + '𤠔' => '𤠔', + '獺' => '獺', + '王' => '王', + '㺬' => '㺬', + '玥' => '玥', + '㺸' => '㺸', + '㺸' => '㺸', + '瑇' => '瑇', + '瑜' => '瑜', + '瑱' => '瑱', + '璅' => '璅', + '瓊' => '瓊', + '㼛' => '㼛', + '甤' => '甤', + '𤰶' => '𤰶', + '甾' => '甾', + '𤲒' => '𤲒', + '異' => '異', + '𢆟' => '𢆟', + '瘐' => '瘐', + '𤾡' => '𤾡', + '𤾸' => '𤾸', + '𥁄' => '𥁄', + '㿼' => '㿼', + '䀈' => '䀈', + '直' => '直', + '𥃳' => '𥃳', + '𥃲' => '𥃲', + '𥄙' => '𥄙', + '𥄳' => '𥄳', + '眞' => '眞', + '真' => '真', + '真' => '真', + '睊' => '睊', + '䀹' => '䀹', + '瞋' => '瞋', + '䁆' => '䁆', + '䂖' => '䂖', + '𥐝' => '𥐝', + '硎' => '硎', + '碌' => '碌', + '磌' => '磌', + '䃣' => '䃣', + '𥘦' => '𥘦', + '祖' => '祖', + '𥚚' => '𥚚', + '𥛅' => '𥛅', + '福' => '福', + '秫' => '秫', + '䄯' => '䄯', + '穀' => '穀', + '穊' => '穊', + '穏' => '穏', + '𥥼' => '𥥼', + '𥪧' => '𥪧', + '𥪧' => '𥪧', + '竮' => '竮', + '䈂' => '䈂', + '𥮫' => '𥮫', + '篆' => '篆', + '築' => '築', + '䈧' => '䈧', + '𥲀' => '𥲀', + '糒' => '糒', + '䊠' => '䊠', + '糨' => '糨', + '糣' => '糣', + '紀' => '紀', + '𥾆' => '𥾆', + '絣' => '絣', + '䌁' => '䌁', + '緇' => '緇', + '縂' => '縂', + '繅' => '繅', + '䌴' => '䌴', + '𦈨' => '𦈨', + '𦉇' => '𦉇', + '䍙' => '䍙', + '𦋙' => '𦋙', + '罺' => '罺', + '𦌾' => '𦌾', + '羕' => '羕', + '翺' => '翺', + '者' => '者', + '𦓚' => '𦓚', + '𦔣' => '𦔣', + '聠' => '聠', + '𦖨' => '𦖨', + '聰' => '聰', + '𣍟' => '𣍟', + '䏕' => '䏕', + '育' => '育', + '脃' => '脃', + '䐋' => '䐋', + '脾' => '脾', + '媵' => '媵', + '𦞧' => '𦞧', + '𦞵' => '𦞵', + '𣎓' => '𣎓', + '𣎜' => '𣎜', + '舁' => '舁', + '舄' => '舄', + '辞' => '辞', + '䑫' => '䑫', + '芑' => '芑', + '芋' => '芋', + '芝' => '芝', + '劳' => '劳', + '花' => '花', + '芳' => '芳', + '芽' => '芽', + '苦' => '苦', + '𦬼' => '𦬼', + '若' => '若', + '茝' => '茝', + '荣' => '荣', + '莭' => '莭', + '茣' => '茣', + '莽' => '莽', + '菧' => '菧', + '著' => '著', + '荓' => '荓', + '菊' => '菊', + '菌' => '菌', + '菜' => '菜', + '𦰶' => '𦰶', + '𦵫' => '𦵫', + '𦳕' => '𦳕', + '䔫' => '䔫', + '蓱' => '蓱', + '蓳' => '蓳', + '蔖' => '蔖', + '𧏊' => '𧏊', + '蕤' => '蕤', + '𦼬' => '𦼬', + '䕝' => '䕝', + '䕡' => '䕡', + '𦾱' => '𦾱', + '𧃒' => '𧃒', + '䕫' => '䕫', + '虐' => '虐', + '虜' => '虜', + '虧' => '虧', + '虩' => '虩', + '蚩' => '蚩', + '蚈' => '蚈', + '蜎' => '蜎', + '蛢' => '蛢', + '蝹' => '蝹', + '蜨' => '蜨', + '蝫' => '蝫', + '螆' => '螆', + '䗗' => '䗗', + '蟡' => '蟡', + '蠁' => '蠁', + '䗹' => '䗹', + '衠' => '衠', + '衣' => '衣', + '𧙧' => '𧙧', + '裗' => '裗', + '裞' => '裞', + '䘵' => '䘵', + '裺' => '裺', + '㒻' => '㒻', + '𧢮' => '𧢮', + '𧥦' => '𧥦', + '䚾' => '䚾', + '䛇' => '䛇', + '誠' => '誠', + '諭' => '諭', + '變' => '變', + '豕' => '豕', + '𧲨' => '𧲨', + '貫' => '貫', + '賁' => '賁', + '贛' => '贛', + '起' => '起', + '𧼯' => '𧼯', + '𠠄' => '𠠄', + '跋' => '跋', + '趼' => '趼', + '跰' => '跰', + '𠣞' => '𠣞', + '軔' => '軔', + '輸' => '輸', + '𨗒' => '𨗒', + '𨗭' => '𨗭', + '邔' => '邔', + '郱' => '郱', + '鄑' => '鄑', + '𨜮' => '𨜮', + '鄛' => '鄛', + '鈸' => '鈸', + '鋗' => '鋗', + '鋘' => '鋘', + '鉼' => '鉼', + '鏹' => '鏹', + '鐕' => '鐕', + '𨯺' => '𨯺', + '開' => '開', + '䦕' => '䦕', + '閷' => '閷', + '𨵷' => '𨵷', + '䧦' => '䧦', + '雃' => '雃', + '嶲' => '嶲', + '霣' => '霣', + '𩅅' => '𩅅', + '𩈚' => '𩈚', + '䩮' => '䩮', + '䩶' => '䩶', + '韠' => '韠', + '𩐊' => '𩐊', + '䪲' => '䪲', + '𩒖' => '𩒖', + '頋' => '頋', + '頋' => '頋', + '頩' => '頩', + '𩖶' => '𩖶', + '飢' => '飢', + '䬳' => '䬳', + '餩' => '餩', + '馧' => '馧', + '駂' => '駂', + '駾' => '駾', + '䯎' => '䯎', + '𩬰' => '𩬰', + '鬒' => '鬒', + '鱀' => '鱀', + '鳽' => '鳽', + '䳎' => '䳎', + '䳭' => '䳭', + '鵧' => '鵧', + '𪃎' => '𪃎', + '䳸' => '䳸', + '𪄅' => '𪄅', + '𪈎' => '𪈎', + '𪊑' => '𪊑', + '麻' => '麻', + '䵖' => '䵖', + '黹' => '黹', + '黾' => '黾', + '鼅' => '鼅', + '鼏' => '鼏', + '鼖' => '鼖', + '鼻' => '鼻', + '𪘀' => '𪘀', +); diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php new file mode 100644 index 0000000..ec90f36 --- /dev/null +++ b/lib/SymfonyMailer/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/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php new file mode 100644 index 0000000..1574902 --- /dev/null +++ b/lib/SymfonyMailer/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/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/bootstrap.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/bootstrap.php new file mode 100644 index 0000000..3608e5c --- /dev/null +++ b/lib/SymfonyMailer/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/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php new file mode 100644 index 0000000..e36d1a9 --- /dev/null +++ b/lib/SymfonyMailer/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/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/composer.json b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/composer.json new file mode 100644 index 0000000..9bd04e8 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-intl-normalizer/composer.json @@ -0,0 +1,36 @@ +{ + "name": "symfony/polyfill-intl-normalizer", + "type": "library", + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "keywords": ["polyfill", "shim", "compatibility", "portable", "intl", "normalizer"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.2" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, + "files": [ "bootstrap.php" ], + "classmap": [ "Resources/stubs" ] + }, + "suggest": { + "ext-intl": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/LICENSE b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/LICENSE new file mode 100644 index 0000000..6e3afce --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Mbstring.php b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Mbstring.php new file mode 100644 index 0000000..31e36a3 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Mbstring.php @@ -0,0 +1,1045 @@ + + * + * 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 + * - mb_ucfirst - Make a string's first character uppercase + * - mb_lcfirst - Make a string's first character lowercase + * - mb_trim - Strip whitespace (or other characters) from the beginning and end of a string + * - mb_ltrim - Strip whitespace (or other characters) from the beginning of a string + * - mb_rtrim - Strip whitespace (or other characters) from the end of a string + * + * 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 +{ + public const MB_CASE_FOLD = \PHP_INT_MAX; + + private const SIMPLE_CASE_FOLD = [ + ['µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"], + ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'], + ]; + + private static $encodingList = ['ASCII', 'UTF-8']; + private static $language = 'neutral'; + private static $internalEncoding = 'UTF-8'; + + public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) + { + if (\is_array($s)) { + $r = []; + foreach ($s as $str) { + $r[] = self::mb_convert_encoding($str, $toEncoding, $fromEncoding); + } + + return $r; + } + + if (\is_array($fromEncoding) || (null !== $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]+/', [__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, &...$vars) + { + $ok = true; + array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) { + if (false === $v = self::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) || (80000 > \PHP_VERSION_ID && !$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 self::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) || (80000 > \PHP_VERSION_ID && !$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 = ["\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, [__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) { + static $caseFolding = null; + if (null === $caseFolding) { + $caseFolding = self::getData('caseFolding'); + } + $s = strtr($s, $caseFolding); + } + + static $lower = null; + if (null === $lower) { + $lower = self::getData('lowerCase'); + } + $map = $lower; + } + + static $ulenMask = ["\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; + } + + $normalizedEncoding = self::getEncoding($encoding); + + if ('UTF-8' === $normalizedEncoding || false !== @iconv($normalizedEncoding, $normalizedEncoding, ' ')) { + self::$internalEncoding = $normalizedEncoding; + + return true; + } + + if (80000 > \PHP_VERSION_ID) { + return false; + } + + throw new \ValueError(sprintf('Argument #1 ($encoding) must be a valid encoding, "%s" given', $encoding)); + } + + public static function mb_language($lang = null) + { + if (null === $lang) { + return self::$language; + } + + switch ($normalizedLang = strtolower($lang)) { + case 'uni': + case 'neutral': + self::$language = $normalizedLang; + + return true; + } + + if (80000 > \PHP_VERSION_ID) { + return false; + } + + throw new \ValueError(sprintf('Argument #1 ($language) must be a valid language, "%s" given', $lang)); + } + + public static function mb_list_encodings() + { + return ['UTF-8']; + } + + public static function mb_encoding_aliases($encoding) + { + switch (strtoupper($encoding)) { + case 'UTF8': + case 'UTF-8': + return ['utf8']; + } + + return false; + } + + public static function mb_check_encoding($var = null, $encoding = null) + { + if (null === $encoding) { + if (null === $var) { + return false; + } + $encoding = self::$internalEncoding; + } + + if (!\is_array($var)) { + return self::mb_detect_encoding($var, [$encoding]) || false !== @iconv($encoding, $encoding, $var); + } + + foreach ($var as $key => $value) { + if (!self::mb_check_encoding($key, $encoding)) { + return false; + } + if (!self::mb_check_encoding($value, $encoding)) { + return false; + } + } + + return true; + } + + 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) { + if (80000 > \PHP_VERSION_ID) { + trigger_error(__METHOD__.': Empty delimiter', \E_USER_WARNING); + + return false; + } + + return 0; + } + + 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 = '' !== $needle || 80000 > \PHP_VERSION_ID + ? iconv_strrpos($haystack, $needle, $encoding) + : self::mb_strlen($haystack, $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) { + if (80000 > \PHP_VERSION_ID) { + trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING); + + return false; + } + + throw new \ValueError('Argument #2 ($length) must be greater than 0'); + } + + 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, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY); + } + + $result = []; + $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 (null === $c) { + return 'none'; + } + if (0 === strcasecmp($c, 'none')) { + return true; + } + if (80000 > \PHP_VERSION_ID) { + return false; + } + if (\is_int($c) || 'long' === $c || 'entity' === $c) { + return false; + } + + throw new \ValueError('Argument #1 ($substitute_character) must be "none", "long", "entity" or a valid codepoint'); + } + + 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, $needle] = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], [ + self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding), + self::mb_convert_case($needle, \MB_CASE_LOWER, $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) { + $pos = strrpos($haystack, $needle); + } else { + $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, \MB_CASE_LOWER, $encoding); + $needle = self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding); + + $haystack = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $haystack); + $needle = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $needle); + + 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 = [ + '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; + } + + public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null): string + { + if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { + throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); + } + + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given'); + } + + if (self::mb_strlen($pad_string, $encoding) <= 0) { + throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string'); + } + + $paddingRequired = $length - self::mb_strlen($string, $encoding); + + if ($paddingRequired < 1) { + return $string; + } + + switch ($pad_type) { + case \STR_PAD_LEFT: + return self::mb_substr(str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding).$string; + case \STR_PAD_RIGHT: + return $string.self::mb_substr(str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding); + default: + $leftPaddingLength = floor($paddingRequired / 2); + $rightPaddingLength = $paddingRequired - $leftPaddingLength; + + return self::mb_substr(str_repeat($pad_string, $leftPaddingLength), 0, $leftPaddingLength, $encoding).$string.self::mb_substr(str_repeat($pad_string, $rightPaddingLength), 0, $rightPaddingLength, $encoding); + } + } + + public static function mb_ucfirst(string $string, ?string $encoding = null): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, 'mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given'); + } + + $firstChar = mb_substr($string, 0, 1, $encoding); + $firstChar = mb_convert_case($firstChar, \MB_CASE_TITLE, $encoding); + + return $firstChar.mb_substr($string, 1, null, $encoding); + } + + public static function mb_lcfirst(string $string, ?string $encoding = null): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, 'mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given'); + } + + $firstChar = mb_substr($string, 0, 1, $encoding); + $firstChar = mb_convert_case($firstChar, \MB_CASE_LOWER, $encoding); + + return $firstChar.mb_substr($string, 1, null, $encoding); + } + + 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; + } + + public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__); + } + + public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__); + } + + public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{[%s]+$}Du', $string, $characters, $encoding, __FUNCTION__); + } + + private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, $function.'(): Argument #3 ($encoding) must be a valid encoding, "%s" given'); + } + + if ('' === $characters) { + return null === $encoding ? $string : self::mb_convert_encoding($string, $encoding); + } + + if ('UTF-8' === $encoding) { + $encoding = null; + if (!preg_match('//u', $string)) { + $string = @iconv('UTF-8', 'UTF-8//IGNORE', $string); + } + if (null !== $characters && !preg_match('//u', $characters)) { + $characters = @iconv('UTF-8', 'UTF-8//IGNORE', $characters); + } + } else { + $string = iconv($encoding, 'UTF-8//IGNORE', $string); + + if (null !== $characters) { + $characters = iconv($encoding, 'UTF-8//IGNORE', $characters); + } + } + + if (null === $characters) { + $characters = "\\0 \f\n\r\t\v\u{00A0}\u{1680}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{2028}\u{2029}\u{202F}\u{205F}\u{3000}\u{0085}\u{180E}"; + } else { + $characters = preg_quote($characters); + } + + $string = preg_replace(sprintf($regex, $characters), '', $string); + + if (null === $encoding) { + return $string; + } + + return iconv('UTF-8', $encoding.'//IGNORE', $string); + } + + private static function assertEncoding(string $encoding, string $errorFormat): void + { + try { + $validEncoding = @self::mb_check_encoding('', $encoding); + } catch (\ValueError $e) { + throw new \ValueError(sprintf($errorFormat, $encoding)); + } + + // BC for PHP 7.3 and lower + if (!$validEncoding) { + throw new \ValueError(sprintf($errorFormat, $encoding)); + } + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/README.md b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/README.md new file mode 100644 index 0000000..478b40d --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/README.md @@ -0,0 +1,13 @@ +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/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php new file mode 100644 index 0000000..512bba0 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php @@ -0,0 +1,119 @@ + 'i̇', + 'µ' => 'μ', + 'ſ' => 's', + 'ͅ' => 'ι', + 'ς' => 'σ', + 'ϐ' => 'β', + 'ϑ' => 'θ', + 'ϕ' => 'φ', + 'ϖ' => 'π', + 'ϰ' => 'κ', + 'ϱ' => 'ρ', + 'ϵ' => 'ε', + 'ẛ' => 'ṡ', + 'ι' => 'ι', + 'ß' => 'ss', + 'ʼn' => 'ʼn', + 'ǰ' => 'ǰ', + 'ΐ' => 'ΐ', + 'ΰ' => 'ΰ', + 'և' => 'եւ', + 'ẖ' => 'ẖ', + 'ẗ' => 'ẗ', + 'ẘ' => 'ẘ', + 'ẙ' => 'ẙ', + 'ẚ' => 'aʾ', + 'ẞ' => 'ss', + 'ὐ' => 'ὐ', + 'ὒ' => 'ὒ', + 'ὔ' => 'ὔ', + 'ὖ' => 'ὖ', + 'ᾀ' => 'ἀι', + 'ᾁ' => 'ἁι', + 'ᾂ' => 'ἂι', + 'ᾃ' => 'ἃι', + 'ᾄ' => 'ἄι', + 'ᾅ' => 'ἅι', + 'ᾆ' => 'ἆι', + 'ᾇ' => 'ἇι', + 'ᾈ' => 'ἀι', + 'ᾉ' => 'ἁι', + 'ᾊ' => 'ἂι', + 'ᾋ' => 'ἃι', + 'ᾌ' => 'ἄι', + 'ᾍ' => 'ἅι', + 'ᾎ' => 'ἆι', + 'ᾏ' => 'ἇι', + 'ᾐ' => 'ἠι', + 'ᾑ' => 'ἡι', + 'ᾒ' => 'ἢι', + 'ᾓ' => 'ἣι', + 'ᾔ' => 'ἤι', + 'ᾕ' => 'ἥι', + 'ᾖ' => 'ἦι', + 'ᾗ' => 'ἧι', + 'ᾘ' => 'ἠι', + 'ᾙ' => 'ἡι', + 'ᾚ' => 'ἢι', + 'ᾛ' => 'ἣι', + 'ᾜ' => 'ἤι', + 'ᾝ' => 'ἥι', + 'ᾞ' => 'ἦι', + 'ᾟ' => 'ἧι', + 'ᾠ' => 'ὠι', + 'ᾡ' => 'ὡι', + 'ᾢ' => 'ὢι', + 'ᾣ' => 'ὣι', + 'ᾤ' => 'ὤι', + 'ᾥ' => 'ὥι', + 'ᾦ' => 'ὦι', + 'ᾧ' => 'ὧι', + 'ᾨ' => 'ὠι', + 'ᾩ' => 'ὡι', + 'ᾪ' => 'ὢι', + 'ᾫ' => 'ὣι', + 'ᾬ' => 'ὤι', + 'ᾭ' => 'ὥι', + 'ᾮ' => 'ὦι', + 'ᾯ' => 'ὧι', + 'ᾲ' => 'ὰι', + 'ᾳ' => 'αι', + 'ᾴ' => 'άι', + 'ᾶ' => 'ᾶ', + 'ᾷ' => 'ᾶι', + 'ᾼ' => 'αι', + 'ῂ' => 'ὴι', + 'ῃ' => 'ηι', + 'ῄ' => 'ήι', + 'ῆ' => 'ῆ', + 'ῇ' => 'ῆι', + 'ῌ' => 'ηι', + 'ῒ' => 'ῒ', + 'ῖ' => 'ῖ', + 'ῗ' => 'ῗ', + 'ῢ' => 'ῢ', + 'ῤ' => 'ῤ', + 'ῦ' => 'ῦ', + 'ῧ' => 'ῧ', + 'ῲ' => 'ὼι', + 'ῳ' => 'ωι', + 'ῴ' => 'ώι', + 'ῶ' => 'ῶ', + 'ῷ' => 'ῶι', + 'ῼ' => 'ωι', + 'ff' => 'ff', + 'fi' => 'fi', + 'fl' => 'fl', + 'ffi' => 'ffi', + 'ffl' => 'ffl', + 'ſt' => 'st', + 'st' => 'st', + 'ﬓ' => 'մն', + 'ﬔ' => 'մե', + 'ﬕ' => 'մի', + 'ﬖ' => 'վն', + 'ﬗ' => 'մխ', +]; diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php new file mode 100644 index 0000000..fac60b0 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php @@ -0,0 +1,1397 @@ + '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/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php new file mode 100644 index 0000000..2a8f6e7 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php @@ -0,0 +1,5 @@ + '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', + '𐐨' => '𐐀', + '𐐩' => '𐐁', + '𐐪' => '𐐂', + '𐐫' => '𐐃', + '𐐬' => '𐐄', + '𐐭' => '𐐅', + '𐐮' => '𐐆', + '𐐯' => '𐐇', + '𐐰' => '𐐈', + '𐐱' => '𐐉', + '𐐲' => '𐐊', + '𐐳' => '𐐋', + '𐐴' => '𐐌', + '𐐵' => '𐐍', + '𐐶' => '𐐎', + '𐐷' => '𐐏', + '𐐸' => '𐐐', + '𐐹' => '𐐑', + '𐐺' => '𐐒', + '𐐻' => '𐐓', + '𐐼' => '𐐔', + '𐐽' => '𐐕', + '𐐾' => '𐐖', + '𐐿' => '𐐗', + '𐑀' => '𐐘', + '𐑁' => '𐐙', + '𐑂' => '𐐚', + '𐑃' => '𐐛', + '𐑄' => '𐐜', + '𐑅' => '𐐝', + '𐑆' => '𐐞', + '𐑇' => '𐐟', + '𐑈' => '𐐠', + '𐑉' => '𐐡', + '𐑊' => '𐐢', + '𐑋' => '𐐣', + '𐑌' => '𐐤', + '𐑍' => '𐐥', + '𐑎' => '𐐦', + '𐑏' => '𐐧', + '𐓘' => '𐒰', + '𐓙' => '𐒱', + '𐓚' => '𐒲', + '𐓛' => '𐒳', + '𐓜' => '𐒴', + '𐓝' => '𐒵', + '𐓞' => '𐒶', + '𐓟' => '𐒷', + '𐓠' => '𐒸', + '𐓡' => '𐒹', + '𐓢' => '𐒺', + '𐓣' => '𐒻', + '𐓤' => '𐒼', + '𐓥' => '𐒽', + '𐓦' => '𐒾', + '𐓧' => '𐒿', + '𐓨' => '𐓀', + '𐓩' => '𐓁', + '𐓪' => '𐓂', + '𐓫' => '𐓃', + '𐓬' => '𐓄', + '𐓭' => '𐓅', + '𐓮' => '𐓆', + '𐓯' => '𐓇', + '𐓰' => '𐓈', + '𐓱' => '𐓉', + '𐓲' => '𐓊', + '𐓳' => '𐓋', + '𐓴' => '𐓌', + '𐓵' => '𐓍', + '𐓶' => '𐓎', + '𐓷' => '𐓏', + '𐓸' => '𐓐', + '𐓹' => '𐓑', + '𐓺' => '𐓒', + '𐓻' => '𐓓', + '𐳀' => '𐲀', + '𐳁' => '𐲁', + '𐳂' => '𐲂', + '𐳃' => '𐲃', + '𐳄' => '𐲄', + '𐳅' => '𐲅', + '𐳆' => '𐲆', + '𐳇' => '𐲇', + '𐳈' => '𐲈', + '𐳉' => '𐲉', + '𐳊' => '𐲊', + '𐳋' => '𐲋', + '𐳌' => '𐲌', + '𐳍' => '𐲍', + '𐳎' => '𐲎', + '𐳏' => '𐲏', + '𐳐' => '𐲐', + '𐳑' => '𐲑', + '𐳒' => '𐲒', + '𐳓' => '𐲓', + '𐳔' => '𐲔', + '𐳕' => '𐲕', + '𐳖' => '𐲖', + '𐳗' => '𐲗', + '𐳘' => '𐲘', + '𐳙' => '𐲙', + '𐳚' => '𐲚', + '𐳛' => '𐲛', + '𐳜' => '𐲜', + '𐳝' => '𐲝', + '𐳞' => '𐲞', + '𐳟' => '𐲟', + '𐳠' => '𐲠', + '𐳡' => '𐲡', + '𐳢' => '𐲢', + '𐳣' => '𐲣', + '𐳤' => '𐲤', + '𐳥' => '𐲥', + '𐳦' => '𐲦', + '𐳧' => '𐲧', + '𐳨' => '𐲨', + '𐳩' => '𐲩', + '𐳪' => '𐲪', + '𐳫' => '𐲫', + '𐳬' => '𐲬', + '𐳭' => '𐲭', + '𐳮' => '𐲮', + '𐳯' => '𐲯', + '𐳰' => '𐲰', + '𐳱' => '𐲱', + '𐳲' => '𐲲', + '𑣀' => '𑢠', + '𑣁' => '𑢡', + '𑣂' => '𑢢', + '𑣃' => '𑢣', + '𑣄' => '𑢤', + '𑣅' => '𑢥', + '𑣆' => '𑢦', + '𑣇' => '𑢧', + '𑣈' => '𑢨', + '𑣉' => '𑢩', + '𑣊' => '𑢪', + '𑣋' => '𑢫', + '𑣌' => '𑢬', + '𑣍' => '𑢭', + '𑣎' => '𑢮', + '𑣏' => '𑢯', + '𑣐' => '𑢰', + '𑣑' => '𑢱', + '𑣒' => '𑢲', + '𑣓' => '𑢳', + '𑣔' => '𑢴', + '𑣕' => '𑢵', + '𑣖' => '𑢶', + '𑣗' => '𑢷', + '𑣘' => '𑢸', + '𑣙' => '𑢹', + '𑣚' => '𑢺', + '𑣛' => '𑢻', + '𑣜' => '𑢼', + '𑣝' => '𑢽', + '𑣞' => '𑢾', + '𑣟' => '𑢿', + '𖹠' => '𖹀', + '𖹡' => '𖹁', + '𖹢' => '𖹂', + '𖹣' => '𖹃', + '𖹤' => '𖹄', + '𖹥' => '𖹅', + '𖹦' => '𖹆', + '𖹧' => '𖹇', + '𖹨' => '𖹈', + '𖹩' => '𖹉', + '𖹪' => '𖹊', + '𖹫' => '𖹋', + '𖹬' => '𖹌', + '𖹭' => '𖹍', + '𖹮' => '𖹎', + '𖹯' => '𖹏', + '𖹰' => '𖹐', + '𖹱' => '𖹑', + '𖹲' => '𖹒', + '𖹳' => '𖹓', + '𖹴' => '𖹔', + '𖹵' => '𖹕', + '𖹶' => '𖹖', + '𖹷' => '𖹗', + '𖹸' => '𖹘', + '𖹹' => '𖹙', + '𖹺' => '𖹚', + '𖹻' => '𖹛', + '𖹼' => '𖹜', + '𖹽' => '𖹝', + '𖹾' => '𖹞', + '𖹿' => '𖹟', + '𞤢' => '𞤀', + '𞤣' => '𞤁', + '𞤤' => '𞤂', + '𞤥' => '𞤃', + '𞤦' => '𞤄', + '𞤧' => '𞤅', + '𞤨' => '𞤆', + '𞤩' => '𞤇', + '𞤪' => '𞤈', + '𞤫' => '𞤉', + '𞤬' => '𞤊', + '𞤭' => '𞤋', + '𞤮' => '𞤌', + '𞤯' => '𞤍', + '𞤰' => '𞤎', + '𞤱' => '𞤏', + '𞤲' => '𞤐', + '𞤳' => '𞤑', + '𞤴' => '𞤒', + '𞤵' => '𞤓', + '𞤶' => '𞤔', + '𞤷' => '𞤕', + '𞤸' => '𞤖', + '𞤹' => '𞤗', + '𞤺' => '𞤘', + '𞤻' => '𞤙', + '𞤼' => '𞤚', + '𞤽' => '𞤛', + '𞤾' => '𞤜', + '𞤿' => '𞤝', + '𞥀' => '𞤞', + '𞥁' => '𞤟', + '𞥂' => '𞤠', + '𞥃' => '𞤡', + 'ß' => 'SS', + 'ff' => 'FF', + 'fi' => 'FI', + 'fl' => 'FL', + 'ffi' => 'FFI', + 'ffl' => 'FFL', + 'ſt' => 'ST', + 'st' => 'ST', + 'և' => 'ԵՒ', + 'ﬓ' => 'ՄՆ', + 'ﬔ' => 'ՄԵ', + 'ﬕ' => 'ՄԻ', + 'ﬖ' => 'ՎՆ', + 'ﬗ' => 'ՄԽ', + 'ʼn' => 'ʼN', + 'ΐ' => 'Ϊ́', + 'ΰ' => 'Ϋ́', + 'ǰ' => 'J̌', + 'ẖ' => 'H̱', + 'ẗ' => 'T̈', + 'ẘ' => 'W̊', + 'ẙ' => 'Y̊', + 'ẚ' => 'Aʾ', + 'ὐ' => 'Υ̓', + 'ὒ' => 'Υ̓̀', + 'ὔ' => 'Υ̓́', + 'ὖ' => 'Υ̓͂', + 'ᾶ' => 'Α͂', + 'ῆ' => 'Η͂', + 'ῒ' => 'Ϊ̀', + 'ΐ' => 'Ϊ́', + 'ῖ' => 'Ι͂', + 'ῗ' => 'Ϊ͂', + 'ῢ' => 'Ϋ̀', + 'ΰ' => 'Ϋ́', + 'ῤ' => 'Ρ̓', + 'ῦ' => 'Υ͂', + 'ῧ' => 'Ϋ͂', + 'ῶ' => 'Ω͂', + 'ᾈ' => 'ἈΙ', + 'ᾉ' => 'ἉΙ', + 'ᾊ' => 'ἊΙ', + 'ᾋ' => 'ἋΙ', + 'ᾌ' => 'ἌΙ', + 'ᾍ' => 'ἍΙ', + 'ᾎ' => 'ἎΙ', + 'ᾏ' => 'ἏΙ', + 'ᾘ' => 'ἨΙ', + 'ᾙ' => 'ἩΙ', + 'ᾚ' => 'ἪΙ', + 'ᾛ' => 'ἫΙ', + 'ᾜ' => 'ἬΙ', + 'ᾝ' => 'ἭΙ', + 'ᾞ' => 'ἮΙ', + 'ᾟ' => 'ἯΙ', + 'ᾨ' => 'ὨΙ', + 'ᾩ' => 'ὩΙ', + 'ᾪ' => 'ὪΙ', + 'ᾫ' => 'ὫΙ', + 'ᾬ' => 'ὬΙ', + 'ᾭ' => 'ὭΙ', + 'ᾮ' => 'ὮΙ', + 'ᾯ' => 'ὯΙ', + 'ᾼ' => 'ΑΙ', + 'ῌ' => 'ΗΙ', + 'ῼ' => 'ΩΙ', + 'ᾲ' => 'ᾺΙ', + 'ᾴ' => 'ΆΙ', + 'ῂ' => 'ῊΙ', + 'ῄ' => 'ΉΙ', + 'ῲ' => 'ῺΙ', + 'ῴ' => 'ΏΙ', + 'ᾷ' => 'Α͂Ι', + 'ῇ' => 'Η͂Ι', + 'ῷ' => 'Ω͂Ι', +); diff --git a/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/bootstrap.php b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/bootstrap.php new file mode 100644 index 0000000..ff51ae0 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/bootstrap.php @@ -0,0 +1,172 @@ + + * + * 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 (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (!function_exists('mb_convert_encoding')) { + function mb_convert_encoding($string, $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); } +} +if (!function_exists('mb_decode_mimeheader')) { + function mb_decode_mimeheader($string) { return p\Mbstring::mb_decode_mimeheader($string); } +} +if (!function_exists('mb_encode_mimeheader')) { + function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = "\r\n", $indent = 0) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); } +} +if (!function_exists('mb_decode_numericentity')) { + function mb_decode_numericentity($string, $map, $encoding = null) { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); } +} +if (!function_exists('mb_encode_numericentity')) { + function mb_encode_numericentity($string, $map, $encoding = null, $hex = false) { return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex); } +} +if (!function_exists('mb_convert_case')) { + function mb_convert_case($string, $mode, $encoding = null) { return p\Mbstring::mb_convert_case($string, $mode, $encoding); } +} +if (!function_exists('mb_internal_encoding')) { + function mb_internal_encoding($encoding = null) { return p\Mbstring::mb_internal_encoding($encoding); } +} +if (!function_exists('mb_language')) { + function mb_language($language = null) { return p\Mbstring::mb_language($language); } +} +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($value = null, $encoding = null) { return p\Mbstring::mb_check_encoding($value, $encoding); } +} +if (!function_exists('mb_detect_encoding')) { + function mb_detect_encoding($string, $encodings = null, $strict = false) { return p\Mbstring::mb_detect_encoding($string, $encodings, $strict); } +} +if (!function_exists('mb_detect_order')) { + function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); } +} +if (!function_exists('mb_parse_str')) { + function mb_parse_str($string, &$result = []) { parse_str($string, $result); return (bool) $result; } +} +if (!function_exists('mb_strlen')) { + function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); } +} +if (!function_exists('mb_strpos')) { + function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strtolower')) { + function mb_strtolower($string, $encoding = null) { return p\Mbstring::mb_strtolower($string, $encoding); } +} +if (!function_exists('mb_strtoupper')) { + function mb_strtoupper($string, $encoding = null) { return p\Mbstring::mb_strtoupper($string, $encoding); } +} +if (!function_exists('mb_substitute_character')) { + function mb_substitute_character($substitute_character = null) { return p\Mbstring::mb_substitute_character($substitute_character); } +} +if (!function_exists('mb_substr')) { + function mb_substr($string, $start, $length = 2147483647, $encoding = null) { return p\Mbstring::mb_substr($string, $start, $length, $encoding); } +} +if (!function_exists('mb_stripos')) { + function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_stristr')) { + function mb_stristr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strrchr')) { + function mb_strrchr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strrichr')) { + function mb_strrichr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strripos')) { + function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strrpos')) { + function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strstr')) { + function mb_strstr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding); } +} +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($encoding = null) { return p\Mbstring::mb_http_output($encoding); } +} +if (!function_exists('mb_strwidth')) { + function mb_strwidth($string, $encoding = null) { return p\Mbstring::mb_strwidth($string, $encoding); } +} +if (!function_exists('mb_substr_count')) { + function mb_substr_count($haystack, $needle, $encoding = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $encoding); } +} +if (!function_exists('mb_output_handler')) { + function mb_output_handler($string, $status) { return p\Mbstring::mb_output_handler($string, $status); } +} +if (!function_exists('mb_http_input')) { + function mb_http_input($type = null) { return p\Mbstring::mb_http_input($type); } +} + +if (!function_exists('mb_convert_variables')) { + function mb_convert_variables($to_encoding, $from_encoding, &...$vars) { return p\Mbstring::mb_convert_variables($to_encoding, $from_encoding, ...$vars); } +} + +if (!function_exists('mb_ord')) { + function mb_ord($string, $encoding = null) { return p\Mbstring::mb_ord($string, $encoding); } +} +if (!function_exists('mb_chr')) { + function mb_chr($codepoint, $encoding = null) { return p\Mbstring::mb_chr($codepoint, $encoding); } +} +if (!function_exists('mb_scrub')) { + function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); } +} +if (!function_exists('mb_str_split')) { + function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $length, $encoding); } +} + +if (!function_exists('mb_str_pad')) { + function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } +} + +if (!function_exists('mb_ucfirst')) { + function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); } +} + +if (!function_exists('mb_lcfirst')) { + function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); } +} + +if (!function_exists('mb_trim')) { + function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); } +} + +if (!function_exists('mb_ltrim')) { + function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } +} + +if (!function_exists('mb_rtrim')) { + function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $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/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/bootstrap80.php b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/bootstrap80.php new file mode 100644 index 0000000..5236e6d --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/bootstrap80.php @@ -0,0 +1,167 @@ + + * + * 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(array|string|null $string, ?string $to_encoding, array|string|null $from_encoding = null): array|string|false { return p\Mbstring::mb_convert_encoding($string ?? '', (string) $to_encoding, $from_encoding); } +} +if (!function_exists('mb_decode_mimeheader')) { + function mb_decode_mimeheader(?string $string): string { return p\Mbstring::mb_decode_mimeheader((string) $string); } +} +if (!function_exists('mb_encode_mimeheader')) { + function mb_encode_mimeheader(?string $string, ?string $charset = null, ?string $transfer_encoding = null, ?string $newline = "\r\n", ?int $indent = 0): string { return p\Mbstring::mb_encode_mimeheader((string) $string, $charset, $transfer_encoding, (string) $newline, (int) $indent); } +} +if (!function_exists('mb_decode_numericentity')) { + function mb_decode_numericentity(?string $string, array $map, ?string $encoding = null): string { return p\Mbstring::mb_decode_numericentity((string) $string, $map, $encoding); } +} +if (!function_exists('mb_encode_numericentity')) { + function mb_encode_numericentity(?string $string, array $map, ?string $encoding = null, ?bool $hex = false): string { return p\Mbstring::mb_encode_numericentity((string) $string, $map, $encoding, (bool) $hex); } +} +if (!function_exists('mb_convert_case')) { + function mb_convert_case(?string $string, ?int $mode, ?string $encoding = null): string { return p\Mbstring::mb_convert_case((string) $string, (int) $mode, $encoding); } +} +if (!function_exists('mb_internal_encoding')) { + function mb_internal_encoding(?string $encoding = null): string|bool { return p\Mbstring::mb_internal_encoding($encoding); } +} +if (!function_exists('mb_language')) { + function mb_language(?string $language = null): string|bool { return p\Mbstring::mb_language($language); } +} +if (!function_exists('mb_list_encodings')) { + function mb_list_encodings(): array { return p\Mbstring::mb_list_encodings(); } +} +if (!function_exists('mb_encoding_aliases')) { + function mb_encoding_aliases(?string $encoding): array { return p\Mbstring::mb_encoding_aliases((string) $encoding); } +} +if (!function_exists('mb_check_encoding')) { + function mb_check_encoding(array|string|null $value = null, ?string $encoding = null): bool { return p\Mbstring::mb_check_encoding($value, $encoding); } +} +if (!function_exists('mb_detect_encoding')) { + function mb_detect_encoding(?string $string, array|string|null $encodings = null, ?bool $strict = false): string|false { return p\Mbstring::mb_detect_encoding((string) $string, $encodings, (bool) $strict); } +} +if (!function_exists('mb_detect_order')) { + function mb_detect_order(array|string|null $encoding = null): array|bool { return p\Mbstring::mb_detect_order($encoding); } +} +if (!function_exists('mb_parse_str')) { + function mb_parse_str(?string $string, &$result = []): bool { parse_str((string) $string, $result); return (bool) $result; } +} +if (!function_exists('mb_strlen')) { + function mb_strlen(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strlen((string) $string, $encoding); } +} +if (!function_exists('mb_strpos')) { + function mb_strpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strpos((string) $haystack, (string) $needle, (int) $offset, $encoding); } +} +if (!function_exists('mb_strtolower')) { + function mb_strtolower(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtolower((string) $string, $encoding); } +} +if (!function_exists('mb_strtoupper')) { + function mb_strtoupper(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtoupper((string) $string, $encoding); } +} +if (!function_exists('mb_substitute_character')) { + function mb_substitute_character(string|int|null $substitute_character = null): string|int|bool { return p\Mbstring::mb_substitute_character($substitute_character); } +} +if (!function_exists('mb_substr')) { + function mb_substr(?string $string, ?int $start, ?int $length = null, ?string $encoding = null): string { return p\Mbstring::mb_substr((string) $string, (int) $start, $length, $encoding); } +} +if (!function_exists('mb_stripos')) { + function mb_stripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_stripos((string) $haystack, (string) $needle, (int) $offset, $encoding); } +} +if (!function_exists('mb_stristr')) { + function mb_stristr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_stristr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } +} +if (!function_exists('mb_strrchr')) { + function mb_strrchr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrchr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } +} +if (!function_exists('mb_strrichr')) { + function mb_strrichr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrichr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } +} +if (!function_exists('mb_strripos')) { + function mb_strripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strripos((string) $haystack, (string) $needle, (int) $offset, $encoding); } +} +if (!function_exists('mb_strrpos')) { + function mb_strrpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strrpos((string) $haystack, (string) $needle, (int) $offset, $encoding); } +} +if (!function_exists('mb_strstr')) { + function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } +} +if (!function_exists('mb_get_info')) { + function mb_get_info(?string $type = 'all'): array|string|int|false|null { return p\Mbstring::mb_get_info((string) $type); } +} +if (!function_exists('mb_http_output')) { + function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); } +} +if (!function_exists('mb_strwidth')) { + function mb_strwidth(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strwidth((string) $string, $encoding); } +} +if (!function_exists('mb_substr_count')) { + function mb_substr_count(?string $haystack, ?string $needle, ?string $encoding = null): int { return p\Mbstring::mb_substr_count((string) $haystack, (string) $needle, $encoding); } +} +if (!function_exists('mb_output_handler')) { + function mb_output_handler(?string $string, ?int $status): string { return p\Mbstring::mb_output_handler((string) $string, (int) $status); } +} +if (!function_exists('mb_http_input')) { + function mb_http_input(?string $type = null): array|string|false { return p\Mbstring::mb_http_input($type); } +} + +if (!function_exists('mb_convert_variables')) { + function mb_convert_variables(?string $to_encoding, array|string|null $from_encoding, mixed &$var, mixed &...$vars): string|false { return p\Mbstring::mb_convert_variables((string) $to_encoding, $from_encoding ?? '', $var, ...$vars); } +} + +if (!function_exists('mb_ord')) { + function mb_ord(?string $string, ?string $encoding = null): int|false { return p\Mbstring::mb_ord((string) $string, $encoding); } +} +if (!function_exists('mb_chr')) { + function mb_chr(?int $codepoint, ?string $encoding = null): string|false { return p\Mbstring::mb_chr((int) $codepoint, $encoding); } +} +if (!function_exists('mb_scrub')) { + function mb_scrub(?string $string, ?string $encoding = null): string { $encoding ??= mb_internal_encoding(); return mb_convert_encoding((string) $string, $encoding, $encoding); } +} +if (!function_exists('mb_str_split')) { + function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = null): array { return p\Mbstring::mb_str_split((string) $string, (int) $length, $encoding); } +} + +if (!function_exists('mb_str_pad')) { + function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } +} + +if (!function_exists('mb_ucfirst')) { + function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); } +} + +if (!function_exists('mb_lcfirst')) { + function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); } +} + +if (!function_exists('mb_trim')) { + function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); } +} + +if (!function_exists('mb_ltrim')) { + function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } +} + +if (!function_exists('mb_rtrim')) { + function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $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/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/composer.json b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/composer.json new file mode 100644 index 0000000..daa07f8 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/polyfill-mbstring/composer.json @@ -0,0 +1,39 @@ +{ + "name": "symfony/polyfill-mbstring", + "type": "library", + "description": "Symfony polyfill for the Mbstring extension", + "keywords": ["polyfill", "shim", "compatibility", "portable", "mbstring"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.2", + "ext-iconv": "*" + }, + "provide": { + "ext-mbstring": "*" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" }, + "files": [ "bootstrap.php" ] + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/Attribute/Required.php b/lib/SymfonyMailer/vendor/symfony/service-contracts/Attribute/Required.php new file mode 100644 index 0000000..9df8511 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/Attribute/Required.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service\Attribute; + +/** + * A required dependency. + * + * This attribute indicates that a property holds a required dependency. The annotated property or method should be + * considered during the instantiation process of the containing class. + * + * @author Alexander M. Turek + */ +#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)] +final class Required +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/Attribute/SubscribedService.php b/lib/SymfonyMailer/vendor/symfony/service-contracts/Attribute/SubscribedService.php new file mode 100644 index 0000000..f850b84 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/Attribute/SubscribedService.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service\Attribute; + +use Symfony\Contracts\Service\ServiceMethodsSubscriberTrait; +use Symfony\Contracts\Service\ServiceSubscriberInterface; + +/** + * For use as the return value for {@see ServiceSubscriberInterface}. + * + * @example new SubscribedService('http_client', HttpClientInterface::class, false, new Target('githubApi')) + * + * Use with {@see ServiceMethodsSubscriberTrait} to mark a method's return type + * as a subscribed service. + * + * @author Kevin Bond + */ +#[\Attribute(\Attribute::TARGET_METHOD)] +final class SubscribedService +{ + /** @var object[] */ + public array $attributes; + + /** + * @param string|null $key The key to use for the service + * @param class-string|null $type The service class + * @param bool $nullable Whether the service is optional + * @param object|object[] $attributes One or more dependency injection attributes to use + */ + public function __construct( + public ?string $key = null, + public ?string $type = null, + public bool $nullable = false, + array|object $attributes = [], + ) { + $this->attributes = \is_array($attributes) ? $attributes : [$attributes]; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/CHANGELOG.md b/lib/SymfonyMailer/vendor/symfony/service-contracts/CHANGELOG.md new file mode 100644 index 0000000..7932e26 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/CHANGELOG.md @@ -0,0 +1,5 @@ +CHANGELOG +========= + +The changelog is maintained for all Symfony contracts at the following URL: +https://github.com/symfony/contracts/blob/main/CHANGELOG.md diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/LICENSE b/lib/SymfonyMailer/vendor/symfony/service-contracts/LICENSE new file mode 100644 index 0000000..7536cae --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/README.md b/lib/SymfonyMailer/vendor/symfony/service-contracts/README.md new file mode 100644 index 0000000..42841a5 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/README.md @@ -0,0 +1,9 @@ +Symfony Service Contracts +========================= + +A set of abstractions extracted out of the Symfony components. + +Can be used to build on semantics that the Symfony components proved useful and +that already have battle tested implementations. + +See https://github.com/symfony/contracts/blob/main/README.md for more information. diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/ResetInterface.php b/lib/SymfonyMailer/vendor/symfony/service-contracts/ResetInterface.php new file mode 100644 index 0000000..a4f389b --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/ResetInterface.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +/** + * Provides a way to reset an object to its initial state. + * + * When calling the "reset()" method on an object, it should be put back to its + * initial state. This usually means clearing any internal buffers and forwarding + * the call to internal dependencies. All properties of the object should be put + * back to the same state it had when it was first ready to use. + * + * This method could be called, for example, to recycle objects that are used as + * services, so that they can be used to handle several requests in the same + * process loop (note that we advise making your services stateless instead of + * implementing this interface when possible.) + */ +interface ResetInterface +{ + /** + * @return void + */ + public function reset(); +} diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceCollectionInterface.php b/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceCollectionInterface.php new file mode 100644 index 0000000..2333139 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceCollectionInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +/** + * A ServiceProviderInterface that is also countable and iterable. + * + * @author Kevin Bond + * + * @template-covariant T of mixed + * + * @extends ServiceProviderInterface + * @extends \IteratorAggregate + */ +interface ServiceCollectionInterface extends ServiceProviderInterface, \Countable, \IteratorAggregate +{ +} diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceLocatorTrait.php b/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceLocatorTrait.php new file mode 100644 index 0000000..bbe4548 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceLocatorTrait.php @@ -0,0 +1,114 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; + +// Help opcache.preload discover always-needed symbols +class_exists(ContainerExceptionInterface::class); +class_exists(NotFoundExceptionInterface::class); + +/** + * A trait to help implement ServiceProviderInterface. + * + * @author Robin Chalas + * @author Nicolas Grekas + */ +trait ServiceLocatorTrait +{ + private array $loading = []; + private array $providedTypes; + + /** + * @param array $factories + */ + public function __construct( + private array $factories, + ) { + } + + public function has(string $id): bool + { + return isset($this->factories[$id]); + } + + public function get(string $id): mixed + { + if (!isset($this->factories[$id])) { + throw $this->createNotFoundException($id); + } + + if (isset($this->loading[$id])) { + $ids = array_values($this->loading); + $ids = \array_slice($this->loading, array_search($id, $ids)); + $ids[] = $id; + + throw $this->createCircularReferenceException($id, $ids); + } + + $this->loading[$id] = $id; + try { + return $this->factories[$id]($this); + } finally { + unset($this->loading[$id]); + } + } + + public function getProvidedServices(): array + { + if (!isset($this->providedTypes)) { + $this->providedTypes = []; + + foreach ($this->factories as $name => $factory) { + if (!\is_callable($factory)) { + $this->providedTypes[$name] = '?'; + } else { + $type = (new \ReflectionFunction($factory))->getReturnType(); + + $this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '').($type instanceof \ReflectionNamedType ? $type->getName() : $type) : '?'; + } + } + } + + return $this->providedTypes; + } + + private function createNotFoundException(string $id): NotFoundExceptionInterface + { + if (!$alternatives = array_keys($this->factories)) { + $message = 'is empty...'; + } else { + $last = array_pop($alternatives); + if ($alternatives) { + $message = \sprintf('only knows about the "%s" and "%s" services.', implode('", "', $alternatives), $last); + } else { + $message = \sprintf('only knows about the "%s" service.', $last); + } + } + + if ($this->loading) { + $message = \sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $message); + } else { + $message = \sprintf('Service "%s" not found: the current service locator %s', $id, $message); + } + + return new class($message) extends \InvalidArgumentException implements NotFoundExceptionInterface { + }; + } + + private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface + { + return new class(\sprintf('Circular reference detected for service "%s", path: "%s".', $id, implode(' -> ', $path))) extends \RuntimeException implements ContainerExceptionInterface { + }; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceMethodsSubscriberTrait.php b/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceMethodsSubscriberTrait.php new file mode 100644 index 0000000..844be89 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceMethodsSubscriberTrait.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Psr\Container\ContainerInterface; +use Symfony\Contracts\Service\Attribute\Required; +use Symfony\Contracts\Service\Attribute\SubscribedService; + +/** + * Implementation of ServiceSubscriberInterface that determines subscribed services + * from methods that have the #[SubscribedService] attribute. + * + * Service ids are available as "ClassName::methodName" so that the implementation + * of subscriber methods can be just `return $this->container->get(__METHOD__);`. + * + * @author Kevin Bond + */ +trait ServiceMethodsSubscriberTrait +{ + protected ContainerInterface $container; + + public static function getSubscribedServices(): array + { + $services = method_exists(get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : []; + + foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { + if (self::class !== $method->getDeclaringClass()->name) { + continue; + } + + if (!$attribute = $method->getAttributes(SubscribedService::class)[0] ?? null) { + continue; + } + + if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) { + throw new \LogicException(\sprintf('Cannot use "%s" on method "%s::%s()" (can only be used on non-static, non-abstract methods with no parameters).', SubscribedService::class, self::class, $method->name)); + } + + if (!$returnType = $method->getReturnType()) { + throw new \LogicException(\sprintf('Cannot use "%s" on methods without a return type in "%s::%s()".', SubscribedService::class, $method->name, self::class)); + } + + /* @var SubscribedService $attribute */ + $attribute = $attribute->newInstance(); + $attribute->key ??= self::class.'::'.$method->name; + $attribute->type ??= $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType; + $attribute->nullable = $attribute->nullable ?: $returnType->allowsNull(); + + if ($attribute->attributes) { + $services[] = $attribute; + } else { + $services[$attribute->key] = ($attribute->nullable ? '?' : '').$attribute->type; + } + } + + return $services; + } + + #[Required] + public function setContainer(ContainerInterface $container): ?ContainerInterface + { + $ret = null; + if (method_exists(get_parent_class(self::class) ?: '', __FUNCTION__)) { + $ret = parent::setContainer($container); + } + + $this->container = $container; + + return $ret; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceProviderInterface.php b/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceProviderInterface.php new file mode 100644 index 0000000..2e71f00 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceProviderInterface.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Psr\Container\ContainerInterface; + +/** + * A ServiceProviderInterface exposes the identifiers and the types of services provided by a container. + * + * @author Nicolas Grekas + * @author Mateusz Sip + * + * @template-covariant T of mixed + */ +interface ServiceProviderInterface extends ContainerInterface +{ + /** + * @return T + */ + public function get(string $id): mixed; + + public function has(string $id): bool; + + /** + * Returns an associative array of service types keyed by the identifiers provided by the current container. + * + * Examples: + * + * * ['logger' => 'Psr\Log\LoggerInterface'] means the object provides a service named "logger" that implements Psr\Log\LoggerInterface + * * ['foo' => '?'] means the container provides service name "foo" of unspecified type + * * ['bar' => '?Bar\Baz'] means the container provides a service "bar" of type Bar\Baz|null + * + * @return array The provided service types, keyed by service names + */ + public function getProvidedServices(): array; +} diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceSubscriberInterface.php b/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceSubscriberInterface.php new file mode 100644 index 0000000..3da1916 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceSubscriberInterface.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Symfony\Contracts\Service\Attribute\SubscribedService; + +/** + * A ServiceSubscriber exposes its dependencies via the static {@link getSubscribedServices} method. + * + * The getSubscribedServices method returns an array of service types required by such instances, + * optionally keyed by the service names used internally. Service types that start with an interrogation + * mark "?" are optional, while the other ones are mandatory service dependencies. + * + * The injected service locators SHOULD NOT allow access to any other services not specified by the method. + * + * It is expected that ServiceSubscriber instances consume PSR-11-based service locators internally. + * This interface does not dictate any injection method for these service locators, although constructor + * injection is recommended. + * + * @author Nicolas Grekas + */ +interface ServiceSubscriberInterface +{ + /** + * Returns an array of service types (or {@see SubscribedService} objects) required + * by such instances, optionally keyed by the service names used internally. + * + * For mandatory dependencies: + * + * * ['logger' => 'Psr\Log\LoggerInterface'] means the objects use the "logger" name + * internally to fetch a service which must implement Psr\Log\LoggerInterface. + * * ['loggers' => 'Psr\Log\LoggerInterface[]'] means the objects use the "loggers" name + * internally to fetch an iterable of Psr\Log\LoggerInterface instances. + * * ['Psr\Log\LoggerInterface'] is a shortcut for + * * ['Psr\Log\LoggerInterface' => 'Psr\Log\LoggerInterface'] + * + * otherwise: + * + * * ['logger' => '?Psr\Log\LoggerInterface'] denotes an optional dependency + * * ['loggers' => '?Psr\Log\LoggerInterface[]'] denotes an optional iterable dependency + * * ['?Psr\Log\LoggerInterface'] is a shortcut for + * * ['Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface'] + * + * additionally, an array of {@see SubscribedService}'s can be returned: + * + * * [new SubscribedService('logger', Psr\Log\LoggerInterface::class)] + * * [new SubscribedService(type: Psr\Log\LoggerInterface::class, nullable: true)] + * * [new SubscribedService('http_client', HttpClientInterface::class, attributes: new Target('githubApi'))] + * + * @return string[]|SubscribedService[] The required service types, optionally keyed by service names + */ + public static function getSubscribedServices(): array; +} diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceSubscriberTrait.php b/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceSubscriberTrait.php new file mode 100644 index 0000000..ed4cec0 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/ServiceSubscriberTrait.php @@ -0,0 +1,84 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Psr\Container\ContainerInterface; +use Symfony\Contracts\Service\Attribute\Required; +use Symfony\Contracts\Service\Attribute\SubscribedService; + +trigger_deprecation('symfony/contracts', 'v3.5', '"%s" is deprecated, use "ServiceMethodsSubscriberTrait" instead.', ServiceSubscriberTrait::class); + +/** + * Implementation of ServiceSubscriberInterface that determines subscribed services + * from methods that have the #[SubscribedService] attribute. + * + * Service ids are available as "ClassName::methodName" so that the implementation + * of subscriber methods can be just `return $this->container->get(__METHOD__);`. + * + * @property ContainerInterface $container + * + * @author Kevin Bond + * + * @deprecated since symfony/contracts v3.5, use ServiceMethodsSubscriberTrait instead + */ +trait ServiceSubscriberTrait +{ + public static function getSubscribedServices(): array + { + $services = method_exists(get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : []; + + foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { + if (self::class !== $method->getDeclaringClass()->name) { + continue; + } + + if (!$attribute = $method->getAttributes(SubscribedService::class)[0] ?? null) { + continue; + } + + if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) { + throw new \LogicException(\sprintf('Cannot use "%s" on method "%s::%s()" (can only be used on non-static, non-abstract methods with no parameters).', SubscribedService::class, self::class, $method->name)); + } + + if (!$returnType = $method->getReturnType()) { + throw new \LogicException(\sprintf('Cannot use "%s" on methods without a return type in "%s::%s()".', SubscribedService::class, $method->name, self::class)); + } + + /* @var SubscribedService $attribute */ + $attribute = $attribute->newInstance(); + $attribute->key ??= self::class.'::'.$method->name; + $attribute->type ??= $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType; + $attribute->nullable = $attribute->nullable ?: $returnType->allowsNull(); + + if ($attribute->attributes) { + $services[] = $attribute; + } else { + $services[$attribute->key] = ($attribute->nullable ? '?' : '').$attribute->type; + } + } + + return $services; + } + + #[Required] + public function setContainer(ContainerInterface $container): ?ContainerInterface + { + $ret = null; + if (method_exists(get_parent_class(self::class) ?: '', __FUNCTION__)) { + $ret = parent::setContainer($container); + } + + $this->container = $container; + + return $ret; + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php b/lib/SymfonyMailer/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php new file mode 100644 index 0000000..07d12b4 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service\Test; + +class_alias(ServiceLocatorTestCase::class, ServiceLocatorTest::class); + +if (false) { + /** + * @deprecated since PHPUnit 9.6 + */ + class ServiceLocatorTest + { + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/Test/ServiceLocatorTestCase.php b/lib/SymfonyMailer/vendor/symfony/service-contracts/Test/ServiceLocatorTestCase.php new file mode 100644 index 0000000..fdd5b27 --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/Test/ServiceLocatorTestCase.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service\Test; + +use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; +use Symfony\Contracts\Service\ServiceLocatorTrait; + +abstract class ServiceLocatorTestCase extends TestCase +{ + /** + * @param array $factories + */ + protected function getServiceLocator(array $factories): ContainerInterface + { + return new class($factories) implements ContainerInterface { + use ServiceLocatorTrait; + }; + } + + public function testHas() + { + $locator = $this->getServiceLocator([ + 'foo' => fn () => 'bar', + 'bar' => fn () => 'baz', + fn () => 'dummy', + ]); + + $this->assertTrue($locator->has('foo')); + $this->assertTrue($locator->has('bar')); + $this->assertFalse($locator->has('dummy')); + } + + public function testGet() + { + $locator = $this->getServiceLocator([ + 'foo' => fn () => 'bar', + 'bar' => fn () => 'baz', + ]); + + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame('baz', $locator->get('bar')); + } + + public function testGetDoesNotMemoize() + { + $i = 0; + $locator = $this->getServiceLocator([ + 'foo' => function () use (&$i) { + ++$i; + + return 'bar'; + }, + ]); + + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame(2, $i); + } + + public function testThrowsOnUndefinedInternalService() + { + $locator = $this->getServiceLocator([ + 'foo' => function () use (&$locator) { return $locator->get('bar'); }, + ]); + + $this->expectException(NotFoundExceptionInterface::class); + $this->expectExceptionMessage('The service "foo" has a dependency on a non-existent service "bar". This locator only knows about the "foo" service.'); + + $locator->get('foo'); + } + + public function testThrowsOnCircularReference() + { + $locator = $this->getServiceLocator([ + 'foo' => function () use (&$locator) { return $locator->get('bar'); }, + 'bar' => function () use (&$locator) { return $locator->get('baz'); }, + 'baz' => function () use (&$locator) { return $locator->get('bar'); }, + ]); + + $this->expectException(ContainerExceptionInterface::class); + $this->expectExceptionMessage('Circular reference detected for service "bar", path: "bar -> baz -> bar".'); + + $locator->get('foo'); + } +} diff --git a/lib/SymfonyMailer/vendor/symfony/service-contracts/composer.json b/lib/SymfonyMailer/vendor/symfony/service-contracts/composer.json new file mode 100644 index 0000000..bc2e99a --- /dev/null +++ b/lib/SymfonyMailer/vendor/symfony/service-contracts/composer.json @@ -0,0 +1,42 @@ +{ + "name": "symfony/service-contracts", + "type": "library", + "description": "Generic abstractions related to writing services", + "keywords": ["abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "autoload": { + "psr-4": { "Symfony\\Contracts\\Service\\": "" }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "3.6-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + } +}