From 12e99f965ade27bc00c54541096715e1904acd3f Mon Sep 17 00:00:00 2001 From: Anton Medvedev Date: Tue, 22 Oct 2024 14:35:56 +0200 Subject: [PATCH] Release v7.5.3 --- .github/workflows/docker.yml | 3 - .github/workflows/release.yml | 3 - .gitignore | 1 - .php-cs-fixer.dist.php | 13 - Dockerfile | 9 - bin/build | 101 - bin/dep | Bin 2804 -> 792695 bytes bin/docgen | 56 - composer.json | 33 - composer.lock | 5345 ----------------- deployer.phar | Bin 0 -> 792695 bytes docs/KNOWN_BUGS.md | 59 - docs/UPGRADE.md | 274 - docs/api.md | 584 -- docs/avoid-php-fpm-reloading.md | 62 - docs/basics.md | 245 - docs/ci-cd.md | 99 - docs/cli.md | 148 - docs/contrib/README.md | 35 - docs/contrib/bugsnag.md | 36 - docs/contrib/cachetool.md | 159 - docs/contrib/chatwork.md | 190 - docs/contrib/cimonitor.md | 209 - docs/contrib/cloudflare.md | 48 - docs/contrib/cpanel.md | 141 - docs/contrib/crontab.md | 84 - docs/contrib/directadmin.md | 82 - docs/contrib/discord.md | 148 - docs/contrib/grafana.md | 46 - docs/contrib/hangouts.md | 118 - docs/contrib/hipchat.md | 80 - docs/contrib/ispmanager.md | 245 - docs/contrib/mattermost.md | 185 - docs/contrib/ms-teams.md | 171 - docs/contrib/newrelic.md | 79 - docs/contrib/npm.md | 53 - docs/contrib/ntfy.md | 184 - docs/contrib/phinx.md | 114 - docs/contrib/php-fpm.md | 84 - docs/contrib/rabbit.md | 59 - docs/contrib/raygun.md | 40 - docs/contrib/rocketchat.md | 214 - docs/contrib/rollbar.md | 50 - docs/contrib/rsync.md | 208 - docs/contrib/sentry.md | 60 - docs/contrib/slack.md | 204 - docs/contrib/supervisord-monitor.md | 106 - docs/contrib/telegram.md | 157 - docs/contrib/webpack_encore.md | 71 - docs/contrib/workplace.md | 128 - docs/contrib/yammer.md | 128 - docs/contrib/yarn.md | 49 - docs/getting-started.md | 175 - docs/hosts.md | 247 - docs/installation.md | 57 - docs/recipe/README.md | 30 - docs/recipe/cakephp.md | 118 - docs/recipe/codeigniter.md | 91 - docs/recipe/codeigniter4.md | 323 - docs/recipe/common.md | 266 - docs/recipe/composer.md | 32 - docs/recipe/contao.md | 183 - docs/recipe/craftcms.md | 123 - docs/recipe/deploy/check_remote.md | 25 - docs/recipe/deploy/cleanup.md | 35 - docs/recipe/deploy/clear_paths.md | 42 - docs/recipe/deploy/copy_dirs.md | 33 - docs/recipe/deploy/env.md | 24 - docs/recipe/deploy/info.md | 52 - docs/recipe/deploy/lock.md | 40 - docs/recipe/deploy/push.md | 26 - docs/recipe/deploy/release.md | 111 - docs/recipe/deploy/rollback.md | 54 - docs/recipe/deploy/setup.md | 24 - docs/recipe/deploy/shared.md | 47 - docs/recipe/deploy/symlink.md | 35 - docs/recipe/deploy/update_code.md | 90 - docs/recipe/deploy/vendors.md | 58 - docs/recipe/deploy/writable.md | 104 - docs/recipe/drupal7.md | 133 - docs/recipe/drupal8.md | 118 - docs/recipe/flow_framework.md | 123 - docs/recipe/fuelphp.md | 81 - docs/recipe/joomla.md | 101 - docs/recipe/laravel.md | 554 -- docs/recipe/magento.md | 120 - docs/recipe/magento2.md | 775 --- docs/recipe/pimcore.md | 82 - docs/recipe/prestashop.md | 111 - docs/recipe/provision.md | 134 - docs/recipe/provision/databases.md | 90 - docs/recipe/provision/nodejs.md | 35 - docs/recipe/provision/php.md | 54 - docs/recipe/provision/user.md | 43 - docs/recipe/provision/website.md | 69 - docs/recipe/shopware.md | 309 - docs/recipe/silverstripe.md | 137 - docs/recipe/spiral.md | 287 - docs/recipe/statamic.md | 224 - docs/recipe/sulu.md | 88 - docs/recipe/symfony.md | 202 - docs/recipe/typo3.md | 124 - docs/recipe/wordpress.md | 101 - docs/recipe/yii.md | 101 - docs/recipe/zend_framework.md | 66 - docs/selector.md | 198 - docs/sidebar.js | 19 - docs/tasks.md | 136 - docs/yaml.md | 31 - phpstan.neon | 18 - phpunit.xml | 24 - src/Collection/Collection.php | 93 - src/Command/BlackjackCommand.php | 399 -- src/Command/CommandCommon.php | 42 - src/Command/ConfigCommand.php | 79 - src/Command/CustomOption.php | 52 - src/Command/InitCommand.php | 263 - src/Command/MainCommand.php | 203 - src/Command/RunCommand.php | 91 - src/Command/SelectCommand.php | 122 - src/Command/SshCommand.php | 114 - src/Command/TreeCommand.php | 180 - src/Command/WorkerCommand.php | 60 - src/Component/PharUpdate/Console/Command.php | 134 - src/Component/PharUpdate/Console/Helper.php | 34 - .../PharUpdate/Exception/Exception.php | 37 - .../Exception/ExceptionInterface.php | 12 - .../PharUpdate/Exception/FileException.php | 12 - .../Exception/InvalidArgumentException.php | 12 - .../PharUpdate/Exception/LogicException.php | 12 - src/Component/PharUpdate/Manager.php | 114 - src/Component/PharUpdate/Manifest.php | 133 - src/Component/PharUpdate/Update.php | 274 - src/Component/PharUpdate/Version/Builder.php | 280 - .../PharUpdate/Version/Comparator.php | 176 - src/Component/PharUpdate/Version/Dumper.php | 54 - .../Exception/InvalidIdentifierException.php | 47 - .../Exception/InvalidNumberException.php | 47 - .../InvalidStringRepresentationException.php | 47 - .../Version/Exception/VersionException.php | 14 - src/Component/PharUpdate/Version/Parser.php | 117 - .../PharUpdate/Version/Validator.php | 59 - src/Component/PharUpdate/Version/Version.php | 141 - src/Component/Pimple/Container.php | 289 - .../Exception/ExpectedInvokableException.php | 20 - .../Exception/FrozenServiceException.php | 29 - .../InvalidServiceIdentifierException.php | 29 - .../Exception/UnknownIdentifierException.php | 29 - src/Component/ProcessRunner/Printer.php | 76 - src/Component/ProcessRunner/ProcessRunner.php | 92 - src/Component/Ssh/Client.php | 130 - src/Component/Ssh/IOArguments.php | 75 - src/Configuration/Configuration.php | 244 - src/Deployer.php | 382 -- src/Documentation/ApiGen.php | 113 - src/Documentation/DocConfig.php | 35 - src/Documentation/DocGen.php | 412 -- src/Documentation/DocRecipe.php | 184 - src/Documentation/DocTask.php | 46 - src/Exception/ConfigurationException.php | 13 - src/Exception/Exception.php | 69 - src/Exception/GracefulShutdownException.php | 27 - src/Exception/HttpieException.php | 13 - src/Exception/RunException.php | 85 - src/Exception/TimeoutException.php | 22 - src/Exception/WillAskUser.php | 19 - src/Executor/Master.php | 291 - src/Executor/Messenger.php | 168 - src/Executor/Planner.php | 70 - src/Executor/Server.php | 115 - src/Executor/Worker.php | 57 - src/Host/Host.php | 315 - src/Host/HostCollection.php | 25 - src/Host/Localhost.php | 19 - src/Host/Range.php | 44 - src/Importer/Importer.php | 267 - src/Logger/Handler/FileHandler.php | 29 - src/Logger/Handler/HandlerInterface.php | 16 - src/Logger/Handler/NullHandler.php | 16 - src/Logger/Logger.php | 59 - src/Selector/Selector.php | 126 - src/Support/ObjectProxy.php | 32 - src/Support/Reporter.php | 47 - src/Support/helpers.php | 261 - src/Task/Context.php | 87 - src/Task/GroupTask.php | 54 - src/Task/ScriptManager.php | 126 - src/Task/Task.php | 275 - src/Task/TaskCollection.php | 30 - src/Utility/Httpie.php | 210 - src/Utility/Rsync.php | 160 - src/functions.php | 982 --- src/schema.json | 140 - tests/bootstrap.php | 41 - tests/fixtures/project/uploaded.html | 0 tests/fixtures/repository/.env | 1 - tests/fixtures/repository/README.md | 3 - tests/fixtures/repository/composer.json | 6 - tests/fixtures/repository/uploads/poem.txt | 12 - tests/joy/HostDefaultConfigTest.php | 36 - tests/joy/JoyTest.php | 77 - tests/joy/OnFuncTest.php | 49 - tests/legacy/AbstractTest.php | 73 - tests/legacy/CurrentPathTest.php | 35 - tests/legacy/DeployTest.php | 144 - tests/legacy/EnvTest.php | 25 - tests/legacy/NamedArgumentsTest.php | 56 - tests/legacy/OncePerNodeTest.php | 25 - tests/legacy/OnceTest.php | 22 - tests/legacy/ParallelTest.php | 114 - tests/legacy/SelectTest.php | 33 - tests/legacy/UpdateCodeTest.php | 33 - tests/legacy/YamlTest.php | 52 - tests/legacy/recipe/deploy.php | 47 - tests/legacy/recipe/deploy.yaml | 27 - tests/legacy/recipe/env.php | 22 - tests/legacy/recipe/named_arguments.php | 22 - tests/legacy/recipe/once.php | 10 - tests/legacy/recipe/once_per_node.php | 16 - tests/legacy/recipe/parallel.php | 48 - tests/legacy/recipe/select.php | 13 - tests/legacy/recipe/update_code.php | 9 - tests/phpstan-baseline.neon | 36 - tests/src/Collection/CollectionTest.php | 52 - tests/src/Command/BlackjackCommandTest.php | 19 - tests/src/Component/Pimple/PimpleTest.php | 592 -- tests/src/Component/Ssh/IOArgumentsTest.php | 34 - tests/src/Configuration/ConfigurationTest.php | 174 - tests/src/DeployerTest.php | 36 - tests/src/FunctionsTest.php | 182 - tests/src/Host/ConfigurationTest.php | 87 - tests/src/Host/HostTest.php | 86 - tests/src/Host/RangeTest.php | 30 - tests/src/Importer/ImporterTest.php | 82 - tests/src/Selector/SelectorTest.php | 32 - tests/src/Support/HelpersTest.php | 67 - tests/src/Support/ObjectProxyTest.php | 27 - tests/src/Task/ContextTest.php | 36 - tests/src/Task/ScriptManagerTest.php | 103 - tests/src/Task/TaskTest.php | 115 - vendor/autoload.php | 7 - vendor/composer/ClassLoader.php | 445 -- vendor/composer/InstalledVersions.php | 476 -- vendor/composer/autoload_classmap.php | 451 -- vendor/composer/autoload_files.php | 23 - vendor/composer/autoload_namespaces.php | 10 - vendor/composer/autoload_psr4.php | 35 - vendor/composer/autoload_real.php | 75 - vendor/composer/autoload_static.php | 645 -- vendor/composer/installed.php | 281 - vendor/composer/platform_check.php | 26 - .../examples/benchmark-emit-no-arguments.php | 28 - .../examples/benchmark-emit-once.php | 30 - .../examples/benchmark-emit-one-argument.php | 28 - .../evenement/examples/benchmark-emit.php | 28 - .../benchmark-remove-listener-once.php | 39 - .../evenement/src/Evenement/EventEmitter.php | 17 - .../src/Evenement/EventEmitterInterface.php | 22 - .../src/Evenement/EventEmitterTrait.php | 135 - .../src/RequestMethodInterface.php | 34 - .../src/StatusCodeInterface.php | 107 - .../justinrainbow/json-schema/demo/demo.php | 18 - .../JsonSchema/Constraints/BaseConstraint.php | 148 - .../Constraints/CollectionConstraint.php | 121 - .../src/JsonSchema/Constraints/Constraint.php | 218 - .../Constraints/ConstraintInterface.php | 65 - .../JsonSchema/Constraints/EnumConstraint.php | 54 - .../src/JsonSchema/Constraints/Factory.php | 220 - .../Constraints/FormatConstraint.php | 214 - .../Constraints/NumberConstraint.php | 81 - .../Constraints/ObjectConstraint.php | 192 - .../Constraints/SchemaConstraint.php | 94 - .../Constraints/StringConstraint.php | 60 - .../Constraints/TypeCheck/LooseTypeCheck.php | 68 - .../Constraints/TypeCheck/StrictTypeCheck.php | 40 - .../TypeCheck/TypeCheckInterface.php | 18 - .../JsonSchema/Constraints/TypeConstraint.php | 261 - .../Constraints/UndefinedConstraint.php | 419 -- .../src/JsonSchema/Entity/JsonPointer.php | 161 - .../Exception/ExceptionInterface.php | 7 - .../Exception/InvalidArgumentException.php | 17 - .../Exception/InvalidConfigException.php | 17 - .../Exception/InvalidSchemaException.php | 17 - .../InvalidSchemaMediaTypeException.php | 17 - .../Exception/InvalidSourceUriException.php | 17 - .../Exception/JsonDecodingException.php | 40 - .../Exception/ResourceNotFoundException.php | 17 - .../JsonSchema/Exception/RuntimeException.php | 17 - .../UnresolvableJsonPointerException.php | 19 - .../Exception/UriResolverException.php | 17 - .../Exception/ValidationException.php | 14 - .../JsonSchema/Iterator/ObjectIterator.php | 149 - .../json-schema/src/JsonSchema/Rfc3339.php | 30 - .../src/JsonSchema/SchemaStorage.php | 169 - .../src/JsonSchema/SchemaStorageInterface.php | 41 - .../Uri/Retrievers/AbstractRetriever.php | 34 - .../src/JsonSchema/Uri/Retrievers/Curl.php | 83 - .../Uri/Retrievers/FileGetContents.php | 93 - .../Uri/Retrievers/PredefinedArray.php | 56 - .../Uri/Retrievers/UriRetrieverInterface.php | 36 - .../src/JsonSchema/Uri/UriResolver.php | 175 - .../src/JsonSchema/Uri/UriRetriever.php | 349 -- .../src/JsonSchema/UriResolverInterface.php | 26 - .../src/JsonSchema/UriRetrieverInterface.php | 26 - .../json-schema/src/JsonSchema/Validator.php | 88 - .../src/ContainerExceptionInterface.php | 10 - .../psr/container/src/ContainerInterface.php | 36 - .../src/NotFoundExceptionInterface.php | 10 - .../psr/http-message/src/MessageInterface.php | 187 - .../psr/http-message/src/RequestInterface.php | 129 - .../http-message/src/ResponseInterface.php | 68 - .../src/ServerRequestInterface.php | 261 - .../psr/http-message/src/StreamInterface.php | 158 - .../src/UploadedFileInterface.php | 123 - vendor/psr/http-message/src/UriInterface.php | 323 - vendor/react/cache/src/ArrayCache.php | 181 - vendor/react/cache/src/CacheInterface.php | 194 - vendor/react/dns/src/BadServerException.php | 7 - vendor/react/dns/src/Config/Config.php | 137 - vendor/react/dns/src/Config/HostsFile.php | 153 - vendor/react/dns/src/Model/Message.php | 230 - vendor/react/dns/src/Model/Record.php | 153 - .../react/dns/src/Protocol/BinaryDumper.php | 199 - vendor/react/dns/src/Protocol/Parser.php | 356 -- .../react/dns/src/Query/CachingExecutor.php | 88 - .../dns/src/Query/CancellationException.php | 7 - vendor/react/dns/src/Query/CoopExecutor.php | 91 - .../react/dns/src/Query/ExecutorInterface.php | 43 - .../react/dns/src/Query/FallbackExecutor.php | 49 - .../react/dns/src/Query/HostsFileExecutor.php | 89 - vendor/react/dns/src/Query/Query.php | 69 - vendor/react/dns/src/Query/RetryExecutor.php | 86 - .../src/Query/SelectiveTransportExecutor.php | 85 - .../dns/src/Query/TcpTransportExecutor.php | 367 -- .../react/dns/src/Query/TimeoutException.php | 7 - .../react/dns/src/Query/TimeoutExecutor.php | 31 - .../dns/src/Query/UdpTransportExecutor.php | 208 - .../react/dns/src/RecordNotFoundException.php | 7 - vendor/react/dns/src/Resolver/Factory.php | 214 - vendor/react/dns/src/Resolver/Resolver.php | 147 - .../dns/src/Resolver/ResolverInterface.php | 94 - vendor/react/event-loop/src/ExtEvLoop.php | 253 - vendor/react/event-loop/src/ExtEventLoop.php | 275 - vendor/react/event-loop/src/ExtLibevLoop.php | 201 - .../react/event-loop/src/ExtLibeventLoop.php | 285 - vendor/react/event-loop/src/ExtUvLoop.php | 342 -- vendor/react/event-loop/src/Factory.php | 75 - vendor/react/event-loop/src/Loop.php | 225 - vendor/react/event-loop/src/LoopInterface.php | 463 -- .../react/event-loop/src/SignalsHandler.php | 63 - .../react/event-loop/src/StreamSelectLoop.php | 308 - .../event-loop/src/Tick/FutureTickQueue.php | 60 - vendor/react/event-loop/src/Timer/Timer.php | 55 - vendor/react/event-loop/src/Timer/Timers.php | 107 - .../react/event-loop/src/TimerInterface.php | 27 - vendor/react/http/src/Browser.php | 790 --- vendor/react/http/src/Client/Client.php | 31 - vendor/react/http/src/Client/Request.php | 237 - vendor/react/http/src/Client/RequestData.php | 128 - vendor/react/http/src/HttpServer.php | 351 -- vendor/react/http/src/Io/BufferedBody.php | 179 - vendor/react/http/src/Io/ChunkedDecoder.php | 175 - vendor/react/http/src/Io/ChunkedEncoder.php | 92 - .../http/src/Io/CloseProtectionStream.php | 111 - vendor/react/http/src/Io/EmptyBodyStream.php | 142 - vendor/react/http/src/Io/HttpBodyStream.php | 182 - vendor/react/http/src/Io/IniUtil.php | 48 - .../react/http/src/Io/LengthLimitedStream.php | 108 - vendor/react/http/src/Io/MiddlewareRunner.php | 61 - vendor/react/http/src/Io/MultipartParser.php | 328 - .../react/http/src/Io/PauseBufferStream.php | 188 - .../react/http/src/Io/ReadableBodyStream.php | 153 - .../react/http/src/Io/RequestHeaderParser.php | 281 - vendor/react/http/src/Io/Sender.php | 160 - vendor/react/http/src/Io/StreamingServer.php | 383 -- vendor/react/http/src/Io/Transaction.php | 303 - vendor/react/http/src/Io/UploadedFile.php | 130 - vendor/react/http/src/Message/Response.php | 291 - .../http/src/Message/ResponseException.php | 43 - .../react/http/src/Message/ServerRequest.php | 197 - .../LimitConcurrentRequestsMiddleware.php | 211 - .../RequestBodyBufferMiddleware.php | 70 - .../RequestBodyParserMiddleware.php | 46 - .../Middleware/StreamingRequestMiddleware.php | 69 - vendor/react/http/src/Server.php | 18 - .../src/UnwrapReadableStream.php | 137 - .../src/UnwrapWritableStream.php | 164 - vendor/react/promise-stream/src/functions.php | 370 -- .../promise-stream/src/functions_include.php | 7 - .../promise-timer/src/TimeoutException.php | 35 - vendor/react/promise-timer/src/functions.php | 335 -- .../promise-timer/src/functions_include.php | 7 - .../src/CancellablePromiseInterface.php | 17 - .../react/promise/src/CancellationQueue.php | 55 - vendor/react/promise/src/Deferred.php | 65 - .../promise/src/Exception/LengthException.php | 7 - .../promise/src/ExtendedPromiseInterface.php | 98 - vendor/react/promise/src/FulfilledPromise.php | 71 - vendor/react/promise/src/LazyPromise.php | 66 - vendor/react/promise/src/Promise.php | 256 - vendor/react/promise/src/PromiseInterface.php | 41 - .../react/promise/src/PromisorInterface.php | 13 - vendor/react/promise/src/RejectedPromise.php | 79 - .../src/UnhandledRejectionException.php | 31 - vendor/react/promise/src/functions.php | 407 -- .../react/promise/src/functions_include.php | 5 - vendor/react/socket/src/Connection.php | 187 - .../react/socket/src/ConnectionInterface.php | 119 - vendor/react/socket/src/Connector.php | 236 - .../react/socket/src/ConnectorInterface.php | 58 - vendor/react/socket/src/DnsConnector.php | 117 - vendor/react/socket/src/FdServer.php | 212 - vendor/react/socket/src/FixedUriConnector.php | 41 - .../src/HappyEyeBallsConnectionBuilder.php | 333 - .../socket/src/HappyEyeBallsConnector.php | 69 - vendor/react/socket/src/LimitingServer.php | 203 - vendor/react/socket/src/SecureConnector.php | 122 - vendor/react/socket/src/SecureServer.php | 206 - vendor/react/socket/src/Server.php | 114 - vendor/react/socket/src/ServerInterface.php | 151 - vendor/react/socket/src/SocketServer.php | 187 - vendor/react/socket/src/StreamEncryption.php | 141 - vendor/react/socket/src/TcpConnector.php | 159 - vendor/react/socket/src/TcpServer.php | 258 - vendor/react/socket/src/TimeoutConnector.php | 51 - vendor/react/socket/src/UnixConnector.php | 51 - vendor/react/socket/src/UnixServer.php | 154 - vendor/react/stream/src/CompositeStream.php | 83 - .../react/stream/src/DuplexResourceStream.php | 227 - .../stream/src/DuplexStreamInterface.php | 39 - .../stream/src/ReadableResourceStream.php | 179 - .../stream/src/ReadableStreamInterface.php | 362 -- vendor/react/stream/src/ThroughStream.php | 190 - vendor/react/stream/src/Util.php | 75 - .../stream/src/WritableResourceStream.php | 168 - .../stream/src/WritableStreamInterface.php | 347 -- vendor/ringcentral/psr7/src/AppendStream.php | 233 - vendor/ringcentral/psr7/src/BufferStream.php | 137 - vendor/ringcentral/psr7/src/CachingStream.php | 135 - .../ringcentral/psr7/src/DroppingStream.php | 41 - vendor/ringcentral/psr7/src/FnStream.php | 163 - vendor/ringcentral/psr7/src/InflateStream.php | 27 - .../ringcentral/psr7/src/LazyOpenStream.php | 39 - vendor/ringcentral/psr7/src/LimitStream.php | 154 - vendor/ringcentral/psr7/src/MessageTrait.php | 167 - .../ringcentral/psr7/src/MultipartStream.php | 152 - vendor/ringcentral/psr7/src/NoSeekStream.php | 21 - vendor/ringcentral/psr7/src/PumpStream.php | 165 - vendor/ringcentral/psr7/src/Request.php | 146 - vendor/ringcentral/psr7/src/Response.php | 129 - vendor/ringcentral/psr7/src/ServerRequest.php | 122 - vendor/ringcentral/psr7/src/Stream.php | 245 - .../psr7/src/StreamDecoratorTrait.php | 139 - vendor/ringcentral/psr7/src/StreamWrapper.php | 121 - vendor/ringcentral/psr7/src/Uri.php | 601 -- vendor/ringcentral/psr7/src/functions.php | 835 --- .../psr7/src/functions_include.php | 6 - vendor/symfony/console/Application.php | 1301 ---- .../symfony/console/Attribute/AsCommand.php | 39 - .../console/CI/GithubActionReporter.php | 99 - vendor/symfony/console/Color.php | 180 - vendor/symfony/console/Command/Command.php | 710 --- .../console/Command/CompleteCommand.php | 205 - .../console/Command/DumpCompletionCommand.php | 139 - .../symfony/console/Command/HelpCommand.php | 101 - .../symfony/console/Command/LazyCommand.php | 218 - .../symfony/console/Command/ListCommand.php | 95 - .../symfony/console/Command/LockableTrait.php | 69 - .../Command/SignalableCommandInterface.php | 30 - .../CommandLoader/CommandLoaderInterface.php | 42 - .../CommandLoader/ContainerCommandLoader.php | 63 - .../CommandLoader/FactoryCommandLoader.php | 62 - .../console/Completion/CompletionInput.php | 249 - .../Completion/CompletionSuggestions.php | 99 - .../Output/BashCompletionOutput.php | 33 - .../Output/CompletionOutputInterface.php | 25 - .../symfony/console/Completion/Suggestion.php | 37 - vendor/symfony/console/ConsoleEvents.php | 72 - vendor/symfony/console/Cursor.php | 207 - .../AddConsoleCommandPass.php | 148 - .../Descriptor/ApplicationDescription.php | 143 - .../symfony/console/Descriptor/Descriptor.php | 94 - .../Descriptor/DescriptorInterface.php | 24 - .../console/Descriptor/JsonDescriptor.php | 181 - .../console/Descriptor/MarkdownDescriptor.php | 206 - .../console/Descriptor/TextDescriptor.php | 341 -- .../console/Descriptor/XmlDescriptor.php | 247 - .../console/Event/ConsoleCommandEvent.php | 51 - .../console/Event/ConsoleErrorEvent.php | 58 - vendor/symfony/console/Event/ConsoleEvent.php | 67 - .../console/Event/ConsoleSignalEvent.php | 35 - .../console/Event/ConsoleTerminateEvent.php | 43 - .../console/EventListener/ErrorListener.php | 95 - .../Exception/CommandNotFoundException.php | 43 - .../console/Exception/ExceptionInterface.php | 21 - .../Exception/InvalidArgumentException.php | 19 - .../Exception/InvalidOptionException.php | 21 - .../console/Exception/LogicException.php | 19 - .../Exception/MissingInputException.php | 21 - .../Exception/NamespaceNotFoundException.php | 21 - .../console/Exception/RuntimeException.php | 19 - .../console/Formatter/NullOutputFormatter.php | 69 - .../Formatter/NullOutputFormatterStyle.php | 66 - .../console/Formatter/OutputFormatter.php | 285 - .../Formatter/OutputFormatterInterface.php | 60 - .../Formatter/OutputFormatterStyle.php | 108 - .../OutputFormatterStyleInterface.php | 52 - .../Formatter/OutputFormatterStyleStack.php | 110 - .../WrappableOutputFormatterInterface.php | 25 - .../console/Helper/DebugFormatterHelper.php | 107 - .../console/Helper/DescriptorHelper.php | 92 - vendor/symfony/console/Helper/Dumper.php | 64 - .../console/Helper/FormatterHelper.php | 92 - vendor/symfony/console/Helper/Helper.php | 180 - .../console/Helper/HelperInterface.php | 39 - vendor/symfony/console/Helper/HelperSet.php | 108 - .../console/Helper/InputAwareHelper.php | 33 - .../symfony/console/Helper/ProcessHelper.php | 144 - vendor/symfony/console/Helper/ProgressBar.php | 609 -- .../console/Helper/ProgressIndicator.php | 249 - .../symfony/console/Helper/QuestionHelper.php | 616 -- .../console/Helper/SymfonyQuestionHelper.php | 109 - vendor/symfony/console/Helper/Table.php | 915 --- vendor/symfony/console/Helper/TableCell.php | 78 - .../symfony/console/Helper/TableCellStyle.php | 89 - vendor/symfony/console/Helper/TableRows.php | 30 - .../symfony/console/Helper/TableSeparator.php | 25 - vendor/symfony/console/Helper/TableStyle.php | 376 -- vendor/symfony/console/Input/ArgvInput.php | 378 -- vendor/symfony/console/Input/ArrayInput.php | 210 - vendor/symfony/console/Input/Input.php | 213 - .../symfony/console/Input/InputArgument.php | 129 - .../console/Input/InputAwareInterface.php | 26 - .../symfony/console/Input/InputDefinition.php | 424 -- .../symfony/console/Input/InputInterface.php | 151 - vendor/symfony/console/Input/InputOption.php | 231 - .../Input/StreamableInputInterface.php | 37 - vendor/symfony/console/Input/StringInput.php | 84 - .../symfony/console/Logger/ConsoleLogger.php | 126 - .../symfony/console/Output/BufferedOutput.php | 45 - .../symfony/console/Output/ConsoleOutput.php | 172 - .../console/Output/ConsoleOutputInterface.php | 32 - .../console/Output/ConsoleSectionOutput.php | 143 - vendor/symfony/console/Output/NullOutput.php | 128 - vendor/symfony/console/Output/Output.php | 174 - .../console/Output/OutputInterface.php | 110 - .../symfony/console/Output/StreamOutput.php | 115 - .../console/Output/TrimmedBufferOutput.php | 63 - .../console/Question/ChoiceQuestion.php | 183 - .../console/Question/ConfirmationQuestion.php | 57 - vendor/symfony/console/Question/Question.php | 299 - .../console/Resources/bin/hiddeninput.exe | Bin 9216 -> 0 bytes .../console/SignalRegistry/SignalRegistry.php | 65 - .../console/SingleCommandApplication.php | 72 - vendor/symfony/console/Style/OutputStyle.php | 153 - .../symfony/console/Style/StyleInterface.php | 132 - vendor/symfony/console/Style/SymfonyStyle.php | 518 -- vendor/symfony/console/Terminal.php | 172 - .../console/Tester/ApplicationTester.php | 85 - .../Tester/CommandCompletionTester.php | 56 - .../symfony/console/Tester/CommandTester.php | 76 - .../Tester/Constraint/CommandIsSuccessful.php | 55 - vendor/symfony/console/Tester/TesterTrait.php | 197 - .../deprecation-contracts/function.php | 27 - vendor/symfony/polyfill-ctype/Ctype.php | 232 - vendor/symfony/polyfill-ctype/bootstrap.php | 50 - vendor/symfony/polyfill-ctype/bootstrap80.php | 46 - .../polyfill-intl-grapheme/Grapheme.php | 247 - .../polyfill-intl-grapheme/bootstrap.php | 58 - .../polyfill-intl-grapheme/bootstrap80.php | 50 - .../polyfill-intl-normalizer/Normalizer.php | 310 - .../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 - vendor/symfony/polyfill-mbstring/Mbstring.php | 873 --- .../Resources/unidata/lowerCase.php | 1397 ----- .../Resources/unidata/titleCaseRegexp.php | 5 - .../Resources/unidata/upperCase.php | 1489 ----- .../symfony/polyfill-mbstring/bootstrap.php | 147 - .../symfony/polyfill-mbstring/bootstrap80.php | 143 - vendor/symfony/polyfill-php73/Php73.php | 43 - .../Resources/stubs/JsonException.php | 16 - vendor/symfony/polyfill-php73/bootstrap.php | 31 - vendor/symfony/polyfill-php80/Php80.php | 115 - vendor/symfony/polyfill-php80/PhpToken.php | 103 - .../Resources/stubs/Attribute.php | 22 - .../Resources/stubs/PhpToken.php | 7 - .../Resources/stubs/Stringable.php | 11 - .../Resources/stubs/UnhandledMatchError.php | 7 - .../Resources/stubs/ValueError.php | 7 - vendor/symfony/polyfill-php80/bootstrap.php | 42 - .../process/Exception/ExceptionInterface.php | 21 - .../Exception/InvalidArgumentException.php | 21 - .../process/Exception/LogicException.php | 21 - .../Exception/ProcessFailedException.php | 54 - .../Exception/ProcessSignaledException.php | 41 - .../Exception/ProcessTimedOutException.php | 69 - .../process/Exception/RuntimeException.php | 21 - vendor/symfony/process/ExecutableFinder.php | 86 - vendor/symfony/process/InputStream.php | 96 - .../symfony/process/PhpExecutableFinder.php | 99 - vendor/symfony/process/PhpProcess.php | 72 - .../symfony/process/Pipes/AbstractPipes.php | 180 - .../symfony/process/Pipes/PipesInterface.php | 61 - vendor/symfony/process/Pipes/UnixPipes.php | 163 - vendor/symfony/process/Pipes/WindowsPipes.php | 204 - vendor/symfony/process/Process.php | 1652 ----- vendor/symfony/process/ProcessUtils.php | 69 - .../service-contracts/Attribute/Required.php | 25 - .../Attribute/SubscribedService.php | 33 - .../service-contracts/ResetInterface.php | 30 - .../service-contracts/ServiceLocatorTrait.php | 128 - .../ServiceProviderInterface.php | 36 - .../ServiceSubscriberInterface.php | 53 - .../ServiceSubscriberTrait.php | 115 - .../Test/ServiceLocatorTest.php | 95 - vendor/symfony/string/AbstractString.php | 795 --- .../symfony/string/AbstractUnicodeString.php | 620 -- vendor/symfony/string/ByteString.php | 506 -- vendor/symfony/string/CodePointString.php | 270 - .../string/Exception/ExceptionInterface.php | 16 - .../Exception/InvalidArgumentException.php | 16 - .../string/Exception/RuntimeException.php | 16 - .../string/Inflector/EnglishInflector.php | 511 -- .../string/Inflector/FrenchInflector.php | 157 - .../string/Inflector/InflectorInterface.php | 33 - vendor/symfony/string/LazyString.php | 164 - .../Resources/data/wcswidth_table_wide.php | 1135 ---- .../Resources/data/wcswidth_table_zero.php | 1375 ----- vendor/symfony/string/Resources/functions.php | 38 - .../symfony/string/Slugger/AsciiSlugger.php | 183 - .../string/Slugger/SluggerInterface.php | 27 - vendor/symfony/string/UnicodeString.php | 377 -- vendor/symfony/yaml/Command/LintCommand.php | 289 - vendor/symfony/yaml/Dumper.php | 140 - vendor/symfony/yaml/Escaper.php | 95 - .../symfony/yaml/Exception/DumpException.php | 21 - .../yaml/Exception/ExceptionInterface.php | 21 - .../symfony/yaml/Exception/ParseException.php | 132 - .../yaml/Exception/RuntimeException.php | 21 - vendor/symfony/yaml/Inline.php | 812 --- vendor/symfony/yaml/Parser.php | 1305 ---- vendor/symfony/yaml/Tag/TaggedValue.php | 38 - vendor/symfony/yaml/Unescaper.php | 132 - vendor/symfony/yaml/Yaml.php | 100 - 649 files changed, 103313 deletions(-) delete mode 100644 .php-cs-fixer.dist.php delete mode 100644 Dockerfile delete mode 100755 bin/build delete mode 100755 bin/docgen delete mode 100644 composer.lock create mode 100755 deployer.phar delete mode 100644 docs/KNOWN_BUGS.md delete mode 100644 docs/UPGRADE.md delete mode 100644 docs/api.md delete mode 100644 docs/avoid-php-fpm-reloading.md delete mode 100644 docs/basics.md delete mode 100755 docs/ci-cd.md delete mode 100755 docs/cli.md delete mode 100644 docs/contrib/README.md delete mode 100644 docs/contrib/bugsnag.md delete mode 100644 docs/contrib/cachetool.md delete mode 100644 docs/contrib/chatwork.md delete mode 100644 docs/contrib/cimonitor.md delete mode 100644 docs/contrib/cloudflare.md delete mode 100644 docs/contrib/cpanel.md delete mode 100644 docs/contrib/crontab.md delete mode 100644 docs/contrib/directadmin.md delete mode 100644 docs/contrib/discord.md delete mode 100644 docs/contrib/grafana.md delete mode 100644 docs/contrib/hangouts.md delete mode 100644 docs/contrib/hipchat.md delete mode 100644 docs/contrib/ispmanager.md delete mode 100644 docs/contrib/mattermost.md delete mode 100644 docs/contrib/ms-teams.md delete mode 100644 docs/contrib/newrelic.md delete mode 100644 docs/contrib/npm.md delete mode 100644 docs/contrib/ntfy.md delete mode 100644 docs/contrib/phinx.md delete mode 100644 docs/contrib/php-fpm.md delete mode 100644 docs/contrib/rabbit.md delete mode 100644 docs/contrib/raygun.md delete mode 100644 docs/contrib/rocketchat.md delete mode 100644 docs/contrib/rollbar.md delete mode 100644 docs/contrib/rsync.md delete mode 100644 docs/contrib/sentry.md delete mode 100644 docs/contrib/slack.md delete mode 100644 docs/contrib/supervisord-monitor.md delete mode 100644 docs/contrib/telegram.md delete mode 100644 docs/contrib/webpack_encore.md delete mode 100644 docs/contrib/workplace.md delete mode 100644 docs/contrib/yammer.md delete mode 100644 docs/contrib/yarn.md delete mode 100755 docs/getting-started.md delete mode 100644 docs/hosts.md delete mode 100755 docs/installation.md delete mode 100644 docs/recipe/README.md delete mode 100644 docs/recipe/cakephp.md delete mode 100644 docs/recipe/codeigniter.md delete mode 100644 docs/recipe/codeigniter4.md delete mode 100644 docs/recipe/common.md delete mode 100644 docs/recipe/composer.md delete mode 100644 docs/recipe/contao.md delete mode 100644 docs/recipe/craftcms.md delete mode 100644 docs/recipe/deploy/check_remote.md delete mode 100644 docs/recipe/deploy/cleanup.md delete mode 100644 docs/recipe/deploy/clear_paths.md delete mode 100644 docs/recipe/deploy/copy_dirs.md delete mode 100644 docs/recipe/deploy/env.md delete mode 100644 docs/recipe/deploy/info.md delete mode 100644 docs/recipe/deploy/lock.md delete mode 100644 docs/recipe/deploy/push.md delete mode 100644 docs/recipe/deploy/release.md delete mode 100644 docs/recipe/deploy/rollback.md delete mode 100644 docs/recipe/deploy/setup.md delete mode 100644 docs/recipe/deploy/shared.md delete mode 100644 docs/recipe/deploy/symlink.md delete mode 100644 docs/recipe/deploy/update_code.md delete mode 100644 docs/recipe/deploy/vendors.md delete mode 100644 docs/recipe/deploy/writable.md delete mode 100644 docs/recipe/drupal7.md delete mode 100644 docs/recipe/drupal8.md delete mode 100644 docs/recipe/flow_framework.md delete mode 100644 docs/recipe/fuelphp.md delete mode 100644 docs/recipe/joomla.md delete mode 100644 docs/recipe/laravel.md delete mode 100644 docs/recipe/magento.md delete mode 100644 docs/recipe/magento2.md delete mode 100644 docs/recipe/pimcore.md delete mode 100644 docs/recipe/prestashop.md delete mode 100644 docs/recipe/provision.md delete mode 100644 docs/recipe/provision/databases.md delete mode 100644 docs/recipe/provision/nodejs.md delete mode 100644 docs/recipe/provision/php.md delete mode 100644 docs/recipe/provision/user.md delete mode 100644 docs/recipe/provision/website.md delete mode 100644 docs/recipe/shopware.md delete mode 100644 docs/recipe/silverstripe.md delete mode 100644 docs/recipe/spiral.md delete mode 100644 docs/recipe/statamic.md delete mode 100644 docs/recipe/sulu.md delete mode 100644 docs/recipe/symfony.md delete mode 100644 docs/recipe/typo3.md delete mode 100644 docs/recipe/wordpress.md delete mode 100644 docs/recipe/yii.md delete mode 100644 docs/recipe/zend_framework.md delete mode 100644 docs/selector.md delete mode 100644 docs/sidebar.js delete mode 100644 docs/tasks.md delete mode 100644 docs/yaml.md delete mode 100644 phpstan.neon delete mode 100644 phpunit.xml delete mode 100644 src/Collection/Collection.php delete mode 100644 src/Command/BlackjackCommand.php delete mode 100644 src/Command/CommandCommon.php delete mode 100644 src/Command/ConfigCommand.php delete mode 100644 src/Command/CustomOption.php delete mode 100644 src/Command/InitCommand.php delete mode 100644 src/Command/MainCommand.php delete mode 100644 src/Command/RunCommand.php delete mode 100644 src/Command/SelectCommand.php delete mode 100644 src/Command/SshCommand.php delete mode 100644 src/Command/TreeCommand.php delete mode 100644 src/Command/WorkerCommand.php delete mode 100644 src/Component/PharUpdate/Console/Command.php delete mode 100644 src/Component/PharUpdate/Console/Helper.php delete mode 100644 src/Component/PharUpdate/Exception/Exception.php delete mode 100644 src/Component/PharUpdate/Exception/ExceptionInterface.php delete mode 100644 src/Component/PharUpdate/Exception/FileException.php delete mode 100644 src/Component/PharUpdate/Exception/InvalidArgumentException.php delete mode 100644 src/Component/PharUpdate/Exception/LogicException.php delete mode 100644 src/Component/PharUpdate/Manager.php delete mode 100644 src/Component/PharUpdate/Manifest.php delete mode 100644 src/Component/PharUpdate/Update.php delete mode 100644 src/Component/PharUpdate/Version/Builder.php delete mode 100644 src/Component/PharUpdate/Version/Comparator.php delete mode 100644 src/Component/PharUpdate/Version/Dumper.php delete mode 100644 src/Component/PharUpdate/Version/Exception/InvalidIdentifierException.php delete mode 100644 src/Component/PharUpdate/Version/Exception/InvalidNumberException.php delete mode 100644 src/Component/PharUpdate/Version/Exception/InvalidStringRepresentationException.php delete mode 100644 src/Component/PharUpdate/Version/Exception/VersionException.php delete mode 100644 src/Component/PharUpdate/Version/Parser.php delete mode 100644 src/Component/PharUpdate/Version/Validator.php delete mode 100644 src/Component/PharUpdate/Version/Version.php delete mode 100644 src/Component/Pimple/Container.php delete mode 100644 src/Component/Pimple/Exception/ExpectedInvokableException.php delete mode 100644 src/Component/Pimple/Exception/FrozenServiceException.php delete mode 100644 src/Component/Pimple/Exception/InvalidServiceIdentifierException.php delete mode 100644 src/Component/Pimple/Exception/UnknownIdentifierException.php delete mode 100644 src/Component/ProcessRunner/Printer.php delete mode 100644 src/Component/ProcessRunner/ProcessRunner.php delete mode 100644 src/Component/Ssh/Client.php delete mode 100644 src/Component/Ssh/IOArguments.php delete mode 100644 src/Configuration/Configuration.php delete mode 100755 src/Deployer.php delete mode 100644 src/Documentation/ApiGen.php delete mode 100644 src/Documentation/DocConfig.php delete mode 100644 src/Documentation/DocGen.php delete mode 100644 src/Documentation/DocRecipe.php delete mode 100644 src/Documentation/DocTask.php delete mode 100644 src/Exception/ConfigurationException.php delete mode 100644 src/Exception/Exception.php delete mode 100644 src/Exception/GracefulShutdownException.php delete mode 100644 src/Exception/HttpieException.php delete mode 100644 src/Exception/RunException.php delete mode 100644 src/Exception/TimeoutException.php delete mode 100644 src/Exception/WillAskUser.php delete mode 100644 src/Executor/Master.php delete mode 100644 src/Executor/Messenger.php delete mode 100644 src/Executor/Planner.php delete mode 100644 src/Executor/Server.php delete mode 100644 src/Executor/Worker.php delete mode 100644 src/Host/Host.php delete mode 100644 src/Host/HostCollection.php delete mode 100644 src/Host/Localhost.php delete mode 100644 src/Host/Range.php delete mode 100644 src/Importer/Importer.php delete mode 100644 src/Logger/Handler/FileHandler.php delete mode 100644 src/Logger/Handler/HandlerInterface.php delete mode 100644 src/Logger/Handler/NullHandler.php delete mode 100644 src/Logger/Logger.php delete mode 100644 src/Selector/Selector.php delete mode 100644 src/Support/ObjectProxy.php delete mode 100644 src/Support/Reporter.php delete mode 100644 src/Support/helpers.php delete mode 100644 src/Task/Context.php delete mode 100644 src/Task/GroupTask.php delete mode 100644 src/Task/ScriptManager.php delete mode 100644 src/Task/Task.php delete mode 100644 src/Task/TaskCollection.php delete mode 100644 src/Utility/Httpie.php delete mode 100644 src/Utility/Rsync.php delete mode 100644 src/functions.php delete mode 100644 src/schema.json delete mode 100644 tests/bootstrap.php delete mode 100644 tests/fixtures/project/uploaded.html delete mode 100644 tests/fixtures/repository/.env delete mode 100644 tests/fixtures/repository/README.md delete mode 100644 tests/fixtures/repository/composer.json delete mode 100644 tests/fixtures/repository/uploads/poem.txt delete mode 100644 tests/joy/HostDefaultConfigTest.php delete mode 100644 tests/joy/JoyTest.php delete mode 100644 tests/joy/OnFuncTest.php delete mode 100644 tests/legacy/AbstractTest.php delete mode 100644 tests/legacy/CurrentPathTest.php delete mode 100644 tests/legacy/DeployTest.php delete mode 100644 tests/legacy/EnvTest.php delete mode 100644 tests/legacy/NamedArgumentsTest.php delete mode 100644 tests/legacy/OncePerNodeTest.php delete mode 100644 tests/legacy/OnceTest.php delete mode 100644 tests/legacy/ParallelTest.php delete mode 100644 tests/legacy/SelectTest.php delete mode 100644 tests/legacy/UpdateCodeTest.php delete mode 100644 tests/legacy/YamlTest.php delete mode 100644 tests/legacy/recipe/deploy.php delete mode 100644 tests/legacy/recipe/deploy.yaml delete mode 100644 tests/legacy/recipe/env.php delete mode 100644 tests/legacy/recipe/named_arguments.php delete mode 100644 tests/legacy/recipe/once.php delete mode 100644 tests/legacy/recipe/once_per_node.php delete mode 100644 tests/legacy/recipe/parallel.php delete mode 100644 tests/legacy/recipe/select.php delete mode 100644 tests/legacy/recipe/update_code.php delete mode 100644 tests/phpstan-baseline.neon delete mode 100644 tests/src/Collection/CollectionTest.php delete mode 100644 tests/src/Command/BlackjackCommandTest.php delete mode 100644 tests/src/Component/Pimple/PimpleTest.php delete mode 100644 tests/src/Component/Ssh/IOArgumentsTest.php delete mode 100644 tests/src/Configuration/ConfigurationTest.php delete mode 100644 tests/src/DeployerTest.php delete mode 100644 tests/src/FunctionsTest.php delete mode 100644 tests/src/Host/ConfigurationTest.php delete mode 100644 tests/src/Host/HostTest.php delete mode 100644 tests/src/Host/RangeTest.php delete mode 100644 tests/src/Importer/ImporterTest.php delete mode 100644 tests/src/Selector/SelectorTest.php delete mode 100644 tests/src/Support/HelpersTest.php delete mode 100644 tests/src/Support/ObjectProxyTest.php delete mode 100644 tests/src/Task/ContextTest.php delete mode 100644 tests/src/Task/ScriptManagerTest.php delete mode 100644 tests/src/Task/TaskTest.php delete mode 100644 vendor/autoload.php delete mode 100644 vendor/composer/ClassLoader.php delete mode 100644 vendor/composer/InstalledVersions.php delete mode 100644 vendor/composer/autoload_classmap.php delete mode 100644 vendor/composer/autoload_files.php delete mode 100644 vendor/composer/autoload_namespaces.php delete mode 100644 vendor/composer/autoload_psr4.php delete mode 100644 vendor/composer/autoload_real.php delete mode 100644 vendor/composer/autoload_static.php delete mode 100644 vendor/composer/installed.php delete mode 100644 vendor/composer/platform_check.php delete mode 100644 vendor/evenement/evenement/examples/benchmark-emit-no-arguments.php delete mode 100644 vendor/evenement/evenement/examples/benchmark-emit-once.php delete mode 100644 vendor/evenement/evenement/examples/benchmark-emit-one-argument.php delete mode 100644 vendor/evenement/evenement/examples/benchmark-emit.php delete mode 100644 vendor/evenement/evenement/examples/benchmark-remove-listener-once.php delete mode 100644 vendor/evenement/evenement/src/Evenement/EventEmitter.php delete mode 100644 vendor/evenement/evenement/src/Evenement/EventEmitterInterface.php delete mode 100644 vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php delete mode 100644 vendor/fig/http-message-util/src/RequestMethodInterface.php delete mode 100644 vendor/fig/http-message-util/src/StatusCodeInterface.php delete mode 100644 vendor/justinrainbow/json-schema/demo/demo.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/LooseTypeCheck.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/StrictTypeCheck.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/TypeCheckInterface.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Entity/JsonPointer.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ExceptionInterface.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidConfigException.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaException.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Exception/RuntimeException.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UnresolvableJsonPointerException.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ValidationException.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Iterator/ObjectIterator.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Rfc3339.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorage.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorageInterface.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/UriResolverInterface.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/UriRetrieverInterface.php delete mode 100644 vendor/justinrainbow/json-schema/src/JsonSchema/Validator.php delete mode 100644 vendor/psr/container/src/ContainerExceptionInterface.php delete mode 100644 vendor/psr/container/src/ContainerInterface.php delete mode 100644 vendor/psr/container/src/NotFoundExceptionInterface.php delete mode 100644 vendor/psr/http-message/src/MessageInterface.php delete mode 100644 vendor/psr/http-message/src/RequestInterface.php delete mode 100644 vendor/psr/http-message/src/ResponseInterface.php delete mode 100644 vendor/psr/http-message/src/ServerRequestInterface.php delete mode 100644 vendor/psr/http-message/src/StreamInterface.php delete mode 100644 vendor/psr/http-message/src/UploadedFileInterface.php delete mode 100644 vendor/psr/http-message/src/UriInterface.php delete mode 100644 vendor/react/cache/src/ArrayCache.php delete mode 100644 vendor/react/cache/src/CacheInterface.php delete mode 100644 vendor/react/dns/src/BadServerException.php delete mode 100644 vendor/react/dns/src/Config/Config.php delete mode 100644 vendor/react/dns/src/Config/HostsFile.php delete mode 100644 vendor/react/dns/src/Model/Message.php delete mode 100644 vendor/react/dns/src/Model/Record.php delete mode 100644 vendor/react/dns/src/Protocol/BinaryDumper.php delete mode 100644 vendor/react/dns/src/Protocol/Parser.php delete mode 100644 vendor/react/dns/src/Query/CachingExecutor.php delete mode 100644 vendor/react/dns/src/Query/CancellationException.php delete mode 100644 vendor/react/dns/src/Query/CoopExecutor.php delete mode 100644 vendor/react/dns/src/Query/ExecutorInterface.php delete mode 100644 vendor/react/dns/src/Query/FallbackExecutor.php delete mode 100644 vendor/react/dns/src/Query/HostsFileExecutor.php delete mode 100644 vendor/react/dns/src/Query/Query.php delete mode 100644 vendor/react/dns/src/Query/RetryExecutor.php delete mode 100644 vendor/react/dns/src/Query/SelectiveTransportExecutor.php delete mode 100644 vendor/react/dns/src/Query/TcpTransportExecutor.php delete mode 100644 vendor/react/dns/src/Query/TimeoutException.php delete mode 100644 vendor/react/dns/src/Query/TimeoutExecutor.php delete mode 100644 vendor/react/dns/src/Query/UdpTransportExecutor.php delete mode 100644 vendor/react/dns/src/RecordNotFoundException.php delete mode 100644 vendor/react/dns/src/Resolver/Factory.php delete mode 100644 vendor/react/dns/src/Resolver/Resolver.php delete mode 100644 vendor/react/dns/src/Resolver/ResolverInterface.php delete mode 100644 vendor/react/event-loop/src/ExtEvLoop.php delete mode 100644 vendor/react/event-loop/src/ExtEventLoop.php delete mode 100644 vendor/react/event-loop/src/ExtLibevLoop.php delete mode 100644 vendor/react/event-loop/src/ExtLibeventLoop.php delete mode 100644 vendor/react/event-loop/src/ExtUvLoop.php delete mode 100644 vendor/react/event-loop/src/Factory.php delete mode 100644 vendor/react/event-loop/src/Loop.php delete mode 100644 vendor/react/event-loop/src/LoopInterface.php delete mode 100644 vendor/react/event-loop/src/SignalsHandler.php delete mode 100644 vendor/react/event-loop/src/StreamSelectLoop.php delete mode 100644 vendor/react/event-loop/src/Tick/FutureTickQueue.php delete mode 100644 vendor/react/event-loop/src/Timer/Timer.php delete mode 100644 vendor/react/event-loop/src/Timer/Timers.php delete mode 100644 vendor/react/event-loop/src/TimerInterface.php delete mode 100644 vendor/react/http/src/Browser.php delete mode 100644 vendor/react/http/src/Client/Client.php delete mode 100644 vendor/react/http/src/Client/Request.php delete mode 100644 vendor/react/http/src/Client/RequestData.php delete mode 100644 vendor/react/http/src/HttpServer.php delete mode 100644 vendor/react/http/src/Io/BufferedBody.php delete mode 100644 vendor/react/http/src/Io/ChunkedDecoder.php delete mode 100644 vendor/react/http/src/Io/ChunkedEncoder.php delete mode 100644 vendor/react/http/src/Io/CloseProtectionStream.php delete mode 100644 vendor/react/http/src/Io/EmptyBodyStream.php delete mode 100644 vendor/react/http/src/Io/HttpBodyStream.php delete mode 100644 vendor/react/http/src/Io/IniUtil.php delete mode 100644 vendor/react/http/src/Io/LengthLimitedStream.php delete mode 100644 vendor/react/http/src/Io/MiddlewareRunner.php delete mode 100644 vendor/react/http/src/Io/MultipartParser.php delete mode 100644 vendor/react/http/src/Io/PauseBufferStream.php delete mode 100644 vendor/react/http/src/Io/ReadableBodyStream.php delete mode 100644 vendor/react/http/src/Io/RequestHeaderParser.php delete mode 100644 vendor/react/http/src/Io/Sender.php delete mode 100644 vendor/react/http/src/Io/StreamingServer.php delete mode 100644 vendor/react/http/src/Io/Transaction.php delete mode 100644 vendor/react/http/src/Io/UploadedFile.php delete mode 100644 vendor/react/http/src/Message/Response.php delete mode 100644 vendor/react/http/src/Message/ResponseException.php delete mode 100644 vendor/react/http/src/Message/ServerRequest.php delete mode 100644 vendor/react/http/src/Middleware/LimitConcurrentRequestsMiddleware.php delete mode 100644 vendor/react/http/src/Middleware/RequestBodyBufferMiddleware.php delete mode 100644 vendor/react/http/src/Middleware/RequestBodyParserMiddleware.php delete mode 100644 vendor/react/http/src/Middleware/StreamingRequestMiddleware.php delete mode 100644 vendor/react/http/src/Server.php delete mode 100644 vendor/react/promise-stream/src/UnwrapReadableStream.php delete mode 100644 vendor/react/promise-stream/src/UnwrapWritableStream.php delete mode 100644 vendor/react/promise-stream/src/functions.php delete mode 100644 vendor/react/promise-stream/src/functions_include.php delete mode 100644 vendor/react/promise-timer/src/TimeoutException.php delete mode 100644 vendor/react/promise-timer/src/functions.php delete mode 100644 vendor/react/promise-timer/src/functions_include.php delete mode 100644 vendor/react/promise/src/CancellablePromiseInterface.php delete mode 100644 vendor/react/promise/src/CancellationQueue.php delete mode 100644 vendor/react/promise/src/Deferred.php delete mode 100644 vendor/react/promise/src/Exception/LengthException.php delete mode 100644 vendor/react/promise/src/ExtendedPromiseInterface.php delete mode 100644 vendor/react/promise/src/FulfilledPromise.php delete mode 100644 vendor/react/promise/src/LazyPromise.php delete mode 100644 vendor/react/promise/src/Promise.php delete mode 100644 vendor/react/promise/src/PromiseInterface.php delete mode 100644 vendor/react/promise/src/PromisorInterface.php delete mode 100644 vendor/react/promise/src/RejectedPromise.php delete mode 100644 vendor/react/promise/src/UnhandledRejectionException.php delete mode 100644 vendor/react/promise/src/functions.php delete mode 100644 vendor/react/promise/src/functions_include.php delete mode 100644 vendor/react/socket/src/Connection.php delete mode 100644 vendor/react/socket/src/ConnectionInterface.php delete mode 100644 vendor/react/socket/src/Connector.php delete mode 100644 vendor/react/socket/src/ConnectorInterface.php delete mode 100644 vendor/react/socket/src/DnsConnector.php delete mode 100644 vendor/react/socket/src/FdServer.php delete mode 100644 vendor/react/socket/src/FixedUriConnector.php delete mode 100644 vendor/react/socket/src/HappyEyeBallsConnectionBuilder.php delete mode 100644 vendor/react/socket/src/HappyEyeBallsConnector.php delete mode 100644 vendor/react/socket/src/LimitingServer.php delete mode 100644 vendor/react/socket/src/SecureConnector.php delete mode 100644 vendor/react/socket/src/SecureServer.php delete mode 100644 vendor/react/socket/src/Server.php delete mode 100644 vendor/react/socket/src/ServerInterface.php delete mode 100644 vendor/react/socket/src/SocketServer.php delete mode 100644 vendor/react/socket/src/StreamEncryption.php delete mode 100644 vendor/react/socket/src/TcpConnector.php delete mode 100644 vendor/react/socket/src/TcpServer.php delete mode 100644 vendor/react/socket/src/TimeoutConnector.php delete mode 100644 vendor/react/socket/src/UnixConnector.php delete mode 100644 vendor/react/socket/src/UnixServer.php delete mode 100644 vendor/react/stream/src/CompositeStream.php delete mode 100644 vendor/react/stream/src/DuplexResourceStream.php delete mode 100644 vendor/react/stream/src/DuplexStreamInterface.php delete mode 100644 vendor/react/stream/src/ReadableResourceStream.php delete mode 100644 vendor/react/stream/src/ReadableStreamInterface.php delete mode 100644 vendor/react/stream/src/ThroughStream.php delete mode 100644 vendor/react/stream/src/Util.php delete mode 100644 vendor/react/stream/src/WritableResourceStream.php delete mode 100644 vendor/react/stream/src/WritableStreamInterface.php delete mode 100644 vendor/ringcentral/psr7/src/AppendStream.php delete mode 100644 vendor/ringcentral/psr7/src/BufferStream.php delete mode 100644 vendor/ringcentral/psr7/src/CachingStream.php delete mode 100644 vendor/ringcentral/psr7/src/DroppingStream.php delete mode 100644 vendor/ringcentral/psr7/src/FnStream.php delete mode 100644 vendor/ringcentral/psr7/src/InflateStream.php delete mode 100644 vendor/ringcentral/psr7/src/LazyOpenStream.php delete mode 100644 vendor/ringcentral/psr7/src/LimitStream.php delete mode 100644 vendor/ringcentral/psr7/src/MessageTrait.php delete mode 100644 vendor/ringcentral/psr7/src/MultipartStream.php delete mode 100644 vendor/ringcentral/psr7/src/NoSeekStream.php delete mode 100644 vendor/ringcentral/psr7/src/PumpStream.php delete mode 100644 vendor/ringcentral/psr7/src/Request.php delete mode 100644 vendor/ringcentral/psr7/src/Response.php delete mode 100644 vendor/ringcentral/psr7/src/ServerRequest.php delete mode 100644 vendor/ringcentral/psr7/src/Stream.php delete mode 100644 vendor/ringcentral/psr7/src/StreamDecoratorTrait.php delete mode 100644 vendor/ringcentral/psr7/src/StreamWrapper.php delete mode 100644 vendor/ringcentral/psr7/src/Uri.php delete mode 100644 vendor/ringcentral/psr7/src/functions.php delete mode 100644 vendor/ringcentral/psr7/src/functions_include.php delete mode 100644 vendor/symfony/console/Application.php delete mode 100644 vendor/symfony/console/Attribute/AsCommand.php delete mode 100644 vendor/symfony/console/CI/GithubActionReporter.php delete mode 100644 vendor/symfony/console/Color.php delete mode 100644 vendor/symfony/console/Command/Command.php delete mode 100644 vendor/symfony/console/Command/CompleteCommand.php delete mode 100644 vendor/symfony/console/Command/DumpCompletionCommand.php delete mode 100644 vendor/symfony/console/Command/HelpCommand.php delete mode 100644 vendor/symfony/console/Command/LazyCommand.php delete mode 100644 vendor/symfony/console/Command/ListCommand.php delete mode 100644 vendor/symfony/console/Command/LockableTrait.php delete mode 100644 vendor/symfony/console/Command/SignalableCommandInterface.php delete mode 100644 vendor/symfony/console/CommandLoader/CommandLoaderInterface.php delete mode 100644 vendor/symfony/console/CommandLoader/ContainerCommandLoader.php delete mode 100644 vendor/symfony/console/CommandLoader/FactoryCommandLoader.php delete mode 100644 vendor/symfony/console/Completion/CompletionInput.php delete mode 100644 vendor/symfony/console/Completion/CompletionSuggestions.php delete mode 100644 vendor/symfony/console/Completion/Output/BashCompletionOutput.php delete mode 100644 vendor/symfony/console/Completion/Output/CompletionOutputInterface.php delete mode 100644 vendor/symfony/console/Completion/Suggestion.php delete mode 100644 vendor/symfony/console/ConsoleEvents.php delete mode 100644 vendor/symfony/console/Cursor.php delete mode 100644 vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php delete mode 100644 vendor/symfony/console/Descriptor/ApplicationDescription.php delete mode 100644 vendor/symfony/console/Descriptor/Descriptor.php delete mode 100644 vendor/symfony/console/Descriptor/DescriptorInterface.php delete mode 100644 vendor/symfony/console/Descriptor/JsonDescriptor.php delete mode 100644 vendor/symfony/console/Descriptor/MarkdownDescriptor.php delete mode 100644 vendor/symfony/console/Descriptor/TextDescriptor.php delete mode 100644 vendor/symfony/console/Descriptor/XmlDescriptor.php delete mode 100644 vendor/symfony/console/Event/ConsoleCommandEvent.php delete mode 100644 vendor/symfony/console/Event/ConsoleErrorEvent.php delete mode 100644 vendor/symfony/console/Event/ConsoleEvent.php delete mode 100644 vendor/symfony/console/Event/ConsoleSignalEvent.php delete mode 100644 vendor/symfony/console/Event/ConsoleTerminateEvent.php delete mode 100644 vendor/symfony/console/EventListener/ErrorListener.php delete mode 100644 vendor/symfony/console/Exception/CommandNotFoundException.php delete mode 100644 vendor/symfony/console/Exception/ExceptionInterface.php delete mode 100644 vendor/symfony/console/Exception/InvalidArgumentException.php delete mode 100644 vendor/symfony/console/Exception/InvalidOptionException.php delete mode 100644 vendor/symfony/console/Exception/LogicException.php delete mode 100644 vendor/symfony/console/Exception/MissingInputException.php delete mode 100644 vendor/symfony/console/Exception/NamespaceNotFoundException.php delete mode 100644 vendor/symfony/console/Exception/RuntimeException.php delete mode 100644 vendor/symfony/console/Formatter/NullOutputFormatter.php delete mode 100644 vendor/symfony/console/Formatter/NullOutputFormatterStyle.php delete mode 100644 vendor/symfony/console/Formatter/OutputFormatter.php delete mode 100644 vendor/symfony/console/Formatter/OutputFormatterInterface.php delete mode 100644 vendor/symfony/console/Formatter/OutputFormatterStyle.php delete mode 100644 vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php delete mode 100644 vendor/symfony/console/Formatter/OutputFormatterStyleStack.php delete mode 100644 vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php delete mode 100644 vendor/symfony/console/Helper/DebugFormatterHelper.php delete mode 100644 vendor/symfony/console/Helper/DescriptorHelper.php delete mode 100644 vendor/symfony/console/Helper/Dumper.php delete mode 100644 vendor/symfony/console/Helper/FormatterHelper.php delete mode 100644 vendor/symfony/console/Helper/Helper.php delete mode 100644 vendor/symfony/console/Helper/HelperInterface.php delete mode 100644 vendor/symfony/console/Helper/HelperSet.php delete mode 100644 vendor/symfony/console/Helper/InputAwareHelper.php delete mode 100644 vendor/symfony/console/Helper/ProcessHelper.php delete mode 100644 vendor/symfony/console/Helper/ProgressBar.php delete mode 100644 vendor/symfony/console/Helper/ProgressIndicator.php delete mode 100644 vendor/symfony/console/Helper/QuestionHelper.php delete mode 100644 vendor/symfony/console/Helper/SymfonyQuestionHelper.php delete mode 100644 vendor/symfony/console/Helper/Table.php delete mode 100644 vendor/symfony/console/Helper/TableCell.php delete mode 100644 vendor/symfony/console/Helper/TableCellStyle.php delete mode 100644 vendor/symfony/console/Helper/TableRows.php delete mode 100644 vendor/symfony/console/Helper/TableSeparator.php delete mode 100644 vendor/symfony/console/Helper/TableStyle.php delete mode 100644 vendor/symfony/console/Input/ArgvInput.php delete mode 100644 vendor/symfony/console/Input/ArrayInput.php delete mode 100644 vendor/symfony/console/Input/Input.php delete mode 100644 vendor/symfony/console/Input/InputArgument.php delete mode 100644 vendor/symfony/console/Input/InputAwareInterface.php delete mode 100644 vendor/symfony/console/Input/InputDefinition.php delete mode 100644 vendor/symfony/console/Input/InputInterface.php delete mode 100644 vendor/symfony/console/Input/InputOption.php delete mode 100644 vendor/symfony/console/Input/StreamableInputInterface.php delete mode 100644 vendor/symfony/console/Input/StringInput.php delete mode 100644 vendor/symfony/console/Logger/ConsoleLogger.php delete mode 100644 vendor/symfony/console/Output/BufferedOutput.php delete mode 100644 vendor/symfony/console/Output/ConsoleOutput.php delete mode 100644 vendor/symfony/console/Output/ConsoleOutputInterface.php delete mode 100644 vendor/symfony/console/Output/ConsoleSectionOutput.php delete mode 100644 vendor/symfony/console/Output/NullOutput.php delete mode 100644 vendor/symfony/console/Output/Output.php delete mode 100644 vendor/symfony/console/Output/OutputInterface.php delete mode 100644 vendor/symfony/console/Output/StreamOutput.php delete mode 100644 vendor/symfony/console/Output/TrimmedBufferOutput.php delete mode 100644 vendor/symfony/console/Question/ChoiceQuestion.php delete mode 100644 vendor/symfony/console/Question/ConfirmationQuestion.php delete mode 100644 vendor/symfony/console/Question/Question.php delete mode 100644 vendor/symfony/console/Resources/bin/hiddeninput.exe delete mode 100644 vendor/symfony/console/SignalRegistry/SignalRegistry.php delete mode 100644 vendor/symfony/console/SingleCommandApplication.php delete mode 100644 vendor/symfony/console/Style/OutputStyle.php delete mode 100644 vendor/symfony/console/Style/StyleInterface.php delete mode 100644 vendor/symfony/console/Style/SymfonyStyle.php delete mode 100644 vendor/symfony/console/Terminal.php delete mode 100644 vendor/symfony/console/Tester/ApplicationTester.php delete mode 100644 vendor/symfony/console/Tester/CommandCompletionTester.php delete mode 100644 vendor/symfony/console/Tester/CommandTester.php delete mode 100644 vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php delete mode 100644 vendor/symfony/console/Tester/TesterTrait.php delete mode 100644 vendor/symfony/deprecation-contracts/function.php delete mode 100644 vendor/symfony/polyfill-ctype/Ctype.php delete mode 100644 vendor/symfony/polyfill-ctype/bootstrap.php delete mode 100644 vendor/symfony/polyfill-ctype/bootstrap80.php delete mode 100644 vendor/symfony/polyfill-intl-grapheme/Grapheme.php delete mode 100644 vendor/symfony/polyfill-intl-grapheme/bootstrap.php delete mode 100644 vendor/symfony/polyfill-intl-grapheme/bootstrap80.php delete mode 100644 vendor/symfony/polyfill-intl-normalizer/Normalizer.php delete mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php delete mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalComposition.php delete mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php delete mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php delete mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php delete mode 100644 vendor/symfony/polyfill-intl-normalizer/bootstrap.php delete mode 100644 vendor/symfony/polyfill-intl-normalizer/bootstrap80.php delete mode 100644 vendor/symfony/polyfill-mbstring/Mbstring.php delete mode 100644 vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php delete mode 100644 vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php delete mode 100644 vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php delete mode 100644 vendor/symfony/polyfill-mbstring/bootstrap.php delete mode 100644 vendor/symfony/polyfill-mbstring/bootstrap80.php delete mode 100644 vendor/symfony/polyfill-php73/Php73.php delete mode 100644 vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php delete mode 100644 vendor/symfony/polyfill-php73/bootstrap.php delete mode 100644 vendor/symfony/polyfill-php80/Php80.php delete mode 100644 vendor/symfony/polyfill-php80/PhpToken.php delete mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php delete mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php delete mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php delete mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php delete mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php delete mode 100644 vendor/symfony/polyfill-php80/bootstrap.php delete mode 100644 vendor/symfony/process/Exception/ExceptionInterface.php delete mode 100644 vendor/symfony/process/Exception/InvalidArgumentException.php delete mode 100644 vendor/symfony/process/Exception/LogicException.php delete mode 100644 vendor/symfony/process/Exception/ProcessFailedException.php delete mode 100644 vendor/symfony/process/Exception/ProcessSignaledException.php delete mode 100644 vendor/symfony/process/Exception/ProcessTimedOutException.php delete mode 100644 vendor/symfony/process/Exception/RuntimeException.php delete mode 100644 vendor/symfony/process/ExecutableFinder.php delete mode 100644 vendor/symfony/process/InputStream.php delete mode 100644 vendor/symfony/process/PhpExecutableFinder.php delete mode 100644 vendor/symfony/process/PhpProcess.php delete mode 100644 vendor/symfony/process/Pipes/AbstractPipes.php delete mode 100644 vendor/symfony/process/Pipes/PipesInterface.php delete mode 100644 vendor/symfony/process/Pipes/UnixPipes.php delete mode 100644 vendor/symfony/process/Pipes/WindowsPipes.php delete mode 100644 vendor/symfony/process/Process.php delete mode 100644 vendor/symfony/process/ProcessUtils.php delete mode 100644 vendor/symfony/service-contracts/Attribute/Required.php delete mode 100644 vendor/symfony/service-contracts/Attribute/SubscribedService.php delete mode 100644 vendor/symfony/service-contracts/ResetInterface.php delete mode 100644 vendor/symfony/service-contracts/ServiceLocatorTrait.php delete mode 100644 vendor/symfony/service-contracts/ServiceProviderInterface.php delete mode 100644 vendor/symfony/service-contracts/ServiceSubscriberInterface.php delete mode 100644 vendor/symfony/service-contracts/ServiceSubscriberTrait.php delete mode 100644 vendor/symfony/service-contracts/Test/ServiceLocatorTest.php delete mode 100644 vendor/symfony/string/AbstractString.php delete mode 100644 vendor/symfony/string/AbstractUnicodeString.php delete mode 100644 vendor/symfony/string/ByteString.php delete mode 100644 vendor/symfony/string/CodePointString.php delete mode 100644 vendor/symfony/string/Exception/ExceptionInterface.php delete mode 100644 vendor/symfony/string/Exception/InvalidArgumentException.php delete mode 100644 vendor/symfony/string/Exception/RuntimeException.php delete mode 100644 vendor/symfony/string/Inflector/EnglishInflector.php delete mode 100644 vendor/symfony/string/Inflector/FrenchInflector.php delete mode 100644 vendor/symfony/string/Inflector/InflectorInterface.php delete mode 100644 vendor/symfony/string/LazyString.php delete mode 100644 vendor/symfony/string/Resources/data/wcswidth_table_wide.php delete mode 100644 vendor/symfony/string/Resources/data/wcswidth_table_zero.php delete mode 100644 vendor/symfony/string/Resources/functions.php delete mode 100644 vendor/symfony/string/Slugger/AsciiSlugger.php delete mode 100644 vendor/symfony/string/Slugger/SluggerInterface.php delete mode 100644 vendor/symfony/string/UnicodeString.php delete mode 100644 vendor/symfony/yaml/Command/LintCommand.php delete mode 100644 vendor/symfony/yaml/Dumper.php delete mode 100644 vendor/symfony/yaml/Escaper.php delete mode 100644 vendor/symfony/yaml/Exception/DumpException.php delete mode 100644 vendor/symfony/yaml/Exception/ExceptionInterface.php delete mode 100644 vendor/symfony/yaml/Exception/ParseException.php delete mode 100644 vendor/symfony/yaml/Exception/RuntimeException.php delete mode 100644 vendor/symfony/yaml/Inline.php delete mode 100644 vendor/symfony/yaml/Parser.php delete mode 100644 vendor/symfony/yaml/Tag/TaggedValue.php delete mode 100644 vendor/symfony/yaml/Unescaper.php delete mode 100644 vendor/symfony/yaml/Yaml.php diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index e05bc14bb..b837821f6 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -33,9 +33,6 @@ jobs: env: VERSION: ${{ inputs.version }} - - name: Build phar - run: php -d phar.readonly=0 bin/build -v"$RELEASE_VERSION" - - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 812ba5e51..c475d0759 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,9 +27,6 @@ jobs: env: VERSION: ${{ inputs.version }} - - name: Build phar - run: php -d phar.readonly=0 bin/build -v"$RELEASE_VERSION" - - name: Sign phar run: | mkdir -p ~/.gnupg/ diff --git a/.gitignore b/.gitignore index 3efdc55eb..00700065b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -deployer.phar .phpunit.result.cache docker-compose.override.yml .php-cs-fixer.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php deleted file mode 100644 index 1a7f83995..000000000 --- a/.php-cs-fixer.dist.php +++ /dev/null @@ -1,13 +0,0 @@ -in(__DIR__ . '/src') - ->in(__DIR__ . '/recipe') - ->in(__DIR__ . '/contrib') - ->in(__DIR__ . '/tests'); - -return (new PhpCsFixer\Config()) - ->setRules([ - '@PER-CS' => true, - ]) - ->setFinder($finder); diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index f4c3c1242..000000000 --- a/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM php:8.3-cli-alpine - -RUN apk add --no-cache bash git openssh-client rsync - -COPY deployer.phar /bin/deployer.phar - -WORKDIR /app - -ENTRYPOINT ["php", "/bin/deployer.phar"] diff --git a/bin/build b/bin/build deleted file mode 100755 index 72d1546c3..000000000 --- a/bin/build +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env php - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -if (ini_get('phar.readonly') === '1') { - throw new \Exception('Writing to phar files is disabled. Change your `php.ini` or append `-d phar.readonly=false` to the shebang, if supported by your `env` executable.'); -} - -define('__ROOT__', realpath(__DIR__ . '/..')); -chdir(__ROOT__); - -$opt = getopt('v:', ['nozip']); - -$version = $opt['v'] ?? null; -if (empty($version)) { - echo "Please, specify version as \"-v8.0.0\".\n"; - exit(1); -} -if (!preg_match('/^\d+\.\d+\.\d+(\-\w+(\.\d+)?)?$/', $version)) { - echo "Version must be \"7.0.0-beta.42\". Got \"$version\".\n"; - exit(1); -} - -$pharName = "deployer.phar"; -$pharFile = __ROOT__ . '/' . $pharName; -if (file_exists($pharFile)) { - unlink($pharFile); -} - -$ignore = [ - '.anton', - '.git', - 'Tests', - 'tests', - 'deploy.php', - '.php-cs-fixer.dist.php', -]; - -$phar = new \Phar($pharFile, 0, $pharName); -$phar->setSignatureAlgorithm(\Phar::SHA1); -$phar->startBuffering(); -$iterator = new RecursiveDirectoryIterator(__ROOT__, FilesystemIterator::SKIP_DOTS); -$iterator = new RecursiveCallbackFilterIterator($iterator, function (SplFileInfo $fileInfo) use ($ignore) { - return !in_array($fileInfo->getBasename(), $ignore, true); -}); -$iterator = new RecursiveIteratorIterator($iterator); -$iterator = new CallbackFilterIterator($iterator, function (SplFileInfo $fileInfo) { - //'bash', 'fish', 'zsh' is a completion templates - return in_array($fileInfo->getExtension(), ['php', 'exe', 'bash', 'fish', 'zsh'], true); -}); - -foreach ($iterator as $fileInfo) { - $file = str_replace(__ROOT__, '', $fileInfo->getRealPath()); - echo "+ " . $file . "\n"; - $phar->addFile($fileInfo->getRealPath(), $file); - - if (!array_key_exists('nozip', $opt)) { - $phar[$file]->compress(Phar::GZ); - - if (!$phar[$file]->isCompressed()) { - echo "Could not compress File: $file\n"; - } - } -} - -// Add schema.json -echo "+ /src/schema.json\n"; -$phar->addFile(realpath(__DIR__ . '/../src/schema.json'), '/src/schema.json'); - -// Add Caddyfile -echo "+ /recipe/provision/Caddyfile\n"; -$phar->addFile(realpath(__DIR__ . '/../recipe/provision/Caddyfile'), '/recipe/provision/Caddyfile'); - -// Add 404.html -echo "+ /recipe/provision/404.html\n"; -$phar->addFile(realpath(__DIR__ . '/../recipe/provision/404.html'), '/recipe/provision/404.html'); - -// Add bin/dep file -echo "+ /bin/dep\n"; -$depContent = file_get_contents(__ROOT__ . '/bin/dep'); -$depContent = str_replace("#!/usr/bin/env php\n", '', $depContent); -$depContent = str_replace('__FILE__', 'str_replace("phar://", "", Phar::running())', $depContent); -$depContent = preg_replace("/run\('.+?'/", "run('$version'", $depContent); -$phar->addFromString('bin/dep', $depContent); - -$phar->setStub( - <<stopBuffering(); -unset($phar); - -echo "$pharName was created successfully.\n"; diff --git a/bin/dep b/bin/dep index 2bfa43b83b1072b9e88f5a1af67ab228ee0de5bb..31e8c048225f7188f7b85a45fec0d6e37067a973 100755 GIT binary patch literal 792695 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

)gT35IfK@W(q#vq`ZxnS9Zg-A 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%0D6gLu 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

}l0P4LMC&|b7wGjS}lD-5>%Ry>2L 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�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

%D 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⁢0VbAH$D7!b0efoL;D?(!HPnoP(i6iU0lDA5bzLhRnQR;h{%6!c@tE_7F@$EH>F}D$=+OfM_Z*#^gc76SJ ziY27^1k$A7jbW)46{|G6-LY-Si^6GIeoTtSM44BH=Wz5klS#(5T*6Gdwc-*celhlJ z7gzH)S1i$a4j;=ok zwioT2U}gNx^XJc}XHP8ex<2;nW-PCjnlWCMd>4}f`sQCzB9@S*uo~fl+B^A-NyD~MDJFnTa(L^3B@+Ze(z%r;BYk16 z4MuBdX+Bi}q znP!o5eD@ryQg0%5(v>xQazKU8g7bW_9+#a5e+louX-slFmlv#C>z@SyF9*<*gb&Impr4M791&PvN34%hM zr<9r$xxKV`B05%eFED{;*hK6({?aZdKMU*LcQ^!Ji=kupy>cxC~f#R7}asB%JPj7!9owbj|8nG{BGIBynG{Mv6V6Q4TWUwfV zkE8?U=0_`;bLEfSbp->b2q1`ct5dfK3^zhl@fD@K=kVFYB&b-u5dnAZe6{IKcm_ia zvb08Zh`wj+q7=O znhNPJwFJemd#+^4K9Pn2*?*ojLe5OUjqKd$%CK8r0W_8yHhjmF)^|Aa2Au(&R>?a; z7l1A;bR&4TuB;y#l~fzTB7dYJIwkZ) zN+(<`$l!>*IA@XXCJM2Mnsw85U&|)Fqx9)vcyLFgxrToQe9Fl=q2w9q7~-}D;ZppG zYn|2+Tw)BkMQs0#7*p6f0S;jJXhVdoleR>2;_4kF9VYgyE4axj25?zDl&02RoukQ0 zI2fhT%kyCgpbD=zCApCsaWYJrl_RnyY4602SkmV-oZ#Dl0z6V=C9i~|vy9&hV#Eqv zr(8iM2xeSM_x|DQ< zoEcM8r}Oz5=&x^2kmK``@CE?StwqPQ?rZun?dP=J&R2W(F_BUFc@Q53R@%S#ir{NUhXtPe)54f}^ww4YFwDsH4)sr# zC@di^0gr9p;^J|jl#XcV9JWzL2m^Z};@$(PhEZ*GB#VF?wVRFgZ-hjm8{z2N*U*%W zvd*5h)g84;Z9Rg!pa=0 zfGdJy3*qDrftcB{VVSy76Xb2CTy$<pJ|(k?lZx-xom=(Pcaw|^;h-5tWxDBK8(1{qo^ zI_)TWy0@hLD^kZn2X0FH-CQH{%3^-lH2)TYW*g?g;+H*cbhJ2FVry3Dpu;2qXj>h4 z39@{s#F{5N_WJeD@7TBO?Q$i+tX6G*zW&He8b2F#8p)P z+rl24gke|dr&GI^ySLDXPB{MRrrC5MzR1c{apc%w;jViNkyC+Q*tSPU(`iSZKI?hg zcifD7KaMWLJ;-v0ceLvxU5|w}%=YbZ8=jZbXnICZKCh@DztC_2IOEMa#|1YS@Ng7< z#mc5q*~~A@uG5=Yip0M3fWdCj<=hc^JM*}rLL_JlzWdvYUYq2ha;JvIKwU2T40Puct#=s48m z13bD1$EO}i#~5;w>_7FQU|jT{R{LnQ$vuKbOO%KHDG^8C6Bqg0TvOF8?88CZU483e z`;3t$4piL%qcyAhLfdm`-}R$F1V7vNn|Q!DXg??PZy%z;iS6-+-njAg#7ivDsxEXf zB!}a3w+xs@;Uqwl)>)%-)FyB~QV&+s^E7Kx?N*Sj?ybze=Jp<<(5WTl36EHJ)Q*W(Q)-l&VY~~Bg0@o1Hm4%dsehc2H}60 z9olk_fM;D_%o-PsT4H5=dAs>g=k(grLVj;OeNhMH^iK(9U(0mO?QJTrz9hd#<;4 zgQy#cp%e>Uu(KigodB)Ih&7SJK(_A1n4e2hwe*SyQ81fPJ=Ph|UAALo%z_e>mojg2 zBWqX#w-WZ`VuOgt%K`#HQ9Pi_@^OoOe)-akh1sBCZne)XmXKAXsL?h8hL9GcQJO

LlKxzkEWa-_P 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 delta 51 zcmeyq!QhMN1j+4jygbER9P#mPo<6Se@zei^^LUEqCKi{Z7OCqfsHCJ8 - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Deployer\Documentation\ApiGen; -use Deployer\Documentation\DocGen; -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Output\ConsoleOutput; - -require __DIR__ . '/../vendor/autoload.php'; - -chdir(realpath(__DIR__ . '/..')); - -$input = new ArgvInput(); -$output = new ConsoleOutput(); -$app = new Application('DocGen', '1.0.0'); -$app->setDefaultCommand('all'); - -$api = function () use ($output) { - $parser = new ApiGen(); - $parser->parse(file_get_contents(__DIR__ . '/../src/functions.php')); - $md = $parser->markdown(); - file_put_contents(__DIR__ . '/../docs/api.md', $md); - $output->writeln('API Reference documentation updated.'); -}; - -$recipes = function () use ($input, $output) { - $docgen = new DocGen(__DIR__ . '/..'); - $docgen->parse(__DIR__ . '/../recipe'); - $docgen->parse(__DIR__ . '/../contrib'); - - if ($input->getOption('json')) { - echo json_encode($docgen->recipes, JSON_PRETTY_PRINT); - return; - } - - $docgen->gen(__DIR__ . '/../docs'); - $output->writeln('Recipes documentation updated.'); -}; - -$app->register('api')->setCode($api); -$app->register('recipes')->setCode($recipes)->addOption('json'); -$app->register('all')->setCode(function () use ($recipes, $api) { - $api(); - $recipes(); - echo `git status`; -})->addOption('json'); - -$app->run($input, $output); diff --git a/composer.json b/composer.json index 50e6b2201..517e4ce7b 100644 --- a/composer.json +++ b/composer.json @@ -20,44 +20,11 @@ "url": "https://github.com/sponsors/antonmedv" } ], - "autoload": { - "psr-4": { - "Deployer\\": "src/" - }, - "files": [ - "vendor/autoload.php", - "src/Support/helpers.php", - "src/functions.php" - ] - }, - "scripts": { - "test": "pest", - "test:e2e": "pest --config tests/e2e/phpunit-e2e.xml", - "check": "php-cs-fixer check", - "fix": "php-cs-fixer fix", - "phpstan": "phpstan analyse -c phpstan.neon --memory-limit 1G", - "phpstan:baseline": "@phpstan --generate-baseline tests/phpstan-baseline.neon" - }, "bin": [ "bin/dep" ], "require": { "php": "^8.0|^7.3", "ext-json": "*" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.64", - "pestphp/pest": "^3.3", - "phpstan/phpstan": "^1.4", - "phpunit/php-code-coverage": "^11.0", - "phpunit/phpunit": "^11.4" - }, - "config": { - "sort-packages": true, - "process-timeout": 0, - "allow-plugins": { - "pestphp/pest-plugin": true, - "dealerdirect/phpcodesniffer-composer-installer": true - } } } diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 55eab858c..000000000 --- a/composer.lock +++ /dev/null @@ -1,5345 +0,0 @@ -{ - "_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": "590c5d88b1f7bf2c252e807ad78087b5", - "packages": [], - "packages-dev": [ - { - "name": "brianium/paratest", - "version": "v7.5.7", - "source": { - "type": "git", - "url": "https://github.com/paratestphp/paratest.git", - "reference": "4890b17f569efea5e034e519dc883da53a67448d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/4890b17f569efea5e034e519dc883da53a67448d", - "reference": "4890b17f569efea5e034e519dc883da53a67448d", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-simplexml": "*", - "fidry/cpu-core-counter": "^1.2.0", - "jean85/pretty-package-versions": "^2.0.6", - "php": "~8.2.0 || ~8.3.0", - "phpunit/php-code-coverage": "^11.0.6", - "phpunit/php-file-iterator": "^5.1.0", - "phpunit/php-timer": "^7.0.1", - "phpunit/phpunit": "^11.4.0", - "sebastian/environment": "^7.2.0", - "symfony/console": "^6.4.11 || ^7.1.5", - "symfony/process": "^6.4.8 || ^7.1.5" - }, - "require-dev": { - "doctrine/coding-standard": "^12.0.0", - "ext-pcov": "*", - "ext-posix": "*", - "infection/infection": "^0.29.7", - "phpstan/phpstan": "^1.12.6", - "phpstan/phpstan-deprecation-rules": "^1.2.1", - "phpstan/phpstan-phpunit": "^1.4.0", - "phpstan/phpstan-strict-rules": "^1.6.1", - "squizlabs/php_codesniffer": "^3.10.3", - "symfony/filesystem": "^6.4.9 || ^7.1.5" - }, - "bin": [ - "bin/paratest", - "bin/paratest_for_phpstorm" - ], - "type": "library", - "autoload": { - "psr-4": { - "ParaTest\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Brian Scaturro", - "email": "scaturrob@gmail.com", - "role": "Developer" - }, - { - "name": "Filippo Tessarotto", - "email": "zoeslam@gmail.com", - "role": "Developer" - } - ], - "description": "Parallel testing for PHP", - "homepage": "https://github.com/paratestphp/paratest", - "keywords": [ - "concurrent", - "parallel", - "phpunit", - "testing" - ], - "support": { - "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v7.5.7" - }, - "funding": [ - { - "url": "https://github.com/sponsors/Slamdunk", - "type": "github" - }, - { - "url": "https://paypal.me/filippotessarotto", - "type": "paypal" - } - ], - "time": "2024-10-07T06:27:54+00:00" - }, - { - "name": "clue/ndjson-react", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/clue/reactphp-ndjson.git", - "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", - "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", - "shasum": "" - }, - "require": { - "php": ">=5.3", - "react/stream": "^1.2" - }, - "require-dev": { - "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", - "react/event-loop": "^1.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Clue\\React\\NDJson\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering" - } - ], - "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", - "homepage": "https://github.com/clue/reactphp-ndjson", - "keywords": [ - "NDJSON", - "json", - "jsonlines", - "newline", - "reactphp", - "streaming" - ], - "support": { - "issues": "https://github.com/clue/reactphp-ndjson/issues", - "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" - }, - "funding": [ - { - "url": "https://clue.engineering/support", - "type": "custom" - }, - { - "url": "https://github.com/clue", - "type": "github" - } - ], - "time": "2022-12-23T10:58:28+00:00" - }, - { - "name": "composer/pcre", - "version": "3.3.1", - "source": { - "type": "git", - "url": "https://github.com/composer/pcre.git", - "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/63aaeac21d7e775ff9bc9d45021e1745c97521c4", - "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<1.11.10" - }, - "require-dev": { - "phpstan/phpstan": "^1.11.10", - "phpstan/phpstan-strict-rules": "^1.1", - "phpunit/phpunit": "^8 || ^9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - }, - "phpstan": { - "includes": [ - "extension.neon" - ] - } - }, - "autoload": { - "psr-4": { - "Composer\\Pcre\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "PCRE wrapping library that offers type-safe preg_* replacements.", - "keywords": [ - "PCRE", - "preg", - "regex", - "regular expression" - ], - "support": { - "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.3.1" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2024-08-27T18:44:43+00:00" - }, - { - "name": "composer/semver", - "version": "3.4.3", - "source": { - "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", - "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.11", - "symfony/phpunit-bridge": "^3 || ^7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", - "keywords": [ - "semantic", - "semver", - "validation", - "versioning" - ], - "support": { - "irc": "ircs://irc.libera.chat:6697/composer", - "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.3" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2024-09-19T14:15:21+00:00" - }, - { - "name": "composer/xdebug-handler", - "version": "3.0.5", - "source": { - "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", - "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", - "shasum": "" - }, - "require": { - "composer/pcre": "^1 || ^2 || ^3", - "php": "^7.2.5 || ^8.0", - "psr/log": "^1 || ^2 || ^3" - }, - "require-dev": { - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-strict-rules": "^1.1", - "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Composer\\XdebugHandler\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" - } - ], - "description": "Restarts a process without Xdebug.", - "keywords": [ - "Xdebug", - "performance" - ], - "support": { - "irc": "ircs://irc.libera.chat:6697/composer", - "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2024-05-06T16:37:16+00:00" - }, - { - "name": "doctrine/deprecations", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/doctrine/deprecations.git", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "1.4.10 || 1.10.15", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "0.18.4", - "psr/log": "^1 || ^2 || ^3", - "vimeo/psalm": "4.30.0 || 5.12.0" - }, - "suggest": { - "psr/log": "Allows logging deprecations via PSR-3 logger implementation" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", - "homepage": "https://www.doctrine-project.org/", - "support": { - "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.3" - }, - "time": "2024-01-30T19:34:25+00:00" - }, - { - "name": "evenement/evenement", - "version": "v3.0.2", - "source": { - "type": "git", - "url": "https://github.com/igorw/evenement.git", - "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", - "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "require-dev": { - "phpunit/phpunit": "^9 || ^6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Evenement\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch" - } - ], - "description": "Événement is a very simple event dispatching library for PHP", - "keywords": [ - "event-dispatcher", - "event-emitter" - ], - "support": { - "issues": "https://github.com/igorw/evenement/issues", - "source": "https://github.com/igorw/evenement/tree/v3.0.2" - }, - "time": "2023-08-08T05:53:35+00:00" - }, - { - "name": "fidry/cpu-core-counter", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "8520451a140d3f46ac33042715115e290cf5785f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", - "reference": "8520451a140d3f46ac33042715115e290cf5785f", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "fidry/makefile": "^0.2.0", - "fidry/php-cs-fixer-config": "^1.1.2", - "phpstan/extension-installer": "^1.2.0", - "phpstan/phpstan": "^1.9.2", - "phpstan/phpstan-deprecation-rules": "^1.0.0", - "phpstan/phpstan-phpunit": "^1.2.2", - "phpstan/phpstan-strict-rules": "^1.4.4", - "phpunit/phpunit": "^8.5.31 || ^9.5.26", - "webmozarts/strict-phpunit": "^7.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Fidry\\CpuCoreCounter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Théo FIDRY", - "email": "theo.fidry@gmail.com" - } - ], - "description": "Tiny utility to get the number of CPU cores.", - "keywords": [ - "CPU", - "core" - ], - "support": { - "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" - }, - "funding": [ - { - "url": "https://github.com/theofidry", - "type": "github" - } - ], - "time": "2024-08-06T10:04:20+00:00" - }, - { - "name": "filp/whoops", - "version": "2.16.0", - "source": { - "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "befcdc0e5dce67252aa6322d82424be928214fa2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/befcdc0e5dce67252aa6322d82424be928214fa2", - "reference": "befcdc0e5dce67252aa6322d82424be928214fa2", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0", - "psr/log": "^1.0.1 || ^2.0 || ^3.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", - "symfony/var-dumper": "^4.0 || ^5.0" - }, - "suggest": { - "symfony/var-dumper": "Pretty print complex values better with var-dumper available", - "whoops/soap": "Formats errors as SOAP responses" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Whoops\\": "src/Whoops/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Filipe Dobreira", - "homepage": "https://github.com/filp", - "role": "Developer" - } - ], - "description": "php error handling for cool kids", - "homepage": "https://filp.github.io/whoops/", - "keywords": [ - "error", - "exception", - "handling", - "library", - "throwable", - "whoops" - ], - "support": { - "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.16.0" - }, - "funding": [ - { - "url": "https://github.com/denis-sokolov", - "type": "github" - } - ], - "time": "2024-09-25T12:00:00+00:00" - }, - { - "name": "friendsofphp/php-cs-fixer", - "version": "v3.64.0", - "source": { - "type": "git", - "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "58dd9c931c785a79739310aef5178928305ffa67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/58dd9c931c785a79739310aef5178928305ffa67", - "reference": "58dd9c931c785a79739310aef5178928305ffa67", - "shasum": "" - }, - "require": { - "clue/ndjson-react": "^1.0", - "composer/semver": "^3.4", - "composer/xdebug-handler": "^3.0.3", - "ext-filter": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "fidry/cpu-core-counter": "^1.0", - "php": "^7.4 || ^8.0", - "react/child-process": "^0.6.5", - "react/event-loop": "^1.0", - "react/promise": "^2.0 || ^3.0", - "react/socket": "^1.0", - "react/stream": "^1.0", - "sebastian/diff": "^4.0 || ^5.0 || ^6.0", - "symfony/console": "^5.4 || ^6.0 || ^7.0", - "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", - "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", - "symfony/finder": "^5.4 || ^6.0 || ^7.0", - "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", - "symfony/polyfill-mbstring": "^1.28", - "symfony/polyfill-php80": "^1.28", - "symfony/polyfill-php81": "^1.28", - "symfony/process": "^5.4 || ^6.0 || ^7.0", - "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" - }, - "require-dev": { - "facile-it/paraunit": "^1.3 || ^2.3", - "infection/infection": "^0.29.5", - "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^2.1", - "mikey179/vfsstream": "^1.6.11", - "php-coveralls/php-coveralls": "^2.7", - "php-cs-fixer/accessible-object": "^1.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5", - "phpunit/phpunit": "^9.6.19 || ^10.5.21 || ^11.2", - "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", - "symfony/yaml": "^5.4 || ^6.0 || ^7.0" - }, - "suggest": { - "ext-dom": "For handling output formats in XML", - "ext-mbstring": "For handling non-UTF8 characters." - }, - "bin": [ - "php-cs-fixer" - ], - "type": "application", - "autoload": { - "psr-4": { - "PhpCsFixer\\": "src/" - }, - "exclude-from-classmap": [ - "src/Fixer/Internal/*" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" - } - ], - "description": "A tool to automatically fix PHP code style", - "keywords": [ - "Static code analysis", - "fixer", - "standards", - "static analysis" - ], - "support": { - "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.64.0" - }, - "funding": [ - { - "url": "https://github.com/keradus", - "type": "github" - } - ], - "time": "2024-08-30T23:09:38+00:00" - }, - { - "name": "jean85/pretty-package-versions", - "version": "2.0.6", - "source": { - "type": "git", - "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/f9fdd29ad8e6d024f52678b570e5593759b550b4", - "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.0.0", - "php": "^7.1|^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.2", - "jean85/composer-provided-replaced-stub-package": "^1.0", - "phpstan/phpstan": "^1.4", - "phpunit/phpunit": "^7.5|^8.5|^9.4", - "vimeo/psalm": "^4.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Jean85\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alessandro Lai", - "email": "alessandro.lai85@gmail.com" - } - ], - "description": "A library to get pretty versions strings of installed dependencies", - "keywords": [ - "composer", - "package", - "release", - "versions" - ], - "support": { - "issues": "https://github.com/Jean85/pretty-package-versions/issues", - "source": "https://github.com/Jean85/pretty-package-versions/tree/2.0.6" - }, - "time": "2024-03-08T09:58:59+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.12.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3 <3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpspec/prophecy": "^1.10", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2024-06-12T14:39:25+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v5.3.1", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", - "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "php": ">=7.4" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" - }, - "time": "2024-10-08T18:51:32+00:00" - }, - { - "name": "nunomaduro/collision", - "version": "v8.4.0", - "source": { - "type": "git", - "url": "https://github.com/nunomaduro/collision.git", - "reference": "e7d1aa8ed753f63fa816932bbc89678238843b4a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/e7d1aa8ed753f63fa816932bbc89678238843b4a", - "reference": "e7d1aa8ed753f63fa816932bbc89678238843b4a", - "shasum": "" - }, - "require": { - "filp/whoops": "^2.15.4", - "nunomaduro/termwind": "^2.0.1", - "php": "^8.2.0", - "symfony/console": "^7.1.3" - }, - "conflict": { - "laravel/framework": "<11.0.0 || >=12.0.0", - "phpunit/phpunit": "<10.5.1 || >=12.0.0" - }, - "require-dev": { - "larastan/larastan": "^2.9.8", - "laravel/framework": "^11.19.0", - "laravel/pint": "^1.17.1", - "laravel/sail": "^1.31.0", - "laravel/sanctum": "^4.0.2", - "laravel/tinker": "^2.9.0", - "orchestra/testbench-core": "^9.2.3", - "pestphp/pest": "^2.35.0 || ^3.0.0", - "sebastian/environment": "^6.1.0 || ^7.0.0" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" - ] - }, - "branch-alias": { - "dev-8.x": "8.x-dev" - } - }, - "autoload": { - "files": [ - "./src/Adapters/Phpunit/Autoload.php" - ], - "psr-4": { - "NunoMaduro\\Collision\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "Cli error handling for console/command-line PHP applications.", - "keywords": [ - "artisan", - "cli", - "command-line", - "console", - "error", - "handling", - "laravel", - "laravel-zero", - "php", - "symfony" - ], - "support": { - "issues": "https://github.com/nunomaduro/collision/issues", - "source": "https://github.com/nunomaduro/collision" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" - } - ], - "time": "2024-08-03T15:32:23+00:00" - }, - { - "name": "nunomaduro/termwind", - "version": "v2.1.0", - "source": { - "type": "git", - "url": "https://github.com/nunomaduro/termwind.git", - "reference": "e5f21eade88689536c0cdad4c3cd75f3ed26e01a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/e5f21eade88689536c0cdad4c3cd75f3ed26e01a", - "reference": "e5f21eade88689536c0cdad4c3cd75f3ed26e01a", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": "^8.2", - "symfony/console": "^7.0.4" - }, - "require-dev": { - "ergebnis/phpstan-rules": "^2.2.0", - "illuminate/console": "^11.1.1", - "laravel/pint": "^1.15.0", - "mockery/mockery": "^1.6.11", - "pestphp/pest": "^2.34.6", - "phpstan/phpstan": "^1.10.66", - "phpstan/phpstan-strict-rules": "^1.5.2", - "symfony/var-dumper": "^7.0.4", - "thecodingmachine/phpstan-strict-rules": "^1.0.0" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Termwind\\Laravel\\TermwindServiceProvider" - ] - }, - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "files": [ - "src/Functions.php" - ], - "psr-4": { - "Termwind\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "Its like Tailwind CSS, but for the console.", - "keywords": [ - "cli", - "console", - "css", - "package", - "php", - "style" - ], - "support": { - "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v2.1.0" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://github.com/xiCO2k", - "type": "github" - } - ], - "time": "2024-09-05T15:25:50+00:00" - }, - { - "name": "pestphp/pest", - "version": "v3.3.2", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest.git", - "reference": "1513ede73b150b8bcf9def90486e85ecc2bac4e1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/1513ede73b150b8bcf9def90486e85ecc2bac4e1", - "reference": "1513ede73b150b8bcf9def90486e85ecc2bac4e1", - "shasum": "" - }, - "require": { - "brianium/paratest": "^7.5.7", - "nunomaduro/collision": "^8.4.0", - "nunomaduro/termwind": "^2.1.0", - "pestphp/pest-plugin": "^3.0.0", - "pestphp/pest-plugin-arch": "^3.0.0", - "pestphp/pest-plugin-mutate": "^3.0.5", - "php": "^8.2.0", - "phpunit/phpunit": "^11.4.1" - }, - "conflict": { - "phpunit/phpunit": ">11.4.1", - "sebastian/exporter": "<6.0.0", - "webmozart/assert": "<1.11.0" - }, - "require-dev": { - "pestphp/pest-dev-tools": "^3.2.0", - "pestphp/pest-plugin-type-coverage": "^3.1.0", - "symfony/process": "^7.1.5" - }, - "bin": [ - "bin/pest" - ], - "type": "library", - "extra": { - "pest": { - "plugins": [ - "Pest\\Mutate\\Plugins\\Mutate", - "Pest\\Plugins\\Configuration", - "Pest\\Plugins\\Bail", - "Pest\\Plugins\\Cache", - "Pest\\Plugins\\Coverage", - "Pest\\Plugins\\Init", - "Pest\\Plugins\\Environment", - "Pest\\Plugins\\Help", - "Pest\\Plugins\\Memory", - "Pest\\Plugins\\Only", - "Pest\\Plugins\\Printer", - "Pest\\Plugins\\ProcessIsolation", - "Pest\\Plugins\\Profile", - "Pest\\Plugins\\Retry", - "Pest\\Plugins\\Snapshot", - "Pest\\Plugins\\Verbose", - "Pest\\Plugins\\Version", - "Pest\\Plugins\\Parallel" - ] - }, - "phpstan": { - "includes": [ - "extension.neon" - ] - } - }, - "autoload": { - "files": [ - "src/Functions.php", - "src/Pest.php" - ], - "psr-4": { - "Pest\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "The elegant PHP Testing Framework.", - "keywords": [ - "framework", - "pest", - "php", - "test", - "testing", - "unit" - ], - "support": { - "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v3.3.2" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - } - ], - "time": "2024-10-12T11:36:44+00:00" - }, - { - "name": "pestphp/pest-plugin", - "version": "v3.0.0", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest-plugin.git", - "reference": "e79b26c65bc11c41093b10150c1341cc5cdbea83" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/e79b26c65bc11c41093b10150c1341cc5cdbea83", - "reference": "e79b26c65bc11c41093b10150c1341cc5cdbea83", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^2.0.0", - "composer-runtime-api": "^2.2.2", - "php": "^8.2" - }, - "conflict": { - "pestphp/pest": "<3.0.0" - }, - "require-dev": { - "composer/composer": "^2.7.9", - "pestphp/pest": "^3.0.0", - "pestphp/pest-dev-tools": "^3.0.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Pest\\Plugin\\Manager" - }, - "autoload": { - "psr-4": { - "Pest\\Plugin\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "The Pest plugin manager", - "keywords": [ - "framework", - "manager", - "pest", - "php", - "plugin", - "test", - "testing", - "unit" - ], - "support": { - "source": "https://github.com/pestphp/pest-plugin/tree/v3.0.0" - }, - "funding": [ - { - "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" - } - ], - "time": "2024-09-08T23:21:41+00:00" - }, - { - "name": "pestphp/pest-plugin-arch", - "version": "v3.0.0", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest-plugin-arch.git", - "reference": "0a27e55a270cfe73d8cb70551b91002ee2cb64b0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/0a27e55a270cfe73d8cb70551b91002ee2cb64b0", - "reference": "0a27e55a270cfe73d8cb70551b91002ee2cb64b0", - "shasum": "" - }, - "require": { - "pestphp/pest-plugin": "^3.0.0", - "php": "^8.2", - "ta-tikoma/phpunit-architecture-test": "^0.8.4" - }, - "require-dev": { - "pestphp/pest": "^3.0.0", - "pestphp/pest-dev-tools": "^3.0.0" - }, - "type": "library", - "extra": { - "pest": { - "plugins": [ - "Pest\\Arch\\Plugin" - ] - } - }, - "autoload": { - "files": [ - "src/Autoload.php" - ], - "psr-4": { - "Pest\\Arch\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "The Arch plugin for Pest PHP.", - "keywords": [ - "arch", - "architecture", - "framework", - "pest", - "php", - "plugin", - "test", - "testing", - "unit" - ], - "support": { - "source": "https://github.com/pestphp/pest-plugin-arch/tree/v3.0.0" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - } - ], - "time": "2024-09-08T23:23:55+00:00" - }, - { - "name": "pestphp/pest-plugin-mutate", - "version": "v3.0.5", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest-plugin-mutate.git", - "reference": "e10dbdc98c9e2f3890095b4fe2144f63a5717e08" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-mutate/zipball/e10dbdc98c9e2f3890095b4fe2144f63a5717e08", - "reference": "e10dbdc98c9e2f3890095b4fe2144f63a5717e08", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^5.2.0", - "pestphp/pest-plugin": "^3.0.0", - "php": "^8.2", - "psr/simple-cache": "^3.0.0" - }, - "require-dev": { - "pestphp/pest": "^3.0.8", - "pestphp/pest-dev-tools": "^3.0.0", - "pestphp/pest-plugin-type-coverage": "^3.0.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Pest\\Mutate\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Sandro Gehri", - "email": "sandrogehri@gmail.com" - } - ], - "description": "Mutates your code to find untested cases", - "keywords": [ - "framework", - "mutate", - "mutation", - "pest", - "php", - "plugin", - "test", - "testing", - "unit" - ], - "support": { - "source": "https://github.com/pestphp/pest-plugin-mutate/tree/v3.0.5" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/gehrisandro", - "type": "github" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - } - ], - "time": "2024-09-22T07:54:40+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "54750ef60c58e43759730615a392c31c80e23176" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", - "reference": "54750ef60c58e43759730615a392c31c80e23176", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2024-03-03T12:33:53+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" - }, - "time": "2022-02-21T01:04:05+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.4.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", - "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.1", - "ext-filter": "*", - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.5", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-webmozart-assert": "^1.2", - "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.1" - }, - "time": "2024-05-21T05:55:05+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.8.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "153ae662783729388a584b4361f2545e4d841e3c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c", - "reference": "153ae662783729388a584b4361f2545e4d841e3c", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.0", - "php": "^7.3 || ^8.0", - "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.13" - }, - "require-dev": { - "ext-tokenizer": "*", - "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2" - }, - "time": "2024-02-23T11:10:43+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.33.0", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/82a311fd3690fb2bf7b64d5c98f912b3dd746140", - "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "doctrine/annotations": "^2.0", - "nikic/php-parser": "^4.15", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.33.0" - }, - "time": "2024-10-13T11:25:22+00:00" - }, - { - "name": "phpstan/phpstan", - "version": "1.12.6", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "dc4d2f145a88ea7141ae698effd64d9df46527ae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dc4d2f145a88ea7141ae698effd64d9df46527ae", - "reference": "dc4d2f145a88ea7141ae698effd64d9df46527ae", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0" - }, - "conflict": { - "phpstan/phpstan-shim": "*" - }, - "bin": [ - "phpstan", - "phpstan.phar" - ], - "type": "library", - "autoload": { - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPStan - PHP Static Analysis Tool", - "keywords": [ - "dev", - "static analysis" - ], - "support": { - "docs": "https://phpstan.org/user-guide/getting-started", - "forum": "https://github.com/phpstan/phpstan/discussions", - "issues": "https://github.com/phpstan/phpstan/issues", - "security": "https://github.com/phpstan/phpstan/security/policy", - "source": "https://github.com/phpstan/phpstan-src" - }, - "funding": [ - { - "url": "https://github.com/ondrejmirtes", - "type": "github" - }, - { - "url": "https://github.com/phpstan", - "type": "github" - } - ], - "time": "2024-10-06T15:03:59+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "11.0.7", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f7f08030e8811582cc459871d28d6f5a1a4d35ca", - "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^5.3.1", - "php": ">=8.2", - "phpunit/php-file-iterator": "^5.1.0", - "phpunit/php-text-template": "^4.0.1", - "sebastian/code-unit-reverse-lookup": "^4.0.1", - "sebastian/complexity": "^4.0.1", - "sebastian/environment": "^7.2.0", - "sebastian/lines-of-code": "^3.0.1", - "sebastian/version": "^5.0.2", - "theseer/tokenizer": "^1.2.3" - }, - "require-dev": { - "phpunit/phpunit": "^11.4.1" - }, - "suggest": { - "ext-pcov": "PHP extension that provides line coverage", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "11.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.7" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-10-09T06:21:38+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "5.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", - "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-08-27T05:02:59+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "5.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^11.0" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:07:44+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:08:43+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "7.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "7.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "security": "https://github.com/sebastianbergmann/php-timer/security/policy", - "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:09:35+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "11.4.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "7875627f15f4da7e7f0823d1f323f7295a77334e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7875627f15f4da7e7f0823d1f323f7295a77334e", - "reference": "7875627f15f4da7e7f0823d1f323f7295a77334e", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.0", - "phar-io/manifest": "^2.0.4", - "phar-io/version": "^3.2.1", - "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0.6", - "phpunit/php-file-iterator": "^5.1.0", - "phpunit/php-invoker": "^5.0.1", - "phpunit/php-text-template": "^4.0.1", - "phpunit/php-timer": "^7.0.1", - "sebastian/cli-parser": "^3.0.2", - "sebastian/code-unit": "^3.0.1", - "sebastian/comparator": "^6.1.0", - "sebastian/diff": "^6.0.2", - "sebastian/environment": "^7.2.0", - "sebastian/exporter": "^6.1.3", - "sebastian/global-state": "^7.0.2", - "sebastian/object-enumerator": "^6.0.1", - "sebastian/type": "^5.1.0", - "sebastian/version": "^5.0.1" - }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "11.4-dev" - } - }, - "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.4.1" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" - } - ], - "time": "2024-10-08T15:38:37+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": "psr/simple-cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\SimpleCache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for simple caching", - "keywords": [ - "cache", - "caching", - "psr", - "psr-16", - "simple-cache" - ], - "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" - }, - "time": "2021-10-29T13:26:27+00:00" - }, - { - "name": "react/cache", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/cache.git", - "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", - "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "react/promise": "^3.0 || ^2.0 || ^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Async, Promise-based cache interface for ReactPHP", - "keywords": [ - "cache", - "caching", - "promise", - "reactphp" - ], - "support": { - "issues": "https://github.com/reactphp/cache/issues", - "source": "https://github.com/reactphp/cache/tree/v1.2.0" - }, - "funding": [ - { - "url": "https://opencollective.com/reactphp", - "type": "open_collective" - } - ], - "time": "2022-11-30T15:59:55+00:00" - }, - { - "name": "react/child-process", - "version": "v0.6.5", - "source": { - "type": "git", - "url": "https://github.com/reactphp/child-process.git", - "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/child-process/zipball/e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", - "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", - "shasum": "" - }, - "require": { - "evenement/evenement": "^3.0 || ^2.0 || ^1.0", - "php": ">=5.3.0", - "react/event-loop": "^1.2", - "react/stream": "^1.2" - }, - "require-dev": { - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35", - "react/socket": "^1.8", - "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\ChildProcess\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Event-driven library for executing child processes with ReactPHP.", - "keywords": [ - "event-driven", - "process", - "reactphp" - ], - "support": { - "issues": "https://github.com/reactphp/child-process/issues", - "source": "https://github.com/reactphp/child-process/tree/v0.6.5" - }, - "funding": [ - { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" - } - ], - "time": "2022-09-16T13:41:56+00:00" - }, - { - "name": "react/dns", - "version": "v1.13.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/dns.git", - "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", - "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "react/cache": "^1.0 || ^0.6 || ^0.5", - "react/event-loop": "^1.2", - "react/promise": "^3.2 || ^2.7 || ^1.2.1" - }, - "require-dev": { - "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", - "react/async": "^4.3 || ^3 || ^2", - "react/promise-timer": "^1.11" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Dns\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Async DNS resolver for ReactPHP", - "keywords": [ - "async", - "dns", - "dns-resolver", - "reactphp" - ], - "support": { - "issues": "https://github.com/reactphp/dns/issues", - "source": "https://github.com/reactphp/dns/tree/v1.13.0" - }, - "funding": [ - { - "url": "https://opencollective.com/reactphp", - "type": "open_collective" - } - ], - "time": "2024-06-13T14:18:03+00:00" - }, - { - "name": "react/event-loop", - "version": "v1.5.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/event-loop.git", - "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", - "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" - }, - "suggest": { - "ext-pcntl": "For signal handling support when using the StreamSelectLoop" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\EventLoop\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", - "keywords": [ - "asynchronous", - "event-loop" - ], - "support": { - "issues": "https://github.com/reactphp/event-loop/issues", - "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" - }, - "funding": [ - { - "url": "https://opencollective.com/reactphp", - "type": "open_collective" - } - ], - "time": "2023-11-13T13:48:05+00:00" - }, - { - "name": "react/promise", - "version": "v3.2.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/promise.git", - "reference": "8a164643313c71354582dc850b42b33fa12a4b63" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", - "reference": "8a164643313c71354582dc850b42b33fa12a4b63", - "shasum": "" - }, - "require": { - "php": ">=7.1.0" - }, - "require-dev": { - "phpstan/phpstan": "1.10.39 || 1.4.10", - "phpunit/phpunit": "^9.6 || ^7.5" - }, - "type": "library", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "React\\Promise\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "A lightweight implementation of CommonJS Promises/A for PHP", - "keywords": [ - "promise", - "promises" - ], - "support": { - "issues": "https://github.com/reactphp/promise/issues", - "source": "https://github.com/reactphp/promise/tree/v3.2.0" - }, - "funding": [ - { - "url": "https://opencollective.com/reactphp", - "type": "open_collective" - } - ], - "time": "2024-05-24T10:39:05+00:00" - }, - { - "name": "react/socket", - "version": "v1.16.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/socket.git", - "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", - "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", - "shasum": "" - }, - "require": { - "evenement/evenement": "^3.0 || ^2.0 || ^1.0", - "php": ">=5.3.0", - "react/dns": "^1.13", - "react/event-loop": "^1.2", - "react/promise": "^3.2 || ^2.6 || ^1.2.1", - "react/stream": "^1.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", - "react/async": "^4.3 || ^3.3 || ^2", - "react/promise-stream": "^1.4", - "react/promise-timer": "^1.11" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Socket\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", - "keywords": [ - "Connection", - "Socket", - "async", - "reactphp", - "stream" - ], - "support": { - "issues": "https://github.com/reactphp/socket/issues", - "source": "https://github.com/reactphp/socket/tree/v1.16.0" - }, - "funding": [ - { - "url": "https://opencollective.com/reactphp", - "type": "open_collective" - } - ], - "time": "2024-07-26T10:38:09+00:00" - }, - { - "name": "react/stream", - "version": "v1.4.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/stream.git", - "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", - "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", - "shasum": "" - }, - "require": { - "evenement/evenement": "^3.0 || ^2.0 || ^1.0", - "php": ">=5.3.8", - "react/event-loop": "^1.2" - }, - "require-dev": { - "clue/stream-filter": "~1.2", - "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Stream\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" - } - ], - "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", - "keywords": [ - "event-driven", - "io", - "non-blocking", - "pipe", - "reactphp", - "readable", - "stream", - "writable" - ], - "support": { - "issues": "https://github.com/reactphp/stream/issues", - "source": "https://github.com/reactphp/stream/tree/v1.4.0" - }, - "funding": [ - { - "url": "https://opencollective.com/reactphp", - "type": "open_collective" - } - ], - "time": "2024-06-11T12:45:25+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:41:36+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "6bb7d09d6623567178cf54126afa9c2310114268" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6bb7d09d6623567178cf54126afa9c2310114268", - "reference": "6bb7d09d6623567178cf54126afa9c2310114268", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "security": "https://github.com/sebastianbergmann/code-unit/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:44:28+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "183a9b2632194febd219bb9246eee421dad8d45e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", - "reference": "183a9b2632194febd219bb9246eee421dad8d45e", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:45:54+00:00" - }, - { - "name": "sebastian/comparator", - "version": "6.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa37b9e2ca618cb051d71b60120952ee8ca8b03d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa37b9e2ca618cb051d71b60120952ee8ca8b03d", - "reference": "fa37b9e2ca618cb051d71b60120952ee8ca8b03d", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/diff": "^6.0", - "sebastian/exporter": "^6.0" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.1.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-09-11T15:42:56+00:00" - }, - { - "name": "sebastian/complexity", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", - "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:49:50+00:00" - }, - { - "name": "sebastian/diff", - "version": "6.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", - "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:53:05+00:00" - }, - { - "name": "sebastian/environment", - "version": "7.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", - "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "7.2-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "https://github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:54:44+00:00" - }, - { - "name": "sebastian/exporter", - "version": "6.1.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", - "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/recursion-context": "^6.0" - }, - "require-dev": { - "phpunit/phpunit": "^11.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "https://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/6.1.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:56:19+00:00" - }, - { - "name": "sebastian/global-state", - "version": "7.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "3be331570a721f9a4b5917f4209773de17f747d7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", - "reference": "3be331570a721f9a4b5917f4209773de17f747d7", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "7.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "https://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:57:36+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", - "support": { - "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:58:38+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "6.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "f5b498e631a74204185071eb41f33f38d64608aa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", - "reference": "f5b498e631a74204185071eb41f33f38d64608aa", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:00:13+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:01:32+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "6.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:10:34+00:00" - }, - { - "name": "sebastian/type", - "version": "5.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", - "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", - "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/5.1.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-09-17T13:12:04+00:00" - }, - { - "name": "sebastian/version", - "version": "5.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "security": "https://github.com/sebastianbergmann/version/security/policy", - "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-10-09T05:16:32+00:00" - }, - { - "name": "symfony/console", - "version": "v7.1.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0fa539d12b3ccf068a722bbbffa07ca7079af9ee", - "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^6.4|^7.0" - }, - "conflict": { - "symfony/dependency-injection": "<6.4", - "symfony/dotenv": "<6.4", - "symfony/event-dispatcher": "<6.4", - "symfony/lock": "<6.4", - "symfony/process": "<6.4" - }, - "provide": { - "psr/log-implementation": "1.0|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/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "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": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", - "keywords": [ - "cli", - "command-line", - "console", - "terminal" - ], - "support": { - "source": "https://github.com/symfony/console/tree/v7.1.5" - }, - "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-20T08:28:38+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "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.5.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-04-18T09:32:20+00:00" - }, - { - "name": "symfony/event-dispatcher", - "version": "v7.1.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", - "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", - "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.1.1" - }, - "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-05-31T14:57:53+00:00" - }, - { - "name": "symfony/event-dispatcher-contracts", - "version": "v3.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", - "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/event-dispatcher": "^1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "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.5.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-04-18T09:32:20+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v7.1.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/61fe0566189bf32e8cfee78335d8776f64a66f5a", - "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" - }, - "require-dev": { - "symfony/process": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "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 basic utilities for the filesystem", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.1.5" - }, - "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-17T09:16:35+00:00" - }, - { - "name": "symfony/finder", - "version": "v7.1.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "d95bbf319f7d052082fb7af147e0f835a695e823" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823", - "reference": "d95bbf319f7d052082fb7af147e0f835a695e823", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "symfony/filesystem": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "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": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/finder/tree/v7.1.4" - }, - "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-08-13T14:28:19+00:00" - }, - { - "name": "symfony/options-resolver", - "version": "v7.1.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/47aa818121ed3950acd2b58d1d37d08a94f9bf55", - "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" - }, - "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 an improved replacement for the array_replace PHP function", - "homepage": "https://symfony.com", - "keywords": [ - "config", - "configuration", - "options" - ], - "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.1.1" - }, - "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-05-31T14:57:53+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.31.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.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-09T11:45:10+00:00" - }, - { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.31.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } - }, - "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 grapheme_* functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.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-09T11:45:10+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.31.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": { - "name": "symfony/polyfill", - "url": "https://github.com/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.31.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-09T11:45:10+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.31.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/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.31.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-09T11:45:10+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.31.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.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-09T11:45:10+00:00" - }, - { - "name": "symfony/polyfill-php81", - "version": "v1.31.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", - "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" - }, - "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 backporting some PHP 8.1+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.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-09T11:45:10+00:00" - }, - { - "name": "symfony/process", - "version": "v7.1.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "5c03ee6369281177f07f7c68252a280beccba847" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847", - "reference": "5c03ee6369281177f07f7c68252a280beccba847", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "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": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/process/tree/v7.1.5" - }, - "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-19T21:48:23+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v3.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", - "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": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "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.5.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-04-18T09:32:20+00:00" - }, - { - "name": "symfony/stopwatch", - "version": "v7.1.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d", - "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/service-contracts": "^2.5|^3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" - }, - "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 a way to profile code", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.1.1" - }, - "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-05-31T14:57:53+00:00" - }, - { - "name": "symfony/string", - "version": "v7.1.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306", - "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/translation-contracts": "<2.5" - }, - "require-dev": { - "symfony/emoji": "^7.1", - "symfony/error-handler": "^6.4|^7.0", - "symfony/http-client": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", - "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\String\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "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": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", - "homepage": "https://symfony.com", - "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" - ], - "support": { - "source": "https://github.com/symfony/string/tree/v7.1.5" - }, - "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-20T08:28:38+00:00" - }, - { - "name": "ta-tikoma/phpunit-architecture-test", - "version": "0.8.4", - "source": { - "type": "git", - "url": "https://github.com/ta-tikoma/phpunit-architecture-test.git", - "reference": "89f0dea1cb0f0d5744d3ec1764a286af5e006636" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/89f0dea1cb0f0d5744d3ec1764a286af5e006636", - "reference": "89f0dea1cb0f0d5744d3ec1764a286af5e006636", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.18.0 || ^5.0.0", - "php": "^8.1.0", - "phpdocumentor/reflection-docblock": "^5.3.0", - "phpunit/phpunit": "^10.5.5 || ^11.0.0", - "symfony/finder": "^6.4.0 || ^7.0.0" - }, - "require-dev": { - "laravel/pint": "^1.13.7", - "phpstan/phpstan": "^1.10.52" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPUnit\\Architecture\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ni Shi", - "email": "futik0ma011@gmail.com" - }, - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "Methods for testing application architecture", - "keywords": [ - "architecture", - "phpunit", - "stucture", - "test", - "testing" - ], - "support": { - "issues": "https://github.com/ta-tikoma/phpunit-architecture-test/issues", - "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.8.4" - }, - "time": "2024-01-05T14:10:56+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.3", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "support": { - "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.3" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2024-03-03T12:36:25+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "php": "^7.2 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" - }, - "time": "2022-06-03T18:03:27+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": "^8.0|^7.3", - "ext-json": "*" - }, - "platform-dev": [], - "plugin-api-version": "2.6.0" -} diff --git a/deployer.phar b/deployer.phar new file mode 100755 index 0000000000000000000000000000000000000000..31e8c048225f7188f7b85a45fec0d6e37067a973 GIT binary patch literal 792695 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

)gT35IfK@W(q#vq`ZxnS9Zg-A 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%0D6gLu zC7$zB=*A41t%#MZm|-9zmUQICmECds8^sabTOA5yk3G@N(@k_+GaouPzN{VfEimR-^9Z#6HGm_KH$bB3m8A}*hT+GPQB9Nz_%-GD+ znIQuWj2Z`AJl$BC18uawcXUG2PGo!+u^I5!PlW>w=$*)L0B0G=(20yXCdD?Q+bg#B zEKK^1ta%Pi&9n&V4D1J^%aEw1E2;~ro9TL7R6wgxM7LGdepZ=G=q#iGc%6a^~#}9^`YLL+;p`l?#Qb$XZ*zi#Z*;5$-JsUN@iCP$6p%MjKpb_ zO&HpG)JXjGd5+}ZsIRv8`*dpa{Ka(hwquqw8=cs=?Fo9OoN0|Y$9k`6YPP0gdXLdr zx!8$K|L1h=(t}A?*Umssv+ZHcRv3-;IY(W6&M_D4;$yLQRwFJ3;Tpxbs{hAK?sRum$XdVX4DiVl8y8o?SR}^=xbXR1;vtQmN=Br-5pgZ0JeMwUF-ayQ6>&$= zk;MI1aSa)glM!zm_r-Fkn^puB|1T7QonZ#y%_;KbSl#6;yybsOZWBF{o`02YOkbwwSS`u$FNjB2YX`xTzC}ZSp8^-=%E_*NKvaou^ zYwR*^+Vtw$^NyeVgucpGoKSN14l7w#PY=)ye{p+DpYs~FYb8DW)CoborkS$oUK`g; zxk;MGC~|>bKD!kz3(j$2yyB`l`;~R@d~xpH57gQ5<3~nw=Z?p0bnL5VVm3O!HuqOw z!#Y)1J$o2_l;K?r?_qd9!{1`~y9}SEhe)#KeRW0IU-A`YquR0Jc!H%y%k3Q3R9b74 zTI+LOo-Fj`n+x4IE}TmI!&ObY@Ge!xYsO;wnh|d<%IsU29bYpdoJ{P8IKE~At;f+C z3}WS8kTv@8^9T40K0wIpfOCL-4-z5)+5zn@90Qd$V2-pVL09XZBK>@lP=syDnADqhV05)0b*>snKd^2yVKmAF46Vf-XAYd21 zv3AYJ5rp+euh({u&+G}}GsU9>B4OR8{<9PvKF166H@po^bxm(P@j~w5Ck<yfYV7z`?FEAg?Bk-$VaBhDP3-wDL*?+ z{|?k8g!ZzU%e;n3!?uO=Z3Y;2EkI|3kK;w zJgTdUs!QuORu_5w9?7jpo`51d>KwA-b2wV6i;_z|B7w&{barb^O$|it9y#E3M`T43 zJt4fVfI)^oEWdTi}kk z)2gfaPa9Fnzhg5zJz}V?=Kfbay)e64#9ICoYmwzP!yx&$J3>?kxZED?de%1c|xLozDvTb zZ@`a#==Z`uE_k(0OFs18ruT4Bf#cJ-`~3NT`shCiq@{lP*hOCv?VvN|29o?Y{VnyR2>qV`flBAx;(DLjuBfZQ|6#fFR)jt$AK;j`jNX_slfgeIkhK`SoX(kVY zDyUtAsGw%%&qH=3BQi5eV=+UjV?Q(~72z+$PI`(mOvi19#0!rp5Bli3 z7JW*|+-bSAFu(G&9C)$>R@@9s*!swZ9j%ofiyp^X;1K$BJp?e05A86EGMXIGg?CQ_ zX#l^IS=3^rDA~!X*9j}Cvj#kg)yPa%qTPwV0LzeOuoPfH6g)8f7R!adbxHeFJyQ9E zKOvqH^m~|mImv+^7n>y?WL`+8vZ3Ql*_&D3(a9PvXEmH@dt)VUSI0WGHd`=~bc+>; zvzV>kW=LuNGUT2aYb?w7Lt~{!mc>weaHqK^6b#E%g{l-@E_?lA$RjTe1-w#3j&vwX zaRV>+$f1&MzR-+YD$pUyN((+Sak*6$@+Dm1ikvxSbEP8T-D7pQBXWn{1l^+Zay`zU=m+S1y|oYvr=Zr1ic}jN)ArFIK5sCOJw?ver}Mq^iG~ zis8~s-@2*_9}a{COQAW8OS-DCF;%ycmRh`D)oy4mGkevT8G!(F0_|>c#*e@LOU(XjnPbIeCrIR z_$=2c`xUMlS4~~r>a}0qygAwUy#M>vrx(5h7h^h?%N20TI6JqBYv7u>ZJdt_bB}N_ z?mJvR_Z;^F?geg;dzm}Ro#ak)W1Pli@(=J!c?Z9SU&lA|-TWi`9zMn&;GgB6=MVEI z`BVH`{5$-=^Y8PQ`49PYOQGcs^x^`=a#oDZ(H88yl?q$ z%Vo<)mbtEW2C1tb9a>^bmd${b;vLj_-Jstr|th?Pb(+-|EECCaS84cw}?0M3g5#ovY0InOPgi8#cxsQMTMJ^ zkbI8(pL_lXg;d*a;xG_>&sU6ARD>#pK67d5g>G5VQnhGTD2rV$_LnJs# zLycvibj++!(t{*IMzN*9Reo+Xycpa*46;%=N*gi@D`vnK#%eK7E&8w$Hl!V5U{tC( zQX@Y{+;SYrVl+fz!)SV;;zUW5mY$?h5l+XcO;X!&oYed)ZSce~$zV>0a>*j$pXo&! zQ^sba^PdV=IZ=zcY`J+KO8N;1WhWaKQ@xbI+~+k@lA)^@gRsMQK2IrJ+ZxQ3*VHgN0T4vgFQMlvSI ztpNs^Yq_QIB^f!fMA$TI!gpoiz;D()(&uI{xgKB6X5N-IjYemK5-P*zB7yTV?yI%2(u``$C4Oh4mGG*+r@8 zyT>!PZGigf7iFSba3bl@82V;b{v@YFLgF5g9hlAD=G+$A+>O=w4>sI8KfSxYn+?XJ zPd)Nc6qC*guDcWV;24hf%+RPbdU5^&by7`_(=ZUd`&Z0?LtCNt4i!{dx~r8CAeG}@ zCeEa>65G*uOeu(8#ZTamF>yBgQP^A@J->N=@7de;LpvC=Ss7Tt*VZLyTu-3ufGiLj zke1+Z_Du|D#cYR1S}S?vFYFSov2qmPOB4#$5yQ4A$SzGYYa9K$d;WFgBG=@;2OEbo zyJIVWp@!aB3P}$RO=OSaVt5ThPpH^8N2fCP@%C!}>98NAic4ux;DiZkmxNuFg=#oC zX>~^vq?p-~9#j{{8)E``N*dxJ(cM+_Lktu||3ZpA-F?n7WO+MwQcU0D6MP$lxETdh zf3)Nt0k3wwDyfI+{Co^-k14GmI>x$APon}>QCUf9VlI6ovSlMq^BRxP&%N(3ORHUe zKz2F(fSW(RnQZ4^TO(7q?zr0>J-U7_e`6kfzL1B$>jkQ-3*7uPpkL`?{8n&7GDW{s z&@`a-BacA~cOKa>N#^j6_O!hz>yRsb1Nt<=6#PiCAH}Ab#ZoWif3)}>hsHQM zNKZeh9cBWK_=&!Rl`1R}tQ{k1iyr2t@8n_NWZE^05x;W2A7{F{2JPB|x4Vi#Q3XLW2V=OLBP!$;=Fw>KGwMYb;`gxelYivTdL4oE}cHUSLx-y((zhP zLQD5kkT@AUK`J*In?^;CQH1KP1lhoB6)EHa_|m4`RouZ91?C-2vAS@DPE%W2Owq0L%cPGmZi&#$@vz zSs%9vZ1EMZ3Kz`fDBwmK6dp$fM?q>i(V5S-C!?=9{z9rWT#$qzcrqR<-X9oX!iSK1 zC^Qj^K&prtF2xqaAu_TJIgV1ltL9nby3??sQk7=F42+ltpKGJIn;7(A#La-7PzG8i z%0nXZQ^hsM5iCMYNt78qoXIGb0)?SFp=F22)V6cNYZ9G41-jjk6qZb5(C%6Xa7)l=jwMn{cnV zK@ALOx-{(v7@0O$rWN1LVFmhxHj71ICsy>I$x|_xhIu1**0hFLMxxpTfuoQM1h^j{$x~J)^L+}FKbZ?aqXRPmWNi0R1JuFgCSv;0 z3M#A>T9D$v$ZBRamc7cV$%N6>E!eR;U=7?yMMH0WG%csiS7R6)9L%=vIk(PFUaq({ z-L)VQo>c@R+m=dM*R8A~Wf_hkV4=pXG|w`(W7w&_w!`TOMwQf)QUaY!7J$P4SN;Dl z+82uH2EL$E9W>eLIz;74&CR$-YIYkJb80kqgGbd!Fn;9U~VZJ0&m<(&KINyY4&LlCn5+VMUw;Fat&EZtYl_+pMX zrBkq1XaBFKC6=#Jm1VD1un`ot6@4i-Ge4wD7ur30l6kl+k!7^&7Iq?>RQ-1T0JT?b zQ`u8Jorm2oE7)0p$`6^GIYf zqL|=qNE1qMY|iMDS$B2$ad>?{)T#_h6%z$dL_)}<%Ge}VG=wLnVw^z_q{y>?qM^_r zKJq+HW>lgRrAJ>ridiZ+Q_*a>p#0ta)rFTFKOzLz z)$uTdooV-jgh&hvawp6JJ3wU-g;7j13IzWnHm8u#IZdRF+?-|;A(>iqmXi3#wY8*! z-yl-WGR72@h2YznrH$57+^V1*IGBS!6KG>?e&GtCRE#lA7C^saLWHPzbwNlc`P4|F zD8V!^12v&oSr@*xr&jCUGwh9BNI#x5-fQG%Q~2!fAkQ`Fz*;oaHI z{pIK%OlB?>(Wn`(18>#LPlRYNZOn%>5E;=W^B7aKg0(527z8X7iKQ-UI-7FV`dM*O z&|D2L0~|}wH=<}u*GWhtk|(OJw{YdiQl3w+KVaM7fl1l%*wB#Wf$|4PvP)$TBu%1D zr=)CreRKEs=~dg(;dtGHh$ND>8+~%!>48RVVcGmJ9O^!E(08pnPzHkrEZw>S*N$Tp z6>w~QHGF=ndHq3OQgvRq=vUq@*SxHy>W>q~G4@P_B6!)#I%=*k?7&$AS(|R_c#SCixxBT&6wM8yHw9G70+5iEbS4Zzo zAL~Q6SErZP-BoS6Sy`=rRz40on=Eu4AVtnF2Tr{sJU5&kHcS-dv2kYGw8`b}INXpfQT#uzKxQ(I1U5b(*hAI;P?|sFOx*~~}KqIU}Q=imNpf6Un z<8v)sowY@7xo0w=L2{SUkaumXC(#v ztclbha?k~Zt96wNzQ(ikmMrN6g^hfYj^KipGC0iC62+yEoDdh?c^IXV^XeRg=>XH&XyJK`^@11`-{qXtfgHdI@)CJM7 zA__95v}B7$(+pNj7x)cEphP26iiR@l@pLfYq@oIgXd}8l6;&-b|Fj-HU{G1@!Iv#<&-sIv<(^;uPV_?U!(KgJGfC zCe?{oKL#QtS;Ny-!x%BGVR%R7LMW!!V^|1L!Z4$$kQh-mhJ6TvVIIy#)&ZAP>k5&W z&ZDE9E_97`?R3=5T20p9n}(}`N&s2KXjk z-~CqcPO;Y|vW}#8Of(9F!&Yu7!!)zAH1YCL8EuLkkUlrn0%-`D%e`v>snI=wPdRX8 zp0VK)ZV3fb$gp?3ElYMAQ-%cXO`07cf{iSX;f241iF`d8&0so(znfCCx?KD0 zE!ObbrVw3{wi=YAg{`R(0Fq_MxeKaS6m#koZ#)EABCYj3YP00Mv9GhfNYBp>X+&Xn zHNcCxS3MhSwMizvN~YTc)S`A|b?PkqgE%Np8)<|+6@+w-AtxBaUff<_udR%3Wf2wQ z*G?m1^M#{Fx#77B!M0An%oyWK7<$=*xD&y062xQ3g)~}#Zg;Z1T=LEJUW~E1CDlG# z$><22qmexaP+(PE;>=B+JsU@r+?&M{W;hQC;$XxGw%|fY6yuoXIBtZgMQK8RI8UxG zKVIH^xHun&3xG?5E%0e*!k@bU=z#Ud98${403J-ldxi}~*5{Njb&>QHO=AkQH@>nA zC9$R79>J?aV8`Jz@45D%a0ss3A-l8u6VqH!ta>KW`+lY+?r*7CpW0-HmWd!4#up;m zIJt}E9z|wbo!RPdRd@P$gRb2?KqW4U0UR4@c}$;o&G>5_oOOC*KdH2?;~b`)KHC!P zx%m*Yywf<=m}WRcmA2~BMk-`roJ+X(y7`rvspaOrr<{pf<132WUIrDpMFjhcsU)is zntDYfu4|1+1~3f;(_zmslE&wD+@dn%briC$tHAK)#A-vt=t7ESSxn%fHdjbl;@Yvf z5q?KRnsKOzNrXYS;k5{SO!e&8<#yy>e+rI zn#r|IOz|#d=*YjsjbcZ8NZNevu^mg9XMxIZ`*d;NZ=u~`BEJO#yQgt4CPz@Me0MDD zUrlz}eS`Ig!oUTj!nqaz+tk3_B65&B6hepVJb7~c$ z6#m{{VWf$qsH}XrpE?F(rRY`yI<12%bcaToI*Tu!8yxk;%-(oHP8eP*vY&QGD zcu3wvD@Hjv6PogvQAwUBcI8C5Gl#L*yeRj-5z>lFiYz0s$ZsXPPBn@6nq(}dTtP8U zgxo}$2|gluMkB1%< zT3d_9g8`2=Q~^Yd=yEDHx!{y*eBw%E^m0+?ywFF3L810-dt=SiRF((o?{kj-66iQG zv|8Nd8Mo1JYrw2&5*3*yaTY1C4r(H>GJQKI!tOgHb4_4_BFl@{iw_r;CVZTopI7`_ zf4TGc5CJK_p&aCc6&d9@yb(!J;M|v`mNeQp3%*!wD*>K*MVsfq8A6T;hXYz5!r_r` z1OCx}3w9G_MzUV(gACX>3B? zNl*a$_h*EU*=a+_JOG1~j5bISP5PgM8!A^qF?|cyAb09-8NHzy2@%CrR)3tGpDvd3 zi%%wSl#UD(#z_apu%mt@MD`yy8N5^dn#Mv#CK3NiDYPKt1*sMZ(odm)C=yx;HtGv4 zo?aJt!T5DoSzm5B0}hhvMY)kQ3(O)yraMhA!sK(6bRD^s+Ocy^u|hdQmEzVZ_Rjgjyx+zo*g4k&#(+J^RT2O>iGEB-{R@F(Kxm~JDn1!Q7~gf%KS`G zh8Zr5EhjZNB6xO7wka|XC66nwJWYW|Q*#d)>}AzguCN{MO|WuPIGj|av{er~dEmU}-$||A zVMCiov0K|&ZGECYR-W(Oh$Z)yEKYl@i=bldW=qm+nm-=zOGc3C? z&^>TZ^BX?yP~`SNYUH$PRX?OX2kr@}i3eNw?H#(u@@9Lvb)VHeo9|;Wg3{KOs!7|O zIW1EjgeG5Ur+pv?)V%DP(k+*6SD!KG)^POAvY@8w#f3DS6UuLx6x?)SL=|~1BwCm) zj7BR#%4Dx9krtIS*Ys8;sqQ#Rc1-HE@k(@!v8jC_~d>t8-OL z&I`_A-D3I2vu9zi%O4!DYwhm|7(V)4fTt;qzp570Z!|6}E*~@|jrr+2!j=e4(?(jc zsLI=v#c3sMEvPb`27q7&LJMLCBaE|gimnpK-n^EW0n1SO-L8lq@mFZ^4Ot5JKwsHFDo%u^cyBuWoMYH!c3>Zkh~=Iw=hsxn2;bC zwFDr~K}r}bmKUGSX2G!i_VVn{v#Z6jS^Vtv3@t}Jf}_mjoC_72c?Oem7#v}UDlG@G zfdv@!IeLMhIzRN|eCOZC zos-iqRZ&Gz|1g3>m=@AOE)@cQSHcpQ9H>B;EXv&I1;^5#Vur_@T<6E>0bGehqJ~>T zs8fj+PV*2scTLT4YRa=!{*|%exZEoRsi_uL&I$sdGf*-`?HE|+#+HJl(MM1z6dZez zI1hE#ql@9qWLO^+SW+Pf=E6ZH9a))p!VKn;3f^G_&Ul+517(46KZ>*{(Xoh)qNfW} zRz{;H{-vE!_%!xZc^X8KcYjN}3N#7r(+#U>iZ-#qn~S#!N18u!COD{j5=?842j{EG zqI2j#u!AN<*UhL`uL;3t&}>;-86ON*S?9u2!EJbJ+cpJLlSp=Yk``XkFND*As5;Xu|`fXCbf!zE5k-bA-}6S|2H3mpjov!2g)8j>N&c zE#n4WVrndpL>4E;DClMD|NCv0bS>~U(#nclD2E@S@eyreoTNp}9fF?17gT$n#TImj zK8GqlIe8r3e;ZFm(;v@w52NAq{d%Rl^Ac$nDp~&lrb^ey!#y`I;4Jwr7+% zC!x}Dk6(_CU+?Y+!cdy3-gbQ7o4FW2Om82i&o|@y?_aO?JFJ0Hmr(O0;OCB#8ktd$ z{!u)a(QlPjZExE)5dQ98aRq`(E*z`dN2l)Md2SmZi32-ZSImP-OO!-ZCIynRQ-^ zK#5XD6b;4JkR#_FkK_}VV*O$V+`TUZvfuT>-R4l!bHL6!#$rN zA{89dcAVr&RFgJc|Idw}AUX@Q2&$FCT%^VufX=jdfV*M^)o1T(&v;o#wk4XvSrr+k!;IRLmZEq^al6gy#BtQ@ zXaO;pcew{C`?mwaWxzdDdh2So_MqmAw z`Lz)FH*Sjar1_XeLK0JBA2W(pq|seH2v}K0YzlmffMpDr7;&DKIKg<@Hr6Hj%7L?_ zo^T7{X@J>?knYNou0$5ogp|2%pGKSr=Y89O>7+XDit;+H)+}-7x;~NBe~0= z0}Lvqlxyr@*w}bvLBi1TF3U*!XLVhe>>lKB42tH-Xw>8?yqzy@Cf5U-heNutN-)qt zCuN6hRcouLD;1lECE&kUF%{OrtG(*Ow{PH8?;gAuk0GVHSrzJi@wBvm0B9b|q%Ghs zGJVeo^{CLQ+T)aBv5~qQu!S?NTC5K}Q{wJ<>@}}vrn#TLbz8@+>a3%+(imerPdv8$ zKVsOSW<*UzF66Q-3L&+B+67cFIyf2~rMb!M-~f4WkQ;~f_^ge*r@CtAH62=$C_}eU z+V&(nVz8F~u&r!Kbt!qfx11IzX1N0O+fs2TM=W;nuBi|Fy#p2RjB8EPAo zvG`~XF5ev0JcTpYFlxD@j&jE7DdjeE?F2dq7>;3e_u(#_&96`9>oT!trhgRFpxNI) z&`y%%rOJ+1b|!9Nxx(DZk{VABa;Pc+DQv(fC-#rM(zH`HJ(x312JbOsog-<8Wg3nH z!GZPu0DRPfvG+D+++fj{J(woOc#K^Rxup>?-Eq24cMPvoH)^kb2C5^Vn=&_jyHK=@ zMGb{A-7t;^EZ({ZnEO%;1uG~*;bFd`_Fxx0-vbIX`eL1;e9NTZwq{$NEoefqR3bV8 zdjV2-+xau5>oWa-x4s;|?xct?3!_m@nB}D2pJ`nvypE)JsVmp!1P>yI6FgX)^Q;2u zCf&U487}D5JiC6MUvi^EDKh&K!+h6kYPJ4J18=3 zYm+5IA2EU<|9zC~CRtiw)kP#lzV|3{{-Lc~#%^yI+`!jbIw++=pu6SPgDJt+2xH2dO!nAuUtJ(wC z1t=*{J0jMlu?_dq=rObkImLDoyHxl2@$P=LzK>8zrLVb%jyou%^Hy$y#{xR(YkHv$ zoC#JS5fw@CEn}KD=%|TfN1Hp-v__-$WNBvr_x$F!ZPh9@y;5)muayl@*cw4%t33l1z!k!J+Z5!sQZpaA#ECTb{UdV; zOPyJC@Is8vSoAP2Qe_ba%*0T0^WDEBpT-rjuE9{d^|q`Sw9BEk23?TFt{~rNw&cdp z)~KcSX|YSV$JO2a)B3(2l~{7689E&xw}HLQB4ZAn(HBB-*1Iy; z;KYt1pd^K}!QM5QXpiE9THcTeQ7vt%cHpA|kHnMOf18>~1uhEXky$NdLQ& ztX32ebII<^%lF>Q?6PaRESruq7{f!OJXA^}@ZAYVU@M>oA>X%^HG8hfS5f1H#Zf<$ zBUp=#LIZb}&`5<2W>u;zeE()5Z9D(audPeCDrgPTc6+DlhCrASw328%8=K0yR*i8^zPBM5fFL#aGDwF!hJ>=ZTJ;R(DAP9htXDe*MRjA+sG z5XXt0m$vP!K|}myyw#X08e@R-xR(_C9y^DgRUQO*WokC}p{~(K$F0!exRZql)bN~7 zmeV*W5w5MNVYW;Ei~f3<7(Gvsq!!*o-m};w$B_-my@x!ef>sj4@c7o`OzGY~vQ zX=r1aD_t?mm3#xWKt^*bj_a`QLAh+x&j6k^tWnY0{7(d{DB0={o$MH;*49DP}=f z&LyLb1TzM9{1?03l3xkXs5M_Pi|~5Igu~8vcn5d)lgAiU_liVNKn0n84B>s20c)jE z148W}kI6B3bccNAB*MdlPYR)KG$EPn4cja2(+jn--U==&Te#|?Y8q$p9s zWZHH7))yHxwa(7LpvVKfvBi&2>g}v=%-ubye$^}_F~%~PBAtp3!wZm<&)r134V*{v z(K0`}yc@e84*FR+VL7$2Z!0B=+$0Lm^jFY9neLf9i$u+f*lY$&Yqn`?9=4n4BTGw& zW|1xft#3P2r!j{bIoSdqo^CPgoW_H0`paU^#-}>c+zW%w9nl`FqcPk&dm)E$JnRlm8%a2t0^6Bh{1;l$s{X&_|*) z&7TAmnc@TYPar4iK;QxrSw(4qPfD%q$1)fA{G>GXnBYo2RrEGDC{x2-EJodxx1C3Y zoFk#{Ick){gu&nQYzC)K^!;4_`&Td01%OEd;Rl`Tk7%2iRDNhWj9Y`4w!@|3nV z0i6B2NcaxZ6y)h>3UJx~`fc>RfBV}Vh+?_Sxhx4D+fWLLVI{`klf`6sQ=TvGh?mf? z)FcbXwL`_7i(jh)f~8X;s7*-2!Db^2SMhv=eh~)8Vehp2&*y_s7AZeV7GNGznUkaJ81(ZXo%VOVl&7*(NJFiI9;nI_U`6++gYwe1T~ zi|A9UmPfYwIMNW=gq}rVs{40d%`v?>w4z%VL1!JuXc^ zF=I?M5gVJ<5wueV2nGzJ111kEIVt-yUnw{{7d$leD`Eg0OMj!-Hbi+aMWt9rgh5yN zt;6jh{IvzY!b5;>f?#N&LdcjKZAf%FzAjBNw6C@RDnU}wSEFQT{qhSO7;1^QB(J#U zjD;;9HDW+-bOS!JqvML7j85J@U&ebE1yAga^|};a8uj8GxZ;_|qq8Vh6%}3izlui* zdJp+b&Z}5Jg{h^m^&V_2^MPIm!UK$*BMeHI3r8w%g|4{;M@K;mdYHe)xY2uw=G8&V zYV8ei4cJZ0RI4N}gy*0pmz09oVd)4y4R?5}LkzuDsVoRciI^f5p}Rqe7i=jHJvyGV z_)$?Vx0mjzwT?L|s`1o{cz+Miav0g=TL-pG{f!a2OaE76^jY~Sqx?CCt+6JhyE4v} zRkEk4J)m$aZi^o*_gECqAv8obIfn$lFgJ>@1=##GOAa(vXPX6IMM~iZiNIQ=q+ISq z53s2WYqdK@t{z_vXBCkO^4G6%iS1OreP-K)2ZUGQUp2%CwP_M6bbzJUqW&}&dsw0Zpe}fwbzueIJItCP_IaK~=Dl6zZ}3p+(R!Z_JyPjURQ=i36g<<>hy z;<=t6ue9t4`DlB>CFQa7M&(YGGYb(ss#iQp^j)YLW+` zKh1|GtLa|UtdTPzfN`F4akz<~CRV8NM7qd@gp92i&Bc>Vl6~18^VocO(CMkG?LL01 z<65-tcQ6Q8^M8M$Wm_hsx^eTm(!iV79M}$154@Y>y;800Af1aIJ`JJQg8*uq#8i#` zw*sMu+;&+uk4&!=IxP2glyG%>{gT#gfG~4%SwtaUt!iXx{ZYXXxfTPuhIe z2X8$tbH=ELV1A5K<$O6$bLOndd}Uc1I$6*Q?KQ^f4gL0t?CvPS9c*pT@kbOWea)NU zE;PQ+8I1*9IX_JCmJbjnZPwl;v>H;xY@*X%1oShapX7WbTp?-$STp1O>3umcuI*V| z7p(1eY%;zN$vMxTXlyL{iF8g&~!h#bT_6sZ)c6 znQ*ItD%OJw?AP0NsHll;^*x%!_N(b{G?Kabt)}Gzh^FQB3jX}SaI0no2@MEn!N-XR zwacOX$@ZYKP6o<v40HpDsvE{%m_N47&(A^!JWoTN>G(rzRVZS36d z$18f!JDIeyQkxJSW7e8{_S#wG$4 z47EeW1sXVr{mj6Ym_4r3!z%tv8&4PKQUcf6+=yx7fT;+i;HWGKt5}o=^r>=Y}H*Mc#2g2oy`vQWA@d zM#nnMv_j?RPFXE+bmQg{_k$p}Z$+JXmk!P7I(J#_7UK&=KQT${Z(uk_nGt+w^wglW zN6c(OluGrm9BnOEfnT6#>HXTAAlHUDw4i+mI1Ma{sCpg`wkQisa}gmV-ny;ZV8C*h z(9(X#2ch6d({di%7xxpo9ZXXuWZeb*fK6zr7%MVUKGwQg~CuM2OX|+Rj_}0Q-1ewM$8ye24jO6 zG8c}9=fm;o^<}T(=yumR8yIxCq3yZsvN!#4L;To?E}f?A5BdD~+-F5jNi_w+75hDp zUTbjs(v?-{&<3{j3bH+zXf2^b;*u&#_F^V2b&5Ca=2t`;|ZM{%cbQ{9uPQb0D7x68L&;P@~yj2q?ILW8~ut$9Kig0G=oXd-2 zX0xeIjnSrT{1@yZhVaAcc|y=>gei`6xPJXC*KOd}Iow}FRMy_?;T4Bm9H}d9Cu#ekitWVlDT(J4+f{UT?bsdQ`6sRL0+v>$XqSKlF!2Xi% z;z5EhJrbpJSIs1%2w<`AT`bo7ucqVa*4Ey4TjV=39LJnQaY6}vPyI}gG$LY5$;bI5 zO4%IV1-JeU-G#|G-witCtv`w>Bj>50EQo1F_9OY`HCJnPgLHDJ=f6!e2`-u?2?^5a zJd1C}g7_>XNgPndVPh7h*~Axd$~-bns1NV%VtOyv^-qp_ryqL=N@6L-z99ELCt=J* z7LR6vhU7jLV;BJncsk1h3LAwIzm@yGg=*lbKN)8E{U7pRvbSCoO%ND+; z$rM(puN5bsXX#BwIe+7?xx^=wX06?Z{s@`B`rKohBdR6V#oAQY zUcBmpAGzE-4fRhWk#zDT@`gM!IXF3~!2Lo5bxF8>n z{&w9zIqhBdd#CS)@5upq{^A)>ASY(=oi8Zaj+vBE>0PP?S9Px35L+^T$_cWT6CVQ% zunN9W?S$4;h(93&AP7Gh^@A}DJ#s&$Fhgo*Mu`vqqBKd;`=s;6 zKn{p2`Jh1qW)jt(anS9MS6#ws5_P*3g{yJ5&;bi20R=*?3jQllUWy+^fJS~Y%Tb^sCp#u5n99MTMAtxrZt8r;f61k6vfC|~m$ zz4?S-^k+Ap{4De5WLq!ikk8N@mPkQ*vA_&N%1eUPVD=hqK+bS;XrA5$m^z2JQyzIM{#3D?C$AwZ8u}G+E_^;7xaY}2@evuF0hl4j| zB66L52p5?39X{pzdxwtkin%lCb`{OT3}Opl^ac`W4uNHybFS0zRs;<+T_du-aGeAA ztpY-~D{a{|zcM;W@96g`JOV?E)XFZ-D_GO9F}V7wvf)&I|KCez=XWWc1P)Qa1Xp`e znouN=FPF{`9CJxHW+^x;<&`G>)Xn#C&3MOxil2;%S;h(;1NKk3oE=kle@Yy8+NVe+*^Hn$+ce<1VSQ=nFlGHGX~OPRhj7(jup&Ttk3n(;{DS2 zjkbY@dTk@?1nq^4*6^0`x*WJY9g@}m&VF=r5Yot>CF12Me>}uYPZ_cf%JORyK5rHT zfXKQyJ7+%tE)F0&O28{2s*vbYhA%OdkV(RqV@I<=>oQ(!F6EA#JB?BY1i?>}l*Qq@ECGd2Y;Ph0J8N8?!6~ zx;7anr*F?R8DB#;1MrzLM6QX}@zIaNle5z{{d}@P6a|))Ou!sdKcpFC!uodxr^XhX zRSGQ&Qf{Z@j&}|@74H=!*MMx8G63MNwM8)q2eA;7i2QXuJT8rWg)1MYS^STb2{_nF zVs{tvqnJJXN}S0zaEoKoZa53_saL&O;m0lz+|>pGh|h2H)37P@7S$u2oaR-f0Q?4GA~iA& zrGcuknyDFJT9-_{-L-Zx;O(=K8I^wWC$ouL>}Q`_^m)ykaQJO~m(8%~eH@0AH85(E z3@M$+N_^1UTRFpTl~;kflWE|TsxcM{)l_6`#}PT!bl=mcPMe@ZUP(2Op%Vx-&b_LM zR4GDNhVRLfgM$LW>Iqn#tMg(-l*CilY*BS1#eRC(g?V*FUcJi48{Nth{+6!cN}R2c zy9pkftD}#?&jj8Bz)8W!QuVWz)XchTLh|i=&AKFZ5lX$>Vl4)Hky~z%hNJKfV~3)G z3p&L+w-z#PsIbxPfF$&4xpIS8y@jNRkKL8=i1hr{TGfk%d@Tk2FS5RxOc!cL83l6_ z)T$UIX`Om-q2}uRkd=lA#!p9KUPxNfLN=91q+@N$8DeSdun;~GDI1tN)&r) zqDLAtr_be2wwbLZ3Cg})%uNZu9BlKZ<~29C#xO|YXRnu^<`~W z18Z{H=Cev%K|QdEp|~^u-Lv0jzNYRo#L&L<%SB;KQnEToXG}C@RfZ@tTg|K|D$OQr z-I}5`dwQex{B|HM8>?&R=<=e${Wu0OO#EAr0Ctq65gel7te&Cd{X0KS?BZoLNT32O zWCdg%J-jKAEnl^SPD4S25K@!3l@`9o_f4BNy!4VE>(+7b!q88^YR_ zD%Yx-sq5_HJ%qecmk&PToxHVS-&xw`eu7H28-=-L@lljo=>+f~~x zN@3M*UdUI+r4$T%!&nMQC!T_6SSoL|o)+6uy&7%xM59aY(m1SYk7_&v=Q$gJ5gJ2G zKtJ5e^Y`c1y|cbYv`sc!a70A_rHq^| zl=$pc&BsP_ZDS*fp1-&zsHUZ4NAvYsx--oO#m}ncFA$*W6lj*8HFDoII~!_N&gUK%l5NMgN`H`*1oUOB%Y%P2Z?I{T z0*$~Ok&;^mh8e5BW5{XcvJF$~`D&r69CZ7&pxZ{6-7Z(0qW6j=TB!q2ba6SLf|EE zGNFiO!(2q@M9%kh!PxHYl3Uo|n!PvZAT|rjzik1@5S^#-!t3bPq-D9}EuG_KPg_nY z&s(~$vguOEw7(v-^}ZF?>(xt^GFQS}xGlO+V7Rlf=C_Ju^!t9Tow?TLyi-x!or((l zp-xa9=L#?j_D7AS57Q(K?Ra^gW+95*b`~|HJyI-?W%$ZAHAU!~eslXpqqL=psXI$+ z>O#TF3rZcOil*U1@|=A8taG8(GHKVy6xN5WP3dZb>tYbK=e=$HRFz;=w5`mKD?WT%TATD~nx zuSy0kie=&sD|gkjZp~GxfyH)gc2MTgv_ehUt-HO6|Ilb^Uuf-;UGVU%V`q`M2B?I7 z0kevp+^0Nm$IaW&CG-_k(WKi_nkJ$@Zv7XvR!ei!Fc7}`SL~sOq?2jjOn^YA9XfP? znQ-W#7ujCNn#e1oN74-Czq69OPiqUNvO z)!u;(qfnx%(b&%aQg~Ogr_Z>R1Rpi~SZu;`%8$!+C8X-?&l5=wO%b^R)>ZeK{7ita zNEfb{CeDBb!P2WLWXDOTf`>RikN4WAoHI@(Wg%Hj$RwnJ)^Nf$EpOD6eH;b1_+aHQ zcpLg8c*T1%j2a>sZX%2kdpJRb6>o$cKz&dhLV?4(149?NX=)57Q z#d;#@3YzYT;xnl+1DGQ+uAW*sn%+^L>iDDQDN!BygK9i3aHIpR%$+qk8krI zCCq2qeQ@p4I5xr@+Ec)N-2=LE z{5xc0E!9S^O*jB_{52RR=z`<=hNcpCO!BH%`Bo6S?4yAjPCC|h99@gl5QcR}Y+Xu{ zw(Msd$J8K982eZ98?{*5ZreBzeb-k^1Gkp5-WYv#>ZCz7T@+}GZWDALk~E-Y+9D!} zT9UG3Eb{L=yhx@lz69OsB`!JF!^4?j-<{`i9t5M~0FL1%W)kKsp@4sLA{6jBsF=d_ zI-T=ujcd^(Sllqx0)Rz$*#NhR2{ zP;>?>refT|3?wf^MA6aAL_7+DjHFaz5>-ZbmpsjRMl*%KGRYHq_g6usc7GZKh1?~0 z^%T)uOWu9VmLy@b3$Z9tl&CgNHLxc0Z!{NF;+_NoQOq%0_{TXa(R@z|6(d52B0379 zgh&aO##|XT&?nTJNhlYBe*?fT7i>usg`V{;PwT5`ktilAzG}MU@WDQknVAK=jgyt_<5|)rD(#35zlvDPEtbyK)&Iy8GmCJvSOs?<* z(6ykd5Sh~*+3brc(iYjAMJCRNhX|>mL=ma5nbFV%S;jcrIGjL+_hDd6+OyIhn?v}j zlpc5+`ctvsE6DI#+L~#+iwFOmwSeu)z!Jtd^qEH+! z0+t9xg`t}aE4Zw}bBk`@%puA)Cr+G1#SMGh_Rw}7I!0_Emtpe=osBvo+d{jhSR4FX z$a7a5YJvS7)2t?@>l{_)a)^Qs?Owjg3?h=jlsYEU*|tnglshv;H=j3-!zt%Ut!^~a zcX`(FO@F z#eHP8HD@1NzZ!dc0<=zda`k1g9Yik|T3I`-^)0lj+EK5J^+k-RQZSthQrEh4Cazn- z(iD|uLN_g)nCPbNg3c41E@Ga{kY(X(EZlQ9^VF>V6iQcKudT518}Jsy8a=wE@{6xx zIVbo$Y?~Tmtx8N;ZYJP$la69)M4H*PbM}NAHEGMGG@?viNXes(m|O6hO%s4B&9GhX?Z~6U@@=(t-!KxiPpu@+ zjbL~T$nmffE<7|!qS#|j=?|++?-3?v&|7Z9xv6v8d%VXuG37MeWWMZ#a!33=1)Z5td0cQ@)zCX*dOG=sU-uxT&tfZAwvAXa+6 zi+GXY$n4Ax@a6ROf4C(58{2!AY=-yRy-{!wBJVW7?K052| zfV1;n9Jg+%gH|RfbJevUCb8Xx8#R-|{nm1}&6`y_m@<`no91MbCcJqAFO12H$4DM@ zhMmrTK@qq2?l4|q`_lhSL^L-TQEXXF>O;_vP<+*+&tzTpT0L9oa)4#QR=9DSs_pt^ zFL>G8&%M6ja2%Jv_E+{j{kR;8+Cl6z?bM<|=qGsCq3%D~%W3O5_z%Td-*4MC5PtVx z!2v;S7jA;RCUw&wYqkPyv9&>;0vI$+SwtjKC8@aSlK*{2QlcnXzwBb0UmQ#1@xHt7 zj(3;Wmsy-mCTA}v=q0+1nL-guD1z?{ON~T?bWG8g$21cB5uTBIyrrkG*sPzCIl94X zMmhRZXvztr61|S>lefz4IVB=}Q>?!c(u#}nBtb-EkCJU;jWFM!gb~UW9LysjQ>>Zb z3zQ`k!?OoQcXr>0_t)<}eR*d@SuJ&pHQHf?HcV;B*14t|v|~DkH-JEiToMWgZLG#; zlL^NuRRF>xy1N!>COG99{^Cj`^zN^mDs%kBWRk1Ch3~!-nwgb%@A(5x*yc)Z^AuM2 z7Z;-?d=Ohkf_>l+Yq8HXlT^VTg)k~LE6x8F=Q;+Hj&;G=gd|ugFK6=i1i>eh>;Y?v zPQH2MwZ~X%nr2!x9>;96fm4?#!il1-FK=*?tbsDHNXxvr2DBHT88}%}d0i}Rtg&{* zTFA!p4UKS~=*ClSsFScCw7DF}k*0VJlxfu@1yL+voK|S;0_z0x0b4^j;1n5}@hxim zc=JIRQRIJUfv~zaUxvZJ2iYp}X)Q$Z#JGNn5`py-Hz88OL{?<^19PtNWo} zy*9TFsr;LhKcMkQOYUL{I?IY6kWL^AL0ZDZWE-Fg-C63B80bh0dro^bWa?uXF0=VL zG5~uO^}*Gp>KCf}^i;9PlTD#+kG4$**yDSVD5@(c21k$y0GXmm)Xw@aUz`N^S}kzA zhtgbWw5G@<(=MFe0o@M!!wMK6lsn}}C)HI&a4A6s8si!NPRCO06sli@=sicolmO<$ z+I?Xv6v))V=&>2{a)IBu*s0jG1?13KVTjgyX&$UKAFHlmV?*QF^r|$1&y56gu!hle zAIIr*UggW@Nt0>*l07Nia}dWu^Lbwt>UeK0D!&SI{kba}^yY%UYGUd4>}W2QmBA=Z z-qdP?A#M(1DDKNngZxxRY2b65D>dr4Mfa*Dzu`cC|86V+H4`93QBiEy>DB>_!8=nQ zjk=(&LWy7PX?uP=ApshPvbpoxbD#yK-+o#BJ)2JF=-iegy;L~H0ONDg5CPh(b6MKg zRE&bdvwZc;3$62|knRJThl}VYpQc4iN0jy;utWqksbmsoPr;p07SQHD~&)}r< z_7{O`nr>AZ+Oz=sY;IFrrA%G<(7SHMMeY4_kOvWkBHX6r0x^R^6>~zNAHBPk_yO*H zW6pL1U1Ji{qHeu7R{aHf5l9;Z0FvCOU8A7JCMN0kH4(WN=Yc(wOR=;<0e(!sF^N+Gx5emfXZ zX0I=T7|(L(2B01(`hPpnD9YACd0eGfGgBc#y4z=Cx-OM(x9)2Cxnj26vZYn`$kSfp z28B>@Z@ze8m!n^n%Sy)oR1dX!9|d|Hcwt(CVC2UPo)JUc=O~AKEyV^-sE+DwtixsD z6y)%7z@RxCU#ak@f}q0LU(PkAIX&^3;_ocYQ?O9Fh7g00DW_0Pg+Cc;rWBfS6J$A0 zSjx;8aCqmKtG{cq2SHy|*84}9G{M}~A&z{+->-^YP$od~@bk8|8lehAe-wmg_2V`A zwL3Dqz|5u}JI(DoJB%`+m}U>u)mKA-TJB$l1H|Ll`(Kj5jB3VEK6G0@>FeXu&JKx>g%nTRfCsXbrk_eScYFan*!%Tpg$)JV<=K5K!fU4qt@0f#9 z-6yY4kn1WXJF;AWVp$*G9>(bHFij?fro<3GXuMsgV2e-) zN%Peq+xDz;bVo$abTK7Od+EKSzVJT>CxJq}{CuAL1C3KrPunmMe$THsp^7G`Yu*cGAO;fBgf{3STIHsf z#=^BT+o5!$|9xl2326%3{F3B+ci(s4eL4GF7G)HrClQ>$tl$Q6E)eKhGHpTSU<-tY z?K)R-OR?;Ut#C}qEEccNMQ`d|$wLTB|H%j|?uhJa z+!l006Bt$L3<+rI8K+Ss*%}QE(N6SurPigAC@sB7qXa&Fuh2O7Q>TijeUGI^LpcT* zY|*4r!OxJ@NO8d`ThMs_D@Ph-f*AvZn)5JlgADjW)k_0SAo?8vol^5>W)TKfS9mGS z2K7Cz@P(MVYtPmlVnfSgYjC2-6$~1(5YCLWY-3gdGf(c}B(4nVUYCVZg1!e!%vmKY zbh|V$=GnL=8f~R%ca9^FAUP8TKj77y11_oBJ*f>Tk`}k|d`G9krbf(m;5br6}k+3$^8=-hmkB~UO(pLZ+g_cQ&j5|Ds_>r5r z^FUkLPwL==l+(TYU9|TZa&FDc8GQ<|Yo3sHxSD(O#x<8wlbM_zaPt2KOsCT~-~5vl z93Ssv|CME^9S&=h(Bk#=qZYfyM!V<_%~sn^+dvR~_g4%EHBJPCwl5U{nihpN<&uif zzBDLW>~*}Vy=(2RLsQ`2JG;JM2M4ukD%CGUGqW@2oH=WA@HPn($LV$)=)hIT6a*}y zfPWJrHHZLoNMXE)1Hl&<^S+ZA-Nj;4?|N-GAvcV2_$)N#9-|Tt0vqY8?98qw;-kF& zL`d5%NTUcmkt`&eg&GL=Az~io3J3E*$e3s*_%MG96+D87PrTkK!QTBJMg4Coxq>qGU8V7I7jtp<~y{`i@eaq`I6rwj)`LlEsLzIX~q1D?s|rodftJlFf;x zu;pb;YB2;(XHulxUrOAd2^te3F>6yx(NNN0IfNTW9X?{_gG4yS4+|916j?FN(}5vp znvsb8qzZ(k13_Km-Mq9o(MQvg7>pVC?4BE&Rd}GkX}+6E&~gXkjOV&MlCE^A1fO*2 zW|Y$#bT%5Edqx|WPCc`1nR?pI`quy+f|<4rMXEBOND(Q?qSPA0->%zsRJKy{Y#I0O z9A%L39Nr#lRX0!623E(v-G^3dyEtDPUWHOGdqh%zYG>xnO=XM03N< zK&)GfP$LVn9G_ucAx}=|+x4UWdh3z!ADAHJzs)WY=0@4eK2?-RFLd+L6}Zg90&oKo z;YVxZ@X+>XS9+SqB5;?qGlkccHaW%rQNdC_<YrQ@H_T5I3BwCdF*Yt;825O`erV#_qkdm(fWjMAxRilJD;e}uBeP#)+#fK|GmxK*45zhe0cHhY&tmq za`x_OblGax`kUv)3vf4z1E-^l@#t(Y{W`cD4@VcRHr(HX%eZdC>XIXPwfFMn-d?li zO7a^O^5zYLga1qmR2E5ZPWE2EzJAl|ReG7wWMV6dY!=#Vge0j>C9ipE=O|law!gv@ z56&;8lh2ORFc8M?d5Sr3=vJtG01A{{ZKc&B7O8OCi|b4h3ukQE}=!Mv(m1AbFSaHP~@6qEokS5VA_sBQ4Q8;q$pr&T<8@WM=!x! zRI+z8cq)DG?{02C>~FJFamk%xIH?G=i5$!!G1hQ0+{uYd5M2ry1ymQu>#8EvW0WE0 zi5_oU?;Rnryis%(A9sb%7+&RACg0;0L>_WFB=1d@5wlQZW5`fD9>yu0txDX<@xAD> zA~po~sSbmRojbw?j~G_pkhg8GjGas9=m{{=%*gNm7!C3yH5ycJ^wB{)PF5_38P*cM;Ag3UZGR9whDA69~d9#=p_)+}? z#Zt{~+b|5i>nV8HAq|H3-ey~{q5%pF?SK@+4!tO{Yzvb~L86ixMc#dslIBqKv;rM3 zA}NaBkG=dBhM-h4S1^Z%!6oRNw;*TGk%2nk!NO)5JHknN=8x{}LWaxy%v``)Z=FT> zNo>(L8)4bi&MF<>EDVibPxEVvbzPUe2SZ_st{)gQw&0zym;@L*ilb&n_!)w?T6#NY z_x0V6+v}UV%}rTVS@NJ6_Bui95=XbqY+Kkn9^^(8B+AiP0ctDbMk&;zO(No~=<%Ay zKxmOA!$jUbt}8yxwi1MGZi`|zDPRJhwF#h1jlkcn@B~f)X@u>mQO=(DOg@VWr(7KC$MO!=VsFsG zCr4nM&8Z8S2;0r*W#QYmlxzc~fZuVN0luL>m~`D(4$P#@TylYZQET zFnCOT?>EcUhwUnkN-RkWf};pfnn2#{JHirg5WwYk%7v@cvcivG#FUKSp`FQVK4Wo1W9gDue_@a>!`o;A^*<#*b?g6$ma414X&5a9> z)OiaL;wB*zUie%gkVFcw9D+cn8vm+p8>_}K5w?O+-1+^br>W#@ER53NE7(ho@;QJ} zS-Lt$L38d>Tc5blqBP3z1|r~pd%;tGr+ z8+#D7DIa~+HT>?ZzDi6aVp#0J!36t?I3>zhEN^PAuC45f=ALBC!VozSl5ctR)d0%Geipv~tyx=F+d3A0&#zE(GPO-Z0yA%rgm!vh zrt5S~yMVLiAxT-nmSe9vwnvhIw57j&_Lk(t7sb%i=7Bht_Wjeoh{;(V<-OkcphphK zbrcH{#t9?vol`DJ77`gTajT0;Tb|*GuV|2{2-7(c*2k z&a;%I5}s0#C2Vn_N);yQR9! z5_IPUr>PJSmq}=zMqI7b$;Lgc%?G8yPRDo+u18A*`7ft=PHz*|*z+!hKOwlX_q9jh zlk@nFN=60&^D_=l!D;=ykeh@FG9~k+ZRJV=w!mL%rMLw=08COJy-03u`~+O@dTLe6 z!_NT2d^p?D19!Evy>hxG0?#w*N5rk}5d=^)_{=tBIwJ!JX2HCQpr$Y}$Gyv)I7P9O z@z~RU)t5p5eh$dF@M#Xh`jfsweSg*`B4>U~;XFi?3&1~F#di=m$sQ0AimoJo&6zBC zN)YVn%Df#{T?UAeRnIXc(A5NB0x)em5nh5NIcKXI&hi9e>N;b0{%HZ9<+o3sJD<#! z-q;xuXK;)!2Y-iW&CEm$Kc#Xk2~SS6;A;+G1Ihn{2nax05v)epZ!O>@;bL-X8S2 z2EW999iTG3>Ns_t{4$Cigw zt{&a4`FYRiI^&*|j)DGOz=YBba!vFm4Y0X&OPV1$`URn?^KR-jgmNXx;64syWQ$*l zlhJfK-5Jt|oH4|4?0GH=Lx3b4hoef)HYIslqZ(v6ORwqblC9VSuFdJ;m!*4lqWeDR z_zqr?Zv>x5-a(ZRT3*3gl=DxDq_(l(95D4B!1JD^D;UdadZ~sJeC0$vq^r8h1`g04n&SWiUb1|a{p&~O*+--`M?`5DoORK1ACYB|r55CCds@ljnfb8)m)&5r7_^y+Vz z>(4q{PfInn^>>EdvUOgpEl;`ITCG)1XjDOU@iJY$@}}^83g7POw}HBQF|69<4r|?q z%iqs0_o;;0z}_yD*S-J<+RpJHAmlwC=R9B-7EoRxzzU>+pe&D-7Es=DJNW+ z%2{r*9d%`q8V#51&O0vK>RMBsutR(D`N)XZ&4nk6u|2BQ5G zJ6M*a2uuBJQ@7!Y4|>`u3EKQ0EgrJ4wH~!Py=6S=oLS#Mjlm>oiiJs!CM)6{26lO> z_Cmzgg^=Wy5vquSClaQmd{wSMhot;vL|3O4{ru8W!a6Qa9fKp);Qi1(P>qoJ!f z1kP=YBUjmM=x7}c)dXV#gxz_Y)u_Kn`+F{yYs?05RYe=zcWUg3*)Aiv&UbgQNWH=L z@~V1QzG}CMW{T3BNA*niUHvN}U4C^&+QO0Z=q(oH0Gaj|gJZC)eGzWGUPmW*BeyaE z=+?bjZ=N4+e1#m<%hHS6BXfA%{;z=135iDg0XIlMDyBg8kSAGy*ZoxsEfrZ4VB*84 zme{s2uPXnWP$YF|C_HL3O{O+D*{akN&6)sR0~8p#0V#$ZdQogT z7ABL1L?;W1{P$6c(`PUg2rwONiz4+sNKa>N-DX)n&R`7pwGB{NhoJA)cmb|JYJ}yk zshD;eD}I|bPBb~@4~r2j%*rCc4;G}tqK9dfBJ*&lnH1by_4y0->AI?O4hn8}-mYr_ zLnSy{AO!`cihX0mGF?FH&}eL9ahvMC-Cp0^EpOsgiKWy=U~2-DHi);YPOyZnm0C|! zLEz38s6b_6oM#!C27`)tQuJ`mP0NHN`bB{qJ}eTxpudc^B;Iq=Nv+)PqtaiUA^6EK z72Qq#=x(y%`MNRI9ku3JWyz>SXF`BGRr|e@wv(r;!8WR`QP==)j&4aGl~T+eGtkv~ zyD@?=2(ojioMJHXifasyb4xXPDXREgoCleS+t7QFisRp5LsA6E?hV!qMFSKVwqYHxOAl3K+7>2@f=Jg3hW+08yESkNKYGv5`hcMSWU~OZAU(qKd1xt~wdQ`=4!7D|`d4lZM|<)Z;Ts7?=P|>+ zt(61MGh0W)$4mc_a)oQh5WrD7XW#V#HZ~Bv!^pZgwv-1ep5g{lK&!Pkk5ird{Pghn z<@vEdRhH6Qfypv7o+bO!DA>T{rPmi#z%*uux~Qp)cg93JAghQ)(aQr3i6TbPTVx9O za;*CW^Ifs!%6l#;J^i)?Kxry+9RV68jWW~WF(t~vFi}=A*{0-UcXjMwN9lF)JB6b9 zm~CWM`}XbSw$1hB&<)myt9Lu|zV~NAw5Nby>(YhV)6#*zHHwDee+}l30X%yApoXi+uMAC* z)8#51Y~sgC`*Km9B*0a+)?yJ`U~&$L;3y3N%Sh>zS)t?wWC=1_TMAtHyf2fR(bwt7 zmGUfY%q*;!fw?eNi^tsJ99F`{v_l;jm1~X!H1~`zgFvzr4K=arXm+F0Oi7fM{z;<} zoQ*xcMcoU6+%!dwo;hZY>1-mGED`fhdXc9TvD@fXDoCptw`Mj)y`+X`-_f9*NCJz9 zRL`A*7i!3I8?Q-t!H?f!gH`8LtEW(*_QHEM6tzw$l zwJ)&U$sg&+$qAA>q2S?xx}rnOxeXg}4{JdmBw4BLD;7Pt@64TkXHbee%(}h?Nsc-N z6SjNRGTKSCU4IFxN_i#8YhK|{U>7_R8JTKImH^Y5txdaImaEeK2IO=jg{0KP-F+R4 z+uXzy!obH8xW6x+R5Nf!iLVLnYc_JbyLS?s;(Tius%+0M(keY>xHF$dn`_zZziN(+ zwOSddyNU2KrYTjRTedJH5m#Cxx5=8^U}$nQ>!h+b$y8%W5kcsE5tejow+~|6x9R-I z!FyM3l-(9}V9@Vx)vu}NJ^0{yD8rvDO9L1gk0C6wG%isaEN5N-T~$J(*?T7B9G{^- za1`h?aXvl8#E~sHb_OiVl6BZ>wYSXoX$PCt3a4(wtl((e^HF8^;bOzB-3yKiZG}F> z?vek+`{>cU!gN#Jw`~j2YlL)sS|R>K`@F)qqu*f78r+ z?oFe)7iez^xT6vDUyNH0-i(kLCuwX220HMucIXWc>ohhrdNA5dZGKV#@~#6>umAhauGfyADQ$HY$o9<6>o>DA>m0vJ7Kx^fUuy6YZWlfS*AFP*Js~NF z*ag0zaI*^CI9egiejpwl;bO7guub?#ET2a3CFV4;eVW3tD=F_;E;F*@@Kmk;7^hO5 zn*{;bak5H%Z^3~?4g|hUBZh_}H%>#s{Wuyz5>SG)rB5HF+|}jz#pjy~p-Otm7lgwj zVc__Tr@obO>cFGV7s$Z~Se&IcMMIACc&up=2`R%M%82gH<1mRM8gYDzSRBx)re$mc z|L)?+rit+H?lM}Ez<174FAH%+$(RZ}Wx(%A#upg$b3qzwt{)M^CLoN#c^t&4_Duu4 zlGI-kE`o^|hx6;J>#sL(0yD`Jmu>}^934(hVKQ7(Q|d_CPKD;Bltz-eTcNIK5X6s? zyf>_>&8Q^qSBN1NLBxrqA5`e}isXu4SBQ@bpXVyxRHzPhNfvNPf1A_i2wXeX4_`0; z`gD8W6|$F-RV!jk7S*e+z!j@Ie#PvAA?J3Yp?H0uD0U|{ir0du8;Y}k&MvRcK3rYg zUw^s1y#Cy*fH=rwp6QHo6+P%#RJ`r(&MUUF$e}5-MF~&BnGc4R4os3xSStg(?wPhHl zjcqEj1rP4;CH`qRa`Np6^Xcipexqrx{24c=JI!~_NstYFqM%aZEHX}?xOt>Xt5Gv4jxuVCw0Ga2AUa>W*6`0tfC-$S|93We z!HrTuYeT3U>UvdAGsDGp*t(nS?aj7XxK%0asVMig{*B321<{vo$^PwxueC_H_TK(> zjvE^HJ2n17S{r)H#O7n>nWV=}oUV6?9m zRDMLDxr(2QO^W|fm7h)KE&L@zbk58|Cyc_^o$6#NwC&}f7v_Zi;&%CHlo4Wvpr%9QerKB;U}hdjIkeP4$o(D!t+meBKo!?mx0pS8a;kq*2q9q827 z>BsM7atgHXsG_RA>!cFW)T2i0)RKE^cARHw;h5{gOkcz3t_KXFD7(H$m62jYyuYc>kwUr}d z76Z(|fk+(Mz;b}89eDU}b?>Xj6wnW+yVGqa{}a{G6z|Jqw{@9GQC#Bgsk?<)#fOfL zpHDWqTZ%D?c-#BDBSDON)nuuuhN-Gt*~*frtblHpYtJA$F;siJR2 zqVDleARvpnFw!XG!l!2SS}pPt$su{FC%yyaf#bWbP_cwp5c)N2e+g9#$W&Ti!p>xZ zo(+}-RNuA#0F_i-Z`v>veb2ABm5^`{E!yiST_x0Nlcs7Kdjk|1b3?2dJF*==+U-B%EqR}9N0sP9OgH$R6`p>!bU{dfI!tA(BjXu(v_{}$X zN8l3AL=4Y-B~il<<53HV7Vguq^608FcfxERYW%aYfi5kS0%7u_m7B~1*K1Hxpmrpz zQ)9Q>OQVO7E9A7cleiD(zJHrOz096Ust~2mxQ9J=u$InSxhg!aVK03~JLJHb!U`mz zb%=NrMVfEXk%?DFi>cY>Mx*xhrkzo^n8}Ui>L+eW&f_?WQc2$+6n75Vo6(;L=*g|z zagWe*VfQQfQD_}ZV7{dD0aC2UAsN@Av<68cNY2|rcoqjlMO8jB1-3XN6FiWVWBpuc zuM+N#S|pW@>&J29Sdh5}F%rRe{0cio)o*85HW)+8r1ob!Ll9gkzEYP4y=fweQ0N8UXv`Zg74)PchVGYN_s2mG)iD)s5+5s&?i|%!)lhe&TlJs(k17R z*%j%PY>@tMr1K?3az!+5v78zSjy^)$+HAOKI%lt?m^^>m&Fs8Lqw zW<{PGOXI<)YAa(@SJnR2bd~sZw^{Us)sRw`;ke6xRSlhRYx(hlZ3uYC6^$nA59xzo zvMey`(=3;jOU}WRZT@lT8c;TWD?_8fpu!B`k(wMW#ZoVfI!B^PbaNoO`@SbkL6`|F z!pnQj->5WQc*sQt?;HWT=Xw$*50_(jIYt?GFL)?JA^6Q?at`elKDB$c&GXh|XNHbj z;}rb`omAUy+CUI}_g9P}Bp`y&zCsF#Qc^{&NEF)SA&siV9^+M)U287{RON&E9sRM+ zuI*r)HmSM~ES~F`nKOGl$+J9)28R(G!sm<|NV!0uJ7?O0O2K9b^X)2Ca!a!KJ6qxr z8GHLq+=X+t;3(lrS(GtH4aaGaoS4GrC|0X+X@9PC2$wn`AXfQS^JQj%$pi$CQ5s4t zQ>9nTawU6^3uGi)b9@MXpDxa(v-#AA3Mg&HEIcp+2{%^rg|nEz1GgDzr~;#$j*${2 z0r4P;BwL}OBAzPxdZt#nk|-_xlST;~MUgWv=)Gh`h^u?_iur}ioh^PZq(z-l_Sbwa zo%K$|Rr8`Tg+87zXEW;M2mR~kQgMxN#U(Na$AVhA*_;&Dk#FWWR2~av49vM)3M_%2 z<~cPzbQ*9&(@PALs^~`qbaKtt%p$bbsEs#!2kkGjkF(3$S$ni^L4eeB!!4Ou?XaQM zPD)Bm%9IJ?3-Rhuj6YP6M(ebMmY-WG927C!f>07;WE_whv^NEsjvqM%t)4C1Yi)gU_!r>K^fZ9Z zJ_Vu0{Wk@cw2VDya1B~22ueMHc$a8r!9DyP~-a>)U*KeKWnj zYcsuEx9{)X-2W9IOOgWEOC`L=lsRF`oqyJvUfASrjc)tH-dlBltll=}-y#A8>ee&A z!U713CZ2_A<}P27Kd`6T3ZHy3fw$FWJVw6(jZ(o*BQXrU=PP{RP%6}ZKr5(JwGtAl z5O8BTWHO#fM8+N^8A^rt_jN*t)gnR3B@_GEe$Q`~SH10(noku>;la8Hjq?a{_c|ot z29ia%KXeV#L1N}vw>T4U#!t*SY<1<3;Fc4TaTs9Pl*lT6)XWTbmq+}TLuuCx-h<)( z5L{~$XsW?GgA`>jH5@vf9Mc8#9<{_?9PUfq&GmY-yWiwig=Mlj!CptGT};7ML&6&N zE?LQlg2+QKD1++4c&-%b4x@5WMyM_TseZZ)n1e?Lw?Ond9B(`J3nrCt{f!{O_ukc zi0d(|-W13w{qvbZ21L-Zqk^9u<70XiFb#pmc3-o}2Hr>bPRbECFLysw;;~pyCg-5V zG|8q>3uoDua}oZ9+}fgfj^LVq1OZ>g>i8YcirN1-)#`X^>e%Z8_V{#4#V-F-6KV9W z{sOgA-*4J55Pr{JajRIHRQyn%p^OQERH;L#>}{KnaW2GaVn?2j41EBsVxUoI)L47e(GTC7tGOvaE2j?&P@GEq8bRw&tq zB11;8jliux_xv=T%oY<@%Cod7v#@0bVqvTntI}c&TVYemkOHGh&5y;wNS31^ z5w)V9W0e<5qO|lUjmpqPa$@wXSd6+K1SK(;8}0Iz35h3vPtu}Js9fKpF4vsAaV(ss zWA&M`Q&q~iPV`+5yh-k2L!>>9+M!hr4CafM&cg$RtE-PK7_ri(Wb2Ds2?^trWn{-d zyIq(2-DsUNksaI63pm9L)Eds@g2>79oTxj*NupL7yazz5&|b?zF}F3rmEgM@F-U_ zQ8Z|hJ9lBZB%(AUCAVR-eJ3*7OV^K-$#o#>E-Q8YY-#=W(rxGPs zieat@3PT*sv}G({Zn%;gQ9!;88l_Q@h=*C`RE;Dewu*jU`MU8A9m_vQ-eQc@LUiX< zfnk(oEgj3gUTAD0?WXSD^Nnv^vAq~Yca!|DK&BQ=LX=X$rXJ9eaWg2DW*-a^uooMM zm1CoLn@wQVFJrrn`D4{`C5C=e3sVasqj8mLiQ)|E6dce_a6GG(v72!WGi?=-j4yWW z_C!OXtVJfl-o>qB48n=oYX)+fU|u3&Z_6%X<3$o2k6_9ksT#DhR!uEFKJ8?~tt)UL zGn;l>Ptu6i#luyXb}HK;OXGC(6DAWa=5uH@=PCr%?Y!7e6)U=UdT|jxUH<9#c@H+G zEZ-o%j>R+#h6}HkM^P$8dE7i1UoV0mwhzc{aPl<~a(>A2m`a}d|Bf+}*NTO@qeIvk$T_wucu<6h+EP(-|x_gQ+Eo=fcBt zzH@jvIg2-Or!#!rL9fw2H$FuxKOhKxW1OTYTA_49(ByHuio!=|^FHG>89-;&-}Soa z3g7!AL?5G+gq}|lbh6?t@2Q{}c+vJ$_P>e}&Tf?j0rH~wG4a=%6yb1*0^cJc1;ODe zO13!lqp*kKfM96*;*$qXcXNGlc{{methkox2B+u&Q?&GHn)vrwN|xxsPdD%dMnI!1 z@dyZ7a*cG*?ov%Y+E&e@E*4Y-mJ%i)}S^1&g zX7CEpT`UN|_ZoczJ{yww z=`!+mvT?|N;{+VtV}7>ELXV9_YJX2Ec62Lm=n%`N9>Ph2AJJjN4MEWuP3K+CT4=%k z{1tLT79+35B6@qt&1mHzh zO&mw*+bJFo(hR{p18aBY= zMM@vd0Br&i+L$Q1aeF*~BN66>ZedM?P8iai9?_E_e?VYN_Mg+Mj^7}m+5=QsBqSy{ z1+HukRL!-%!y!6Ge}Un=MH~ewx+gGML@LuO+wm%8P%d<<@Q4$#W~=Q_g~eLbBe zvv3X%LlA#33l9c0ofPYV0^MHCsYNKl%z*)WMh_?&8MT~cIbqTpen|WZd~%iNTw3eM zl^y!0*z-s%1AxbC8Pj=}#)vj`s>HLg!=Dk&X2CCyYgM9zJ!$i9i3BRtHUhSW{keT!h}Ct2=8XR@Ai5Id z`vKbGTRuJKXvXKggdKMaBt8`Qh)*gECkUbkvg|4l#GJzUlW@N*W?k)_4^Te0$^lw{ zw~1m!1h;qIu3{?l0_<&2t#e*vLU#mfp(3@`;IX3D7Jqe>mR_6ssB1)R4xVS}0# zR(eH2HL50}>a<%KF~`>Wyx3@pAak9sSN4l7N!CS*1o*5XI~t#=6EW{<3b!4YF}3WO z307d(J#F7KX-e!7Yv;>?Aa{HoKUyws@DEAV$~&wxUueeXT@agQosFs}^eveZAkFEb zQ}o8fpf=j+yiEA@S!aK2Ve5w(sej#lmzOC0OjT~RvVEcF?kwi7%y+ZN|96M9`;iGp z?g6>-7ae-yp#kL}rNX;0XRtNyODYPxRctk1rN;YC z-&LJ#1I3hXh>uAGbvq?XR%z92!6{gR<_~<6K=t?^;s}MOGY$UWc$Etbz6N1LeBFT% z{PGc+J+7UZ6=S~?iWT^Dm1n32%a?YroO4{>7H16V>b^L65Nmt36ZB3e&XGAJ52%9c zB{o;}G6>Z{-v@^)c8Wlc1V1cNu&Of`<)HC{=4%htr3|?8MHFP)@HeqiP?VP+xzE%3 zHj7%5*=RWU$*^fvBjoG!gQNa8q3Vvp0{uWk*J2aFp7yLR*)|fCdcm{-#^%FuAht_< zP^ObBB%q;PZN!=IOlMVmx2Lo|u;#udu5~u7auv1ARFcfmG+!9ed0olpU^5Gc8eZ#$ zQ?rb=0NE?}dFZC6KHfin$8juy`(cnw)4jgmwRCf@qcy zw&Mc-LoI>|?Qz0RV7(w)vV+tODS*-s*9apT6VG4y9x9~N-L$UPb-0RPfC=G9q$pSq zG94gvHd7~86=0MB1><4Vuv$Swb5{vcrz^qzr4h949D)!FuZ#Z^~1g99fi`eO`TbRRSuY{yo63RsrKSQOE zF%>4N<@3eWXYxoDwmSCY-K3K0%y+xyEqFsddrk^ac9QCrU&+e{2ap@eDbT7Qg93JN zHDSC_zb3s}m0>$u9#tSD4+p#1jFSltC#GrT2Pr!&u}rz9Y&81&&E4P5Zx*-b|G1odJioXUCA*@dzqD)DcB8}C*Fl9l z!LnGBIB?qdlf@1Ozj_|xK4)0^fz5;Yti}S&oJC%AjB8lmOdwa_NKP0UkH@BB5uH`A zSS977E6dbT<;1elB=%z^aiAnr>g_u;(#JCR-nzCi!~GF!G5-romj#?CmPr#Gljkpd*vTj85HC`^=828#!DhG6X|ITg@3Sx=XXusr6YyjELIo@9X_nZn zDatcZtbyC65u%%jUy0j7xyG|v-bX2L2F->y`?S6%*&QJzf;r_tY8q+c=1p#C4un4CDj@u%h`2fy_6Y#Xh_GY*B&491Zi;3d(OOh%wkp`uX;7bW@pp=2}x)(EzP%E_ly}ywBuDB%KeH(~7oRSKh*D_7 z{SfOeVNR=G@yKP!8!I*umBSb=i=`5%ANdZvIM%lv!6+jT9j)0%@}4rr^QO@VKKrrI zU{q;!b$82|!5?_1!~gxAM&W{l?9yp5+8&zyI=Q=De7e1yT%3Qr{IHnZoKJqaoS>)L zmru9X7k3{nyH-??F32r@BE$7bSm?COgDqlTTU(U0;Fgf0^nmC2xOQS!&TP4ev~S?> zsL!Fw4{3@+k3=hU(Xihmx8{SYjfzE zBc7a}GjXyn-n!@*y@h=9^B!kXPS8M`JZ&}mQ1gw3YVJ0BROLRx&!(FWdFro>fd;?vWu{7J8?>hC^Auqd{bF9ym>2{eaRJ&ZJ zT!pf((xi&VWAxWn@|YRKZ7S2KOQ>#lkB+OsF|uN+c4~~FC#P*@c|2CH2x%AYz=?&| zGKN!NIIpi&G&`xxo6e>8T!K-!noo9$`l2ApLu=RhFRfPFa@#f#eb-lPGj2p?XnXo< zTe4kOPSbIfOyoCNqk%|JL`?x40JN-W@;&{K{#X|fDS|gU>4Y!#EEc#Ze96kw6dB~`Q zi`ZJO)c(#%C^qB5|5ivFF3!^wLXqtxTPGR_k050sSRjz3STc#5{!3vbfWk@kmWD%bZ2ApiD!Xge8J=};* zCOG99|Km!e^x-$ELdh~M&GjYocQ=xA~ z&ZEP@xoMhZ^@`*=L1zD;gdg8Z!vFn8VD&S$5gac5LTil15N#*Q*sc^Z%|uF8%5BaS zGEzZiob%A|0?Vc4Rpz1goG#SJ3t*qgsS#=CI9vg&gh*Z9 z@E|6sqQ1?xZ=m^(%%mKTov7&9?vUf^=4v*~ajT`SHPASH?XG%F_4Lp#&p&heT0v$p zc&11gjYcg{%6B{+IE<@|hT5Uh^DE2+9P>%4bIIFrYq;IM7Z-|V&lmM>w+k#BzpK1b zc0abbO3Xc_=|qaHg1!~>jg@+?O0np|+)?&VOew0p2E4hwxbWfaTc~>!BUCyx*|G3} zkWpjZkA_PRRS zJ-KB*oU-|%e^|@&%7GY(b@LrTFJH_- zYYn1&D{rRuR?lzAw*2q`(2VEKYV8o83#JQ;T_RSzJz08WJ33(PNDmZWl9%Jv#r|@* zb~XFP&KKnqQ@_->(31MRl8=cnAF^m@n|Uw?Ff0ppP8RNXJBeD;Sre_@;f_YTw|bR3 zy6KtN{ja6IQ;U?#B?+}N+a_25zxefD7~MTEzO*%aCSZVsH7xMN=zM^HL|j*an|yT>aKnk*qU%>_eq!f0VejA$RZB2u2Yn@_AUw|YC zWQn%b$)YAwNrSGxXFp_rY{wT#Bt^gHVAY1Fy2BZ(Imw=dP^A2;}n1@tWlqV=lW1Lf1IG>Vo5wVoyLsVoqg0Y(v-wM6g zKfQQ4K6}Zbgq3U_F?1VIl%$lE>7-&fLANQJ!wh&pNma%e7D|N0PX>cLT3`xJG#*{P zAd7?@>9c z7BF`Ym18_j^K=!nG^Nu*DnKrX&HDJ}HAG_n zWk{Ml<`$wEW|o)7Bo-kGt#P!OG~c(Lq08gbH?^ohmiYX$nUDqALpdaxE)@n(w|9ae z3f`TcjD85Vb`6EmepD1-^NV?!C84$!58a*;iAx+Y{4&E5uN4Zm08YcxwJqdGr2y># zZe#>*4GV_}NAVo#){XWdf^}BWa0|f!YL?j2f+FnVC#g2435#LTuokK}rpE4y>!y8O z(Rm{Bvd?uTv6|yD&1<)%>WWUcmULW}sJ5ub-4e5^%!MyXxOPaz4Js@h?YCa`urFXB3eS{>>U?9t|R z{UQ4EG)Zu7Af)t_7=%PQKu^&#wBz-}2u($SAp5da3iJfVDk`!XE~_eylyM3ybsM`y zI)~~z2A&LoN3Tm)Mp(Jt?0Ux;H&3(y8+ND-09AnKk9X(MOjIeOD}d6&@FLuKICE?BQn!nsQ+tAU<6p+7AI1TCw6|xt zsI!87=GAIGUh$xq*|5Uu?{P_GBDs#R$A}xLX=$HVU*9{BTkyD7~SC% zbB!9u-C??HzTk6Lb|B1Pxb>QYan%IG6#$=s59q0#OZdA;2fa#b9Z+AFml7WdiKhep zd5pfmjem~IlqDoq7;y3De~OYY9P_7|hOA_&O|Wr&42@sy6?KS2e^p=JD1__cYRje| zdHim{0NkFu``%O6>6W}AhT8YqgS9!-e+ylwGg?#B^X9TP$6P&{_O!EJ2UWdx+_fL> zO%E3+)Qdon0#uZP1J!G-*FBA+d%D4gyXxvbtwx}6xvlNOZP|8yOGJ)D)uSj;E25Ye zz!K+(5&ojhhjRHIY(y))fzsH<%3^lj#PXVnHYEiAK1A(kx+uUvoV*pYcAQ!gG3B5l zbK^J!mEA`Dv%~f6vQ}Z&C&+D%%i3nRMTo^@sc(=~$7OUJ?nr*%+e#7m*aUM)(9A^8 z8-GC*o%9i;BwzbaD+Z?=vW#1|>&!4kVl=wJz;B_I0v%(#HQqxiYr4?%-Dt?<6CBAE zo^Z`4oJP%iIZYaWgkKvEkY@@48*+VqS?^Q7xQWVZ{F&DVpO`8V zR~*u}8UT5wxEhd!?=4>X%FCVl(J6LXB;7Gy9^&q^Q>(g4GSsHs^9jaRgsi^I(E|P# z$`5gzqh-Y>7>$B$<%6gG6ojWXWhHzGbTxBq=>P>B?GOD?h+lvO-OINWQ17IQ z*F37Qg^9s7ttMcAXZ0c48A^CNX_ms%8ee;=1ShyBqoCePKEjKF-L*i@ zciQ{WS!X}iNozLvx6@nwS>f@=$ibA3@hoD|By;BAT3E>5a~~7sWEmOtBk80OtgK~K z$eooHU4`&o+FGsa(_3R%Q@M7}(iVsm!Q#JgZMYkT?O+2rcD}#q`a1X$4VafyKWB_whBma!-C`jCYbty%<|XF z*l~Bf;V(E9Ip4P}IF9QS9vcBmHMGGYWnE03Q)eYGjUcvY6?+M|Dsz|T^Ruhv*&tP} zl*S6IY=$~yNulZmYgh$ow4)9(_sO9ys>{WP#*pnWtBI|n`#E=!2}$&iGPihtirJ+Q zh10~CKL1C(?j`oJDd!}ZylPK|IE&vODfPAKerGqcy)@dmKuZUUWa;Cb_2y;hm|*Id z#5$Qh`8)t)pN@-zt;{d&?PBw4K)={mnx=+KZio@;!mM!j&z-Qt1sDNWPv}J7rH;U+ zWY_wP!+eG#xO>=}m^bqYwN~41;xG_>&sU5pR)vbvcj$$x7l~E3RK2JV+g0T_4sn~< zk?oX4RljFHWPfbOP67c+q0sdMP9`(QXY83{_K(si^}M|u4|d=-;u=C8Gr&0|%76^P zL=0|5Nhrk#ZSaG}64-t#;`5~eYUaYhd(GD)Ri!r+t8GG-5_OjE^EBUQ)qGX0V3 zahf7;N4B%X6)g$oSLYtp%4YBLzGNG@WEn?TaH>EO)AioymF)b1q&j*`#nGb@(ZO_2T* zu7>Y!ZURw?jPTW+g@yz8`K#fe^Gxih+3wgq%n{IInx`Ean}|kGH!5R|N~9gswq&s! zwyQRH7z}k{s?^$3A(chTgr>afWA-KQMrRJdSByM&R;Q9z<7z~5-~U2m(n+gPnfQM- zokDt+(kT4Cdijc2E~QZMU6)3{LXySr6rzcg9D=|rWs$Vjb*fN3!uobU&%)kpW*!6PXM;!US(0uvDrECcf16W-dlUku@tVTs76y!jydPT& zWMwQ4LmODPH=h_lt%z@eFJ%n1fKjQ4^*?}+#F~Am0=tJf*aXGJG^;pAv$EH2_wR16 z?rtA1``15?FQC29;rjT#*ogV`Pm43x_&;D;M8?%Ky%S?Ce`ibHmzQbO8Y!OM7t49M zo@bcr#islU)u|#DRMuxUk&jK;RfK338H=KPUV~{VL>mw+C8|WivULw@?OR1`HlS3M ztSVxSOkNhzd-MJQwOHA5+cp$^*H@q!&5&{>yU$VNW#V{}G^1qdCV7xG9+(6rq!hpc zpj}Vm@9Bs1$9e&90k}xA>*_%wfxDc$;zF-ZvUN5X932eM0s4JSB}!;Y5d3CXD8v(_ z)&yPNZxYV#VJ-RtugD<~Yx*!6p$mLN2}7T_A}pdrpjU}mIhB^@Fyfozg8qUFBQD9) z6h%C{7j(5&2(uWaG$KrbVwP~R!HRM=Mp;TQtld&_XZSw6d;Mm9`9_N}DAgJ(bcZF1 zsZ@gAp z;nYMTO0ksaz2vNRHzI#Q4#g7HOM~wN1RsM)e-6-hkh3O&s+dO)#p03q%><-iq%$DN zS)^?#(BBZxkD>R5hPZedBP;~IM?-ELA<+yimLntDqR^kAPOQoC9RMKbSmCf(SP|uk zwR@%L(YTU2ni^RTgXc5M1}=1-OKs0$k`-xptemzv`a=^`5=@S%oRbx>+@vHNjT~)H z(>O*-kY`sbnWeNv zAfaohV2MsnP=Zt05zS{Z(CNyd^9+?QGu_zazVFuZ2AwR2y)15*)2j=xTSPBf}Ab^Rg7ss?1XGVyP{CdTibD zbX)@b1!T8t1fS=>&Od&g2k58S%nOrIuKm!_M6|F);1CB(8wiMhEd7$kv#PJYY~(&u>#9CC+ep2w$rA^V{X>Yy3);w9U>6S9bzmlQ%={n zIL(P{XI~{7@~ePbF{stq(VWU&fTdYXkCu$u<53rj2hS2H- zNs3p}D}Sx(8irmTQ?|0n|I4)7qOhhVm1Rca$TzG7wsWxPnP5gQtq~3Af~Z_DwD6*6 zD+SGtYj&qh#y%~T*Mj_+Q$gY;3zfeWJ6&7`PMhUSFSqEOq%ka+AS=+DrI0saaC9XP z7FXhmE#cuP7^48emk-|Us-w2}1m~$TqOab~FVM`?yU%Y(phupd07wG#vX7z`zT7W> z&QQ}isoij%q9M~$6C7%@qK|HkXhnU}8{A+rVSExCR)bkzh)oBNa_gQTXzb!BBAK$~ zZ72-7cDxONpDR6-8}K59`&}|ztY8~cW`CB%4(_a5sy zm-@2Uu=xa{;F4M=^beiGKPJJrhi3%9b_b&3wL4$*Mpq?vM8+A`4coRt_QK^bK4T?2 zPIy8cd)ysW+_nGc8g5MMTP_DZg*&8f=a!9G$erFwK?ZTfP)u(+LA|EhI_iBr3&Y`$ zbla}0-6u4y+t%L53-TuJ;vU(Fx?t(W+;JamPj&lUMB7RO+b#E2-5SlU(>mN&p29)t zWoc{4j}#O`F<&^l1-RWw>W=B{>zzGeOt;!`zEp#H-^ftN?C*)q4&ZTk6phH=hW82W!D+GNpYWHuPTLqnG4{QI6gUO?kkmL)zv4C;~g84+qInhk;E{Y>cVC@T|x0dhq z+4IxU#i@a^TIw0m=$0rHGNmQENi+@7Ez>i213OS6kpTrkq1AY=)8S-J6>Or|(fGNT z$AVL?;f^a2(eVqa0?A@6rFua>g~46R`ch2{#)LZ;1RHid&At!sdBs zosdM&AY6WPd-hQS?Et>9%3iVh~Xr%4i6%tR3WDH zETUf_TtkJ*rOvkwf}hpQ{C3edz?xCXbSQ#{Y;n(C;?X`=Dl;jQ`tr-s^e+Gj>;X=Vevs@>atsT8oFjM5Avw;aE6pX-ZuCU@Q&{5AMGM}Pt z<6_XYi*AI7s>aYVp>=EJJ4-=I?(eN+Zn;Xfd6g%$O|rZ7{A_Af?!KwPAk_**pa}M>qVX;|Q%KUk5+-Q~1QlhN`XhT|6~T8@VS~a2 zwxC;WVAhsRq@h_}7Y2$QNg_QkR)t6_cAxGQ!>+#&`H_B&h13n}Sys>QrUB^p@ii_4 zJVA7&HP&+}0sFszb=PlYJ5_1k|!C+Ra<873gfW!01s{=V9`4nkh zanApoI&JI5u9vbtsv|=+WrC9Bqy40dgjfN`i zLRwUN=(ImMb;xMHz#VCMU*wFYV;^TiN0$bJ^>L=g+8!>{w*F0H^GUp$wZC@XW_>c3 z{|LXP2pf6TvFCrS1KE+#%dTehwKwZ0eMWGJmFb4~3LPJ#boO7C){Who{+A1PI=Y=L zw;I%WVWmWS*tF&JunHqM3-!!v0rJt0=x4vJ#ag^7OTEu7ez~}XT38#|?-iNS*6wa; ztf65uVG_`)8pDVYMU`m?h2ww%81A60CkA#=z)7kT31!?8o33QcYdP{sW2+_NsylE` zVI^k!m{X`dr*cZ2Zxc?BX`Bd`3`c86!}pAYCy0Vo5m5Dh`e04yT~@?h+;I^r2C;C} zMT>%@vTkLXs=it9Y#caF(73*}wP6OnFoo0A>#Y<4Rf>kjQ7uDwtz6fOb+wWj0e*W# zmhGahffJJTlgPpzbAOMPjxozOv2YuU#xX}$<52URD!-GXo^ubQQu(m%x1tm=92H+U z4^i0{itnCjZ!leUzs{VuSWa(IrFfJ{R@JLTsQX1qGab>gWgBmm-0#fG3f{t^lmgkP zuN0cYW}&f^zVAZ0vrDm&q7qr9^ZBJPQrrC1Zjr&@)$8+LhOa-4hHp+U-VUFiro&4C zb%|MsuO2@WRcEx_-R!99VE6F=mN%I6mgPc9!RB!!!u+(96+{wyZVgLw+1SuW<|A;$ zzDtUliY4QE0((K1*E{O^%6qn>d|Vbz1KCBDlm7sxXSRk5^U0~Aj@xGHX6aU3lW{3< zkl$Xx7DrDeI**+UYV#u0KJ@0JU}NB|@7VcXyE4e?=#7}E-eqP0e|;gEmc^?rkrx#& ze}K~Oxh+#Gen0wsbpGcEr(1WpDuY5Z6<08Rpi-sZR@R8Z9ffw339WYVEiX#=r74&9 z@OIqRV9Qu=_TLlqPKXHSUmPAf{{oFwZExE~4F0ZP!2&@e6|w!@j@=k(iUruxZB9QW zg>gPn_94=pc6V}S4E^upy-1c7ubp5(GWGBw`H)9lf2?nY^dyZc@%a&rMLkQB#{39I zmWmQ@@3Wu4?`7TC=cU%{;2&pBb1%vrm1ul<{{*Af+ceAaSC|id~!pUYJmKDTE{z-r?S79(bY9?F>&RT1+XBOdt zw@L(av!R|+t0i~Mg!S6hWOc)B8p%7C%zK0&?z(X88!h5nnD@Bd>+d0g*Uw#~;or!q z`9a2r9mkg~X1S*_*@i?#k9J9^+TF}_0HvRhR3@X;_c(>qYlSuh60VVbBormv_DFK% zN|QGEkfKMT8tYg(=#XQNdZUc6ho5tF&>;tBwQV%6jm=T(wLv=D6ssi8-`Gp%Pjg3z zFHJa+^mwN=9Kpa^1qX87I79`^4L4i_RRESUTKqVNPBOi1DmoU%M~Ld5r-?65Xx=n# zn21KIQ@WPWF6$YFOPi8(icB91>?eYjnvo}nAe-HnJg^(hkM~fXZ%UDR-<#Qy-dJ?)T zPR=|?zOGPjF+COn^ToLgA4rlk`*s!GvsuR(*Mz4Ier*6r-;?7iPTzP^8@|%6V{Vd0 z6;?_g;$f!+hBTwNr{zncQ)|54bqxIw7!|%se>85HEBOnSHR|b2z+!vB-xtm^%#?EJb#cP{if6!oiMrNJLJR@g6oiFJ|sBE+>2!NxM%m|I#0 zXJ%eE@qU%>@IEq8A6-ENv>sk0hLn;`Z&40U19 z(#hr`ks3+Gb%*@-9Z5-+WXpE84A_hyw#DPUJooVK=(p#|B5AcwU$@9>GF~u6LKXqR z_k>DKL`d`k$Y>RZg0JwI|3K$(g2G1L^E>34&KPiVCp2)Mfh2E3`{Y8oJtw}1-(~XG zLRxiU8b!nx$x5>MLKDgZ5-}gRLc=^1GNzgd-X%!{6rVjZSlWFz!>hrk(ZHy(Ug`za zWJwhXn9`EXQVjuFGQGeRj6jK0`hbQ4>+xx;#c2!*gD4`JT!}al9Jt0$T!{!KV^A7o zztu|7^xcQMUpUi~Yl%CTLOx6`l>({zcC}f_kSD2j|A!pag=ll%p4(KLP1#rX?Z7?m z?YWjlS^|v^GvrXQU$vynuEa5BZm347?}Jj9)V?8-&GZFL^#Zef8B3A+n7R)%{!Yo; zg?T$sEKblI%)0R=KiL*5}pId*n2)L!hZpSdM)9J5;kMsPV8SrpDOUX1wLbM>G@%zF3eNNw9?8J^kV^U|w zuM1=z_7zmMeh7x^A$AQ8%B)Pdp+4sL9}#pQrI3y<&mrj#S+;f*lpTz{5p(93_&PR+ z&Nz}|iJi=lmp)>tq%&-L%Y{J}#k4JyMnI~;f}ik zeezrum%-`09Ip>k`yXVwt@ijIt2xJJfbH{TYINpDwb$%pu9f!cac9P=DbR=6bfi z5))fs+GaUbuAaG~-M~i+#7;)4tQ0A);(DE$<%(ox^GvM2J^xKW4ht4mN>?HU-Y)d2 zj_GC5KwTG9y_x|21>g(QD}&w!YNJ|(EJR5d(RoS7BgmOhOt1FqC`9Wz8e4dee54P> zeoKS^YoxtH<45eKWG%d&8LCOkE+R$N%yG^NZI-qSp@zKezBx^-j_Cuertl3f=E`d~ zhSTn@ZIM^6iZ5SwZ27t_7=Ls6sT)`P%-#h4asrX?VT1S4}Bb8*0{Td)1UkS5?E*da1Jkl7uh0F3-L07_~O1fafSD*(?S`%^=k&Zh^QQ|u42 zTYHfiuF8XikN)YbnD3b-TrB2-zTH{*W8rNng=Q`_ZLL?KV~2@&Q3Rz zI>~RByRXr1Q)kO$<5u$7=Bf1;wN+7X+c*q<_pjhX0Xsw6yeCW7Ug6;abnCDb9S-df zC^j7nQzS!@odt*d_oHMdRh+Et%LxUl$R9tFA4%!sr>d-?X!s$55AaZO0|gfd^uJ=- zf-1n42(!(qP;x_O*)O)lO9DH5k`3T9TX2-{O<9x~M-3kfe{yYFo6AhCt~&f@r9E9y z3jvv`HkvO>3ryx9c!tuDV_7J@VwNj;4wXPgXAQ@-x4WC(re9~Nqw-POl37?Y135QV z^F?hjhc&k)eW47Ds&$6sDEAQ$qe!w98cJfH(etfZRZ60?w39{&e11Sc8F%Wr(@OJ(Sv-hp_o-gc33Zvw zd{Xndlho=uvq|9Oz;xg(TZcYb*FhIohuR$aa`s1Mt!2KdVku*2On zj0;~LRrwN+dI0+4l9FbWM1vzZTr;$-3+_59MEU{;BspeElTvw~A|O$mpQAy& zP=?#h+Z=mnpCee@wssbw8Uv{1Xql?sUuQO~4cMTU*U;3ilUA(grmcADHk05^iV? zlUX2@$|*yk3@%#x6x4?A**?p+nLqKR*6ATj7AylEp|tTT(A4y zW4XQe{j*OYl-sSYJvswpnXSz&wS^n&qglVWat#p%a=t^gZ5l+irME~jA^H^^4x!fq z?p3ACVX+DCI?7(jf-h+{ruXz_!5XRjG=p?u*YqUXp+;xLZJ(Y1oQBVJAy>75hKU;8 zDQgtZfgU0MRKzA2O8RQZfO&fV7Aqmt+C3)@YmO@G?{=6>Ca2o{RHdEK^KP)_G=9XI z#H1NbMSQX)-MVf8C b-5#BIoszS8`t|YYh@s!Up}{QuPQbTqwt!BC|2x}Be0fUc z_ek)knrvUz;a+a_c(R~qzRCsNDIX1 zB?$tWUP){ulHen$QTT&;?;qsHx}+pqQi2vJFQS&avokxC&OYcuC&|fi0>`i_goR9$ z2=vsQ{o`+R+Id2@Ripdw3GFb6Np z!bVtU#M(RDz>9DNosa^nyx~ZVHj(j3l1NseB@uf?_ZO^!&^$9qY`vT;x@oXI@c$7_D!+0?e~ zoipzWa^%zNFZ24lLRhhi87yhAXW!AN3eQ~|nMriZI741CYoSqnAXHB+`I!JMZNxKk z2uHjfP964ZvYFhMJe0uWBPagOc<#~$a9=Wx6*XK~N5RqQvQ@L_V29&f-60MltYf$^ z7$_WMgFVa)GLlDkjm8g7J<-jZHFYQNGHp;WWyY{A9L37I|k7qmYU9wC50IgHOZsITy zz56TXzzT|5xI=+f6jUTsp-tIK>A^S?Vl}ZN+bKmA|Gr}Id@X4ODHnrguP1Khq~or zI(vv_o+_wxDR;2v7Gi0gk=xQ?414KPI-v=yE{#BH6bHq9#uU%d(h$u=o2kwVtx!4I zDXTNwJfd}I!lyG_DmP@TBo(Xs)mllnnHwV6YxD9)%2~Eg{x>}#ISqV@M4m{+$&QR$ z3pKj1Q7HskOHKj4k+rcuJN01i3~2Sc-4Mx+_Zz8FG}6Ud9BZ&2Vo`3%Te4gUZz?z) zkyUEfxfp;AyO35f`eo3SMnT&f*obHk!}*bYp|PPSA^eRrz3E;>ini0zbeo0*Y_-ll zZ(kcR7)0yobQVQ08jYZ;`xYq)msx4>4y`b<@X&{<|Jvf;p{T?`yVvp$?P~mC>bHpF zaV-6YXY;ShY~{Qt2!;_nHK1ROq4V3ta{Y4#qcOB=Ft~wnuYLJ>$>QPH?Q(H~G6XlAbE%&oG&QEl9gdIt^WwOD5o(bTk@wrG+1!y1wJ z+c*$?*H^HBfl7rpe$S;zktW*!MOwh!-IoFdLycr2GAWQ$Qg@Mm?~uAtvMkwYx~m79 zq~>yFcz79|p69DP2o`Sw@`ij_aZM7Q0m1*ADnn#K%nHbIvreSg;2687DIB4&l@D1& zuIU{IK|V_Zf^ksfG;t#ry3{#ha{acFzn03GONuNbOy(QK)0H7q#3bVkght0Ak!np1 zmts!x3@DC0aCmfjA8#(NZkJcqltXD&)R0H2NzAoT{H`z%lSgh=_y!};vQP}rQS1;e zf=4RIUh_ueg?X0d zvPe_Vwxy@^KR}j)s{WQR>Cb^Gf8RsG1>Yw;Pw7S&Pzfe@O6OBytWx>sX(1CGRW4{@ zR!Emy&SZu&{HKC@{5#Dr3|l=)bzk#p5g<&8bV4ajKGGkXY61y-M@q(;RQ=%JfZ&rW z{y+_o8LQ{HGs^Xqpm!PA`FAghJDg=?tY9`3mzmUsYT;Z{W~AE8$$2eW;UQ-Py+Y(rm7&;Y zW|{uSTMgzGQG^al)V#Hid-<+J71rtr)d9#It zO^eJ{b@R6d+q(7~P6axmw2M_W_bid@>gz?Lz!XYs)Asy)2gh1_qkdH(!tUmY>%jKs zq_;hinREk)j|(#juM5SxsBP9ZMlrGSuz|35UNy)DPa`tZZRdd1*m!F&`gS@%-SJ=_ zJRWejQn!Vc$auz9vY_CqU!TSupd;NNDhZ0(3rak!foowHK<=8o$ z_pVK~hl7{iA({A8UTnH~m}$I)8djJl5C2(aDm;B4|67W1WqwwYf!1HR$)HJ;vAx4q zc*jm<;CJG-mw^Vay$&1(*Qu9!&)kHZ1?$vdIBemUx>FviltTO~u6jnMd@eUa=9=s3 zgmMf;swXtl@Js}a$~Vi-nzno`Z11q8SQ@A_pGg5{!xbs6QamgzwenOt*8Drf zqv=TNt8r(e>z9>#P!cVas#AeCs>jv+e4t8rwYyBHOXPl`(1qBk<~=-aR=r}hU!C^q zlPL5Gi`mYKt4WJL8u`qyLD?;zygEDc(%4od(N^KJqvRRX9gWlb9MCAcZZ!5~ppB^- z8IrC)64W(N)gKb=d@N{;`=gzNEf(Y-j`=bxB_D12><7Pw4w?vQu&Wd>lWmB*17Y?4 z1LC8B__ywATg2}0jZPvsf%{xJNL7JA-%3~yCIz1(EVpH9 z^p?)#lgMyL#%v$U1QueYP{R-7QA>pu&eL!*ca6_bnsV0KFN_W0(z+->nrdrRmU|F- z4TX}Z9VOPOv8C|J=u@Z)6m<5ia1;D)Z?3NIme(9Ap!B)$un`W{%6Y3+wZ}DVl+Wpg zDsZN@5-HI-ARa}L79~0=Vpq|_l_@KuQF~fxXA0z#k`PUzsCI|!u3scpjPv2vWJ>O~ zlmGbL8u=7n3n9I++fVIov`3o~*n^f!iiHo0g4SXA1>+@_qRMI2IuQGTo=f4B1daqL z3SV1diWrkkLtMxDT-2Vt;X9f%wYY^#8+gy!{cy$mc~%NlbnK5JZ-w%}D8#D3d)`IA zBcO+}!~9uT=oS4(vq;F1O)9INg+~}LI0D?dg)bpuM+c%qI&9DTzG?D_EH zb89xBNzr}T#K-prP;+yF);ka#6I)Y5SvyY?;=G{Nuu(f>qrjQ$xE>xSlU>f&s0TT8 z^=LYU0guSpj6J^&@mr$~nk`XS6zeUap(!Q04(0r}G0H9Lsxp?QHGbEhfny`4g!1=2 zfHhPKxMa*3OIcjFm1!II=`CaF}9d>1!*xfplO8Tvaqp)w|YW$Xn% zn+f@=R)k|Gt@l;;urNuJsApi2RG=F{eppRw;BDRBzrGujpBVn9E=Z@Hm6p)(o44V= zPZIiMfNT>dPCgik1G4J1WEW%dX&>H-ZQifZU!7LpZ{j!*e$QVq4^%i6EcZ--Yqh01 zqzd-7-IY$atI8w}@olgp+i8nd{oikFC&5rC-OU5Uo*B=tZ$4-AXPK8#G&qmo9PV?j zA>#!D{4c38ATuyIgS*W-lVXE=$q%|>A5huqlO%>4y5vm2Cux{SI8!jn+|H%;HXjnX zp49p`Qn}-@swg0llGo2`28mYcrl_gfrm8;ps*HZ`l z#fp-t;2ghk%FHF_f3MW4TBGb2OlHC`m0|6F!DjKUbQYDd7XB}AgQ#|}v)R>MwMYP9 zK%c)U3%bz`PdN$z@dgxD{1H){c&!HCm$WiDirm7&e8I4j6^*Z_)0Y0VT zkJK>eBrV$PwhP!k=kW8Ai<~KLQklHen}gaG<47#jvq~hkKp3~k_^MKj#7@OKu}{ZN zLVva~v7cwUz3|ucg;4DtJ@xQ?{n6418U_uh~9BO9xkNoDFjUf5=}3Z4ToQ^ zZof<)K2QJtGW$Heu02Ty9q@KQ%(Lmi^BPV6)0T%20_!xkA)w@45h(ifmizf)KDDl8 z;~DkabPuKZ{b23efhXN-kLwW9^?8TdW&uh@qfvLdxamf=0wYVjle1<3Y{}0?1Gm`* z*3QncxfxnC?VV(~-nIJ-IbNIk%qaRtR*+Buw9su8+L`16Bra6l5e>@?RGN#GQyJN_ z5ipZ}-^)jXW(TCN^V@+mc4O@EZdBNjI!out%IqCTA1N>BvS=}>+snyPlW7YW9JVDB zEb>kZwhg&(Z!dlb%W8>Sz8z}pQ%xGAA(MtKj!b#esByq6frH;=7xv5&yjsaFjYEgq zbr1G<7dpP1`!Vtih#d$RkH>of$AQ}6bo|DOnc%`BaespBlM)|@7awMtIKF5dyabe& zyL%5E*a6 z^ZgZ%hsCo+59ErON(uPmP3$H9yM&RwPn)*s2R~e(qqmEA2#=Dd2T;%?w63(Nt((5# z4OKCX--)jpxDS!E?N;5s!=FOr2y}wpy5oYtkstv8gsevR7-Ye#s9uU{{y{RYjfhd8UD_%P#Ah_ zZ-KP^&<_rfCB*5WlZ6~0dnS`)JjRwmU9hQSlW>~+_r8*BBYYubXIjrrz_#@2dG8mt zbGcb=YPIt(HS`6|mV_antT2MljYA_8`Y2jrG~KQJFxbH}_lL8#l)roH@Y( zx(g#5xCB$w@x_y`OzvsB;kuWszX_=z=f|rRa>LDzlEpGYPT-*xadE)l;J^>*+KEUQ zG|^^-9eB1S_(kly9S*F~)Z(NB%4q3C=*3~kBP^n19!Ji{1Is(c*=n>f1onVr*kvA~Rf zW1rYRjw3km>B?ct{Zsky^HlN_hCzg>57PRGl=bT3P09}!-YAT2!Z`4<7pGImzMXu! zkh%Q(GkeA-0Zc?x5Da*ZFzpH06)YulFiWstw4vdacqCW|!`(Wo7&8=w;*Kq`u>Vxr zsXKjj;%Etbe-FWsDe^G-X9xs3FXH~I{PWFd3Tqd~cU)uUQX)jhHwuXeI0*n? zRf?dN+DTwM?1LM45QX__pDbdEbt5~X!NY2+SB9qq7YAMJUr0YI#m{D5N2vnx-lRLz?1yEoYIL$P}n1+J?l-Nk+iV?)cT}fhwir>zdG* z)kO)V?A(7*d&|BHt;neO=CjAH4-wz}pZoPsiIOY#Xv`EM8MH>yq-|p<+ z$CK+Rg1F<*#r7yHH>O-Y9GH8OtVrPD*R+VJ3jp;5kjUNqF%V^NIG7$-odRpXaUF$| zR2Ur2^dvZ2OquXl2}lh|BA6+MePnYafJor1$RAig%sddG_IFWbT#7LB| zMpm%J-a1rYKp+mbx;B0Ib~7G5*jz5R)@(Q)+1J+9{XaCLiJoqTw=-*E1H;4X{>-wk z#^YP7Kl;#X@GEv9p?ns;39Lss9wNF^?vh{x=Rhvtf#+oj1)_t1J)gXCL%SNFImONo zw1hA;$C!&VqM;YNGWL`u$wWmge@r7)YBz!2>VequCXz@)*++b&XM2D7CAAHa03irv z@4$3k+rq|rUCl6xd~zK^Rmq?(1`G@mRS@~QHpnB-tPd6Raq!i*y_Dd65&;lEpKb!Jdogd zTvMw3g7A^Ea6mot9b}2Lw5jh`)zj?X*2)1;9K|$1fBoCv3w*pEu5U>7m+Mr->zpXK zI?v>;ypDv0E@}9J0_Y>2CUFpvHO}fxU4({ut0gwqQ7DTVC6~7IhvmS^v-4q|gRe*c zj}quJy1bNC%x58IRyNIhNx`^yF}j0BNIH~>gsth>d-*^bnOM<8Kb6sp<04X|BjSxB z90&xWZdG6FQtdgK4W)1d0$enu{ga-zKE*>G3v$-9X7O1kiCsOd?EySpduXj&9{SZJ zCeuJ#o%3GlHr~GW1PdlCK^Ymn{#NJNkhnmNsd;Y`GEq|+6(r$bTbG5aQ4nJ#grx2_ zPa&G=8*wABr`F`VHF?x{HK08kl}CJ&v4fSI@mx?q+7@JLhvvmgK$~VIZ$b*ynPf6oG4Tu1TPiMroVR2K;cjt1ullJ z;nw+MmyTF24;7IHGXt6X*d!7~byalKI%K)Ss^zN`MNH3Y|ELAzL{!X)>2)Z)y;uFu zB_=(!n0v~BDR53Q8+iy<|LHrW`&DIrem$3{fL~eK%Hr+TS)o%yZ6z$&SZ1)0+SN+`1yh_3lf4p+RJR&qwcpiM zj>}5ScLZ6`T_XKy##=9kkMbLZ*6esM(ZQ64v}f_ZXPt9-R}wGw6+Ql-be8s(Fp^A( z%2gv9#s)qroy2$;UiqeZ(;wd6Pb@_Q`^5(fr}u+_HJ#>0N^&B)RVTbNR5=_Q--jW2wF^i1Cy$K|-KxP#{MAB+4E+ zVz7l5m>!G}6e*YV#f9?7r{Q`grnY*C804rJifA27@r_@4P(Zag`n;z)O|P zq5I+0yq+IiJpM(k$M}C2ut6gHXQc@A#B{b}HZNTxyxu@;puDy_XTB|~rSych)&`EW z{ZQ=b?$apl~6l7Fe9y&5pol!^^(|;?EuxN|9y|`+$prPn}^o7bN|j~Pkzrgx#x{e zJvfE?4O5V?lmh}R_=Bc7l`TDP;gFaO&i!7=b&=uTFNn;!rZU0Y|ANf&sBo5rHWKcyWd>1gVRwt@ zD649alBZ;=ES^%_Fc2pQNAgTqN>-`Ci#>{+P{NfoNv@E8NeaEe?PJkD@}iU|)p3Qs zq7a%X=iW~b@UuRf?-YJsGQOdb=~zU&a&ct;bBP8cgZ8B0k#P*Y<_TLDk_MqY;)MUoNh0 z2jJghHk%$aBR?FxuilkE@FjUcwH#Sv(B2r2zhB*cn>{X;ip0BD1F2Ey< zINtfl&ez$W-{xOu*JU83F((Ise$@kb%~13oWylNBk;NhE^Ks`W4-_KmLkF5b)f3Ah zw*9+ed|hMq!3R<%UiEGM*jwhBGy>m%v(~f^6ow{($z6lMG19t;a0~+1WLazlt1T4DB;K5y7!#QB>2T=wC!=Zwge&03{#0@o2%p-ox%QQF zDi=yI!%SMhnmTw_)K#Yz%o}do*qaM3Y&Z2Uv>-h1pBzrhuAxDxa^MJZIK|Yq zuG1hKK$rO{hJcG{>86$G@kg)e40k|Nuw#*TthvpW$PY|W zJ&{xwlEZJE0_VjFbJD(O?30BCy;o0Ny1j22I8n_c9K*9%Y^u3|yLIH3f-GmlG>hD5F?nQzx&%C>ON|J#db7Z&4s$9KuOw~Q$x z*Qun;k0~dEP~G_~v`yDf*TZ7{dCHZ$Fi#TVr`eXr(Ml4J1tf`m$^-;vVanH@j8oPj zSwcOyw~6Vavb(xGn@r~ubfr+rl_$xgCrA(r$>U`%X+R!hxq>HB5an0dhA#1lfr+-+pRA3}dXM+AZt*VdCo;FED^6d!piB(U5k?SO_}p2#UslbjNJ z2irb*-C|62UYH>mA_|qBN^3uTaHsv{OK3LeLFTKc#X{;dSWMb6es#z}j*_<6UATR+ zN#j7d*J4vC|E91qvIkcD+g**h=EsQ^iEY=zi%UBehZW{BfqaiPteHg@>&Frwf# z%Tf;YnWGosxb8{i<=N8z8-+A-XJH)WoH}j;d>b{Y+{#nZUd$&qcaxiY`}*PPL3{(x@pE>oC%#*A7dh)4XTUl(Ma)8O#N(JSi@`5IrGZ+je zvkU7Mh%i7g9eyalbrI5sL2pQk8ziWDv;bIkS%M+ZjB58c_d2GrB}nP#scQX zfhst_wlD)U?7psFqbOM5g{q9k{V!k*QX(lOJu3Yk-dyYgbc5cLx!cbQ+>EPQ?%_*P zAK+D(ig^^v_dyvNiFL(FMN(#E{eCY!s+o#W9#@pn4agUytu_pw0Pnv8@6mo2wVI7@ zL;ywff|ny1%_0IUL%Jx&<-=I5>1`+d?<6b*;AZWcJ{*$u+ce(a^$%GrQ4k^d?lW zRJ~H{I;1wg`~BJV?d5Dby6O=7w(3Z^%}T^A4A*iyD$@;$V0k!ewdWU;tE(2|zkw$l zPC#I~q)31ORan&s{#YtW6mKZA4*=97-mwF^%p-uuAnO98e$?;Zjjp~<7Sq{uf*`#( zY0g#x+1X@1Hz(CD4ZZiL z!~oT#4@`$og{uh0p-{8WaqA2#+NsXMc3|iyS*E#yHc3lXm@q!lUiwh z!?sz_A8^DLPQ&e?kzJd{n8nMJx=|su5xRI<0hmvL)BabCbm?JU{91IMbwc0JmOb6=yD2jbU8lULA8V&csE>dnkB#*=iYvLB4@KNUq;jMVmkUVA9-J9~sq9e8n6!Uc6e`7x zH=d;B*}sxav+Mf=-+o!tki)|F0U1>D!hS#vv2FKYyed#l=yV)XFU`vmec+{_tz@;3 zB(W8$R+6r>MG$kx1$7eP0))tj0J?-D}u(^}gZ z`P6q(y%6K)2;VR?%~ZhqhvI(k@Qxo+>OS!}_qK-_rXDTUUS?$44x2ksEXGqH9Jfwx5|$N1gDUwAzgBQceKo1-?7e|im@5k9(1sj@Xy=-6!FP0PZ z>$rY$4vY_n$b-#*(t%?`k`!2aA4kmWzVMtlwrbONUX;{_j zXvSZtA8<1FDU&zPx{QC#7u`H-ZyPz1-~B6?z*)&z#mXMAhl6GukH=AN1bAbgo#e2H zvqGzzl8CgrbgUt-a(!?xe0jiLvJXok z*<7TY!N2RMC|N#d<&v|T?P{K9TX+_KjTZbE2IKgCe8k>GGr==Win4WK3M@qKOG!wWY@T}^%{^SOn=%nwA9$$o=FS7dkQ{DIRbaSPO|l; zeA3LD&0@hNev`ZAj~`;brs?+EBrAC_2e$1$caq&jsYuR>#byN~?2G*&T;vN8?>+A~ zp00VJ|GD8ixkRi~|2H^3V#-@S7n#@xFK5!;Ty*AK?nV6NrodbYqGmv(Td_U zl3?9nf)QCCsi8Ec{7bYcm+)?1a~>Wjcv_tgem`LF84j7`oGr_8El0y)nI`MwyjTn` z-d+u(nH(<5RXXGkqC}gN$M`4BTW@AyOMp}+OLp_|{Cs?K!%o=ipXzVlolP!2UXS7J zUmD&{-hVo~n7oCz{{rL_O2`8I0F8H1!O&4;i$5}SK_9@UBzzui($X-5p^MNHh6;WG zyok}W$P%nQW`}ypdl>n|MS%FY5G33E)_Pk_&`YihaTk@G9Y(Gn^4?^Gp!WzCh`E#> zM45)Kz+6F1B(U!Dm*7?6sJr)KDUt-V<%G?nRE7YTV2kjo*Q-IZv^2fO;PAF>L9xj4 zf`3BSLKKgSA}?eM0;pucBe~7;wG@q1ZX|@Z#y88#tJK6@@N!dRuEc$bD(%$boNuz2 z=w5L2Ax4Y(M>JO15PlAoah>RSqY?eBSI3W-v;OVXZ&%Y#p%AW%vA z)N;$UP&Q&H6ore%W2aCYbL$_C*r}54|2rWiu2=b9SvfrW4v{%fnk4619weyI%5$~k z@yOxQ7oEInr~4CRuTsKTg34Ar$|MsdTWuh2%s2$D60%Q>BXhCX6vil7wP3j{@_Whr z#Dx9l55!mnpeQA7NusKqn1vPlJt)P z9VB{*@dO++kDffUPbw7-{Zgn_PL$ve>l7SpzxPLPpy0Ucnzeg9XXO(X6-Bh2%B7f> zeFLkuh(jv~9O1uJB(ikNAYFwp zPRS-(24w=;JdQgpqB*|TY4Z4X9h7>NH}#$GUP9Gvi2lHOB4#A*zG)Y( zEnU3v6ss)WR?qD>tcXR=$7drL^h; zl?bdFs-4NcEDo&+m>c9Bb_RHwSQVhV6GK-MgbuJ;`@tvz%@2`xly5KeUB&Gtpr(;^ z63&-A{wmr1k^>!u7soJ!Wzj5!Y6K|Bate<$U{e%Oe!|;3QRErc&LM4=ci<;P!W9F` zoW-~fvE%`vZK>&_v8CJ{EyZ0ujxt!%z$-Qx7Dpfs^e$OqP}P`#D@#awYmUhQuRy9fNfN~e6?j=h zF=jh)gdK%#zCk{tyVjbDS($+lNfse$F)%>44~`+%&?6yG4oKH|lwhW%vJ%K(05=1H zD|{guDMSXeA|_f&(x@M~8O3H>lc8A**m;^u;0q4JDKPaMa}EQrP1*wZ@)|XYgC1@H zVZiGinFTlk+SmhuNcJE~LgG<*9?)+2=(AT~vki@bCm}>^idfutX@lXK-!y{S7yllx zpv%J!b9xYJEfGQKp-)G@_jiy1CB1oNq`W38YwT75jA4=@^xAU<#0f4%3MUw~{w-Fqx-zaH%s91dwAcvQCjp;NUb=$H5pFLZdA1I82D7 za#XO^25b#5j1%O5J$>rLi~ zvo40Z&qT`+6uHU&0+tCVXk3DrjP;r6q3=X52rgGU0qwbKZlE#|khR>*UMchM@Vg%z zh1}(0>pKj}%_?!D&=9YABvJ@Hziu%+C<6z?<0wt>?eD+9KVMrbhi{Gg5jtb_)DqvB zDL^jroxXWEWKojTGRH>s4s+-gFBaTM0bA;RSOVGS8qXraaP2t^x#qE$195igVYqBr zY{L?R;Jtc7Hl?vrRj5V8t5N{Zc**(=vOcVp&{!@#>#XjYnguG>9Xbt1WntB~TIE=o zu#ugSRa5iiSyiaJ9rPybZ;hTzLHT7V`@J|7Q_#1mo;fXXYOk^DLFE6^IHBLPeiIA> zr}s80?nS1$4Ah3aylERxoKf_@dUIchlBbX;{ETV>O7R9f6Qy>~8!>xMnIdG788*yC z$`{~ltG_ZR$s~L?xjjw;byqSFXJ9bX#fAHtHq5DI^ zZ7PG^&;IOeS)lgRf1(g*mOZSCD|Cq59kB;e)na>cO*NT}Y{5=H@nV)sQEuzqy&Y;m ztz)nT^dJ^zb~Qe~(BT{FCspi4*@D|~9KAM z!@+H-1$#%fVN9B&hhiV1KC~tkJz6%69etbR#j= z;~tAUvP(r8J8K>&4asB-9YMrk`RrE6Dd=b40n})LRpoa3VY}uO_WBZhYgW$ty=#?e zQE`Ha_wyHWG_r}ybGx0PH$O^%fN9wP2R_%m3`p^T``)(I06R<5gwHmMDbDe++{ai= z3Mi);2)Yol2ZEilKA>^rv2kQ}`0L5=SpqeLtWK?ud5mw zVs0|PEiF^nJ1gk&z)9zuvi(}FtoGP2)h6FgTk7o0K6p|dTrV5Qm|9ANwu3}XS^a+b zyUG21s=^$d91D?a8oFRnx4Iuyb2AMarSJ553QAx>{|UxPuLX{QX-)8dFc=eKG-iLz=FY32E)2ThmM;J=P8}-aC83E*$W_4J8O_B_#d< zsSQ*GX;??PZ*im(A)(8nL2ZucZ&+{DyZp{3tZj2ur+du1J({xSn5EXzv#SYJe{xAl z0*;tb1FcFjT8tDs-0V=5hs8o-A+1{aIirWBiI13`HB(X*pfKsYMoslT#DLN+kZGsg zbyTh)?rI0G$s{YIscmsIAAxw>&R6qpdgnCCZqzwF*|)p7)!Rk&_GmY(C`kfX;bx$V zS`E7IzAQsqvgHOsjGx_q`D#X(CbW}STP0vvGt90H&wWVQZ;`Hm9cAjE0UE4L#H(hF z4HfkUnX*xu{72Z=cFxzavwc^fl*Tnq^Jb42+Zq=g;W|h)hQ@}K0p)D6qdkF8=0kK;-GES8iby zU3YSiAX8QR6qvB$FF2l*EVwR7Bb62B^G+6=gFRuXqS947NeZCWMSf>CrSd{7Fjugl z)n7m*%feLDImWwtA#KYWV5?RHmB8o?X(Q0YYd4+;@A z$$9SX{HZ!p^B~R(-S}{JZjKr5FoGCokX>)FP+MTykyF*6nnID;wO5DV@}gFcw)6sg z6%Rc}OBoqenM;db20HZ#!WCwU@WH;2^}qOV#JtM_qtW&FKR!;b$8XUQ2d^%#K1?p( zpIrp2ti%Io1G*t|9^5?}t}6Qeyd50jL7SRwM-$tMCAF*K(PKnN6P_G1oLKIiU>wj^ zkm9CtuLEY@hv&Zs6+iYo_vqyieVeq|CmID>e&8)wt>r3MQ=i{=pL-@yKNhVPz2Bwl zDpP3DbbVY_B_c}Y!DAIA)Xk)g<_|fblOf>3l<*=WKJa*U4CrnuR-#n?^$&fn!sah_ zT${C3>@;RaIOtSIS>0u3ds)tnn9=Cd*~Q24^rdnlQC3^T8e6r9(XuA9Gi@`%%i5s7 z*!#=(<40TGWbV>~RwvX@=-2`rLmOedivn4}dft6s51^$oQq{hRlzWzHz=>Nzx ze>`@Nv{2jhYdD_Xm2sdY;;E@wt}~bF9%H2Uc-5ivxtXobS)nDAlu517KymLP#V*k( z)MDbBMx;8x+?(h5XciTAujYp|?y3Xx=AgVbh+V}A;pD1#i%yz-0`CxZI7lBG*LS3z zCPi;=YaemWAxXyl9GxSY{E&_*Q7TJmG}4FXYTzHUf(AM;&{FZ0WAzvDRfDI0OvQKQ zY&BZu5ryh>(1$aDwid``5)tmd*|9brTF_uVuR=p!= zK>YRiFS~R?-?;FYFnp<-axky$bho(-sOLOVDcqB~jpvaoW-FY*XyDO(rUlbUm5`dK z9Vfmu;>{RZ!*`>l-G}O~^7m}Nxc571k-0SnyRrK)sa+M_R|2kCK7mB%l3Zv1!nvi= zDU90fv<`{T4U-=!3cMp=Wq{B-t~8k24Bx@-$KbyopNW9o_Z#*>PP=@FR844NPbQ6G zbAa%L!5-c03+9~sv~Msqo2u84`{K@lb5wRIP#>dA!);kWMeyQ69NNuVS z>wA0{_z1g4M3m^*>BxEJIg{2Nru7o$^5QN-b4%sVU#d%wUUR+~)(=mVv7pAK9+4=U z`-}q5LeU1dx!4#gK4mHD!n=Kl=ffjBuxZJL#ntzgQp-=c)yQBc2p0lQo@hW_&H3tv zDIS<1epfd$Q5(&GkplZ2UUy%8&~OQtU9QG3f5*)%HEJIu?N1i$r?o0;qgvM80>(^9 zfulEfU~6ikM?R@ z`^$GU^qljC^z#&qKSX%^2#@*nRE@AM0HKHKhmZCvsrG6seZ(bg7DNa%?KM0@cP`7Q zDCHE9=&PX~`|5&F^qjCAOjoORISlo?9m>1V_a}OUD5XOTxVgggZ-I2z^pElj#LHc7 zK`q<47Z;i9u=bwmY}+YmYJ|3gp5TgG^#QSFd3CK8gHLdRY-jY+_c;x=YPZ1$vg3ws zXS1hildHOa{P;aCx^9Z%C`s`BIXW*(A(-mHa>Gy{J`23IC(U(8}xqmy--;Q1$4lCBT zs&E?#^$lAh#q8H=dRm05{{QXZpY2*(ZyQAve)q2!1Xb)}Cr+9+2}#p5HxiVVDzV^! zplZE4wntg-F1zEThE_s-;t`})NFc;jLgJ}HLP7}m4enpaFX7DWZFcrH>$ndHEGzNO zp857%X1+N)b2jcc1E*G7xL!loQD;Cr)FUQF@ZZr~itHYu1B_0_!=7!8p-n&2`gk6M znS5Pupna`Nu!SDj6k9sMF52kvmMzckGq2mj%|L$Nb~#*cWSU5~ov};$1Bx`uKqk?# z<-vokp6w1bN^Gl%920BMc24jG?{{>#vv>bwk3n%Q=|H3CLi3P8JnE9}h++d>5ITT6 zV1Z|kTph!M46gA)t!8OM?12%HMW;LV(6KFSQTSzfwuw&elV)EzYx5;0VKPG=qex3aO@@up)8al-F&c<8)p+?M9 z|6L7+#67rUYOaAc47eNyS8F%A$xaJ3-PAnK*ZhRpQv0Na;N!UDT%#Dh;b?|Itp3hG zbJ1-yhvwFk_u+};W80#d`R<5%#K7COYhX8&Z{^D$S_Kk6X@8^F`E%8g7=7_B6fs(<#2$d_S|ioQhQiMRz*!;QdLtWxxjKCS<#*9!rTER z;sdO~nCK8{;(g9&OlqUozuh%~MAy6h+ZO{u@w(0Dymz~6o5m)(=An&+O&P0a!B*%Wm#!b69S=jR&h5!jPj^phLX+DtO3sKk0KE86aZ zJxO`@?OAx&cUGZ$`$_l8z7$nWSeK_a9~CkGBY(uj7I?C*8!SiI46iPqKf8SXd6n-^ z73E(Y;FqBhi|FuV`+hv$mJsI;l<~QI_7vUqmvo`=`4_Q2zN@IkFSGW?)PO(6Mtp(R z*4CC5TQ^r*i|y75H+z?yLxzPQIm5~i%pc4Ia8Vxhu|0IdBd6cA4J}qZWq>DLv{7<8mY4qF6 zXP>6OOPQ^g&;HD5pZYs3;PW5;UkP3{;4D{y_X1X&@j6hn36Z-B6zoM@eGTBR0HxHw zMPQ1%mS&cv`J%tT6PoL4y6ELlMv;IU!2?D_eWq&^VNrimH^l1L z4l>!bfVEfw>mD(Xh&6<30cxoN6yFdQp!{onfYYIu>~0zAoYx2mB<5e?Afh^|!doH#m|mNM3ADb{0_qD3PuP$?d1zRC&6IT5po z@JA!f^boaUg-DMlekIR~4j_cln0{P4|8f3IQ+t?jfFX?6^y8Kbt@8&~@`+Pr(>uZe zS)506gW@bYh)JRWoR+xe8pSQ4j&X}HBjm;eRy;NnXekARQR1ifvU>S9#TY2O8c2tT zzIRgZ0@){jp{7OR@j+dnd6BSq0vOqn+d(>BjKY%JA$`m!2Ck%=U`Q0$k}jgF;>Z`- zBlZZ!MOiEo=Y`VPVee-OF!CW~a*Q#M(ovBKldz?r9^FX1w0S=SEo5 z2fje+O_K4>CtD`5&eF`#c*1)_J7vHz3cDhf0a>#F1Z9rr%NS?ZS5kzJd54|WWlqK9 zK~zdT-m{6O``0LZ15Z2iYR7E}!;8<`MB=Ha)uAc9JIG9bstSh!?(wP4V4=1K9lU!+ zrwtN}%Q%^a6KAM>Gx@itPdUiW@V9d((KPo-|}v9*~8-> ziym_P->5=9hfTA4$k(KHNTF|at;8O+<0m?&L}gP*79U%YAIq&0xSSp)@1bWU4U1KQmr&DA0!am%h|JwU5w7sD0Q6v zi32C_C1MIf79-Gq>PrnG1RWvF)=4P%n)ZT6e~G6gY~;P53zz-_Lk_n>BM%r#7=?D{ zT;)2afk-BW{H2iAT$sf%1R`Bawv06Rd;u{FkSlV`Lm?AiGr@b1#^}@D6T_9&yS}=Z z{xO>xQx>I;d<`pK!Gb9**+Zsr0V}2>`a%&Xk;wqb(ZV9`I}Y~~R1`!N(fmRrso=;p zt+)~~&Oc(Dq8vI-rv6Rr(!$gz=btj2X1aPGzMzFHf>O#g;~93{9?8-vv|gtooKYTi zkm)U$n;L|oa~nk9X-UdEP6N{gxM>>W@wkd@uqD%Evc@(t{bce+jrw*mu&79=8GiXZ zNc10f_O0iN8|qF<`#eBui~A1Lk01hXjjGQ@w}1wBBdX+tj+2F3uJ0?zy*jC9;F7Wn z18});Um=#Qo&s;*Lc1Ik##H`ZcTbFgRadQA%grjUk?=~Vu1|bUW9rbJ+jHv>_r*km z0ew>;y04w$S4!gl$V8Q(l7xFWJ8Ljy`(I;nTB>enc+#EPYjG=4 zXOiz_knZM`j=`W2Z53S+(iWRkc2{DelWU1Rkv`&?zOcU_#IO!-bA%@5$sbl~C{5O;9 zMmIuaBLO3L)W$<$Dg@pe=>pgSf<{>H>%!8WW9mtkIOgP-KTtzh$gM$wdmE6HK?jo} zMW(*187o^~9r72}CAp%lDp0oBJ5%Zal5(hwLh{_03hQbajHPpEDwG_1Hn>Z5cgxv) zwVp?*L>aUUu#+Bge`5(te`P5-(9YNppHTL-xw)_hF1JOfL?4Xn+OGe2G;v4AR^+}fasHi-} zuwud3{!P3CrBumo+b|Hl>no-~T1kOxqt`f#10!hz6h#r|78?OgjVvM*DUeiLBgnsZ zNG*-sIOxKQt(oDx_h#YAc~w+VG&+jl2yP2uAr}&Xek*1i=p0;uFx!;5RvWVM2e!f? z1^f7fr*OrV0u_AM4iy(@;3N;0iEZu-xh~Jz_$zHfy1bSWxUM!vtO^HAWgrDdWeHg2 z+LX)*tp-p@WMq33xDNNeUQaK-%`Sbaz|s}W!J1jfgmp$NYlj)Eg)7KI3aqXTM*_+M z<53hTR-z>ly`uS4mz7qi9Q{*POPqf}S)mz6QElG}yZphi@-*ky>XAv2U6@r}Qbg|< z`?3bz6IQ!|v|lVUl#;~da3LHlb)B&cPS}tM*L+M?B@?o%*(lXFPXYgt8%g(iY)o$HJVz4UeRpVHYpny~_ zsaw=U#XS<--*duqrsgj3ZBVP07*UAh0Wf3OW{cM%4T+w5yhGowk7wPjPFL?Ajer-( zAD~GBp^v?n%9$KyBG2h+0K4}eN%QvsH#X_O)0RzZZBRR3n!aG2Hqct}MOWhH4&lXy-ab6>Wg zh)9ilPS4SnWMM73UfNyTvqcIYKES)*%(Pk7F~yNqx+gmGzJHJ%*I+}{QT+%B^wP|;6A1#`zH#x1)O`8n+I3<)K z-6`!|zw(Peq}e_l|3UMn$?$hHyBBMl<}2C5U?u4>oNv$Cn|<2djt=BG`U%xnZF3qo z5dO}uSTiIX8G`#6zorhEcqWZKhNjaA8AjX*PBKePTDVF65mN$ zY2Th_wRd`v&+=OB_(cs~z+fgcOhn27pE*+ovI&?OhyH3l$>a*>;=kFHcTkw*qqqfc z*jR80x0&HG7F@yU#Lir5x2F?l^K&o%CR6sfNs*=yXZcEr>C6C=38W(CQlnxy$<&+~ zk;yjXDQ7sh5PWI(y}Q2Zz3=zvC~KveF#}7cAraarF)j>GU@6QDSI`5U6)NVaD6tkF z*J_f@xke{~N5iXZo@bIvgKtu2DIdP&Y0lM2tybtmVmF1!i!gMfYiYQe;PEF<+x)~` zw+P&0yKS2P__Tnw3uUT z^_G^Hr70Vy{Hr90H)uFU&cG|UeR~UG=;OJZamg3ll0sS1>1@u+Bfs&>EO>w|5Co(W zG70^`>zm&PWIVq0?(Y0i$M%^QV`LeUPsW56vLM<*AT->mZ5yCA5Ub=A8eAzn^9;zV zc5rgTzj8@P0}b?OoM~ZJIK8Ey+x^hH`}L-OJ@|8kZ}txkd#!F6d26amHvPl|q9Y5B z5x+;4>&VM>yLPtK+7PCnnW=0E5-Y~=T{abQU`N#40e2>4W?;;1I(gH_J0n~}~Doo3<^Tle&=2W}E?>(6x5s>8g{ zHp^>DBfV*{9z1Bf;Z!WR>@?dj8vWKAyuEon8nvMcxi(;YMlL)Cjqw)m&oTMtm}Esi z{_+VfE-Yal`PuN8Awr?EUa`|~vNNumF$JD#P8uKSc}k+zs{QV&LM*ok3%}Ib*1A7m z*K)y9k-YL*S@SWZ&r5^?>#v`L%A`wRw^D%hEGyEalF#Lg2sjZ6^UPB|_pIfDDy!X` zGinPm`##2t2MO$}u)~6nN*%KCUpzKd2pmZ6MzuSwa`8jC5Is(FDYjI?Ab1fBWK8H#`G*IlhbOKoaH)ZIq!Q|`DLs3%7y8jkQ_B1GQG4y=+}hi9d>RMc&~S< zSbpVaqxE&+4QQ{o>?uFNQo4SEu)A;`m6#ujEw*?Xn^ZD6C=gwRGJbu#)w3kt-QwBr z7W$VU?*(GYQyYEcw%oWc1=}q8>O@sYzu47T~-dZrF2){{qL>m-Uf5?+H?4|g{i8{X{i>s zr;%)bBeOeZYuf)8!u)|n8b6NKt?UL)Sc1ij%Ken$=ltv(%t)o=?@dbpeYgq^C8J#1 z(eD48EwRr`2wK#j-Vh-(E+!L>m6g8D4_=t<4MV=8VZei?ikigl?HRmb8|^I;9M0%6 zAk$l$-j%so-xq-iTb5dDC@0GH9pk-1&vTm zYXUJ4z2{fVq2LFiceSk`N(*f%=&cr+&Ca^PY!Z@ew@dNAcQ$^|V{=LJ=DnGDZ~o{? zC&XkZUwt>0jx1oWZ>OKGE$L;d6AGs zIBUkzRu32c+WOS4sI>-ZUF+4MjDRKwtt6SigH2(5g;7~E0;dTX`%=^--OKZG^|o1c zt;uc^v$~b z0xwBx@gsnbt254sqcgG#2lji(3rAne*hlZNg*)rIN`QO#_#7nBS(@bN+2nNkSJvx| zZlb{~QBUF|egUOcZEM>w5dQ98aT_VN+bkJlpOU_@(z3zW2Hm$N48=LeqK;%FxoPP7 z-*=MbmpVx|n4#Fd+&y>CbEk7pFN&-Pg7I+x$M7@b8d9Dk(7j;FfK0(;2)EmHD#ey; z$vs=)h@7o|l*Dku790iqkOoDOWccH_!4sAk_wQlALK$RmlgwL=Blsqrph17z352NnBm4d&x?Zkz)U<@HnVaG$|`4fR7Zo z)KI+!PXW;7O0?Ip_t(Jc3Y>&okU?W&J2CREb;PAYQz`*gbg}Z*vAY-Lf?7!(7B13r zyRC4dDgXu^cL=q?XKoGJY^lL#5ZZwVV~1T;Zm&9jLCz+P!qX#tes`qjr(=46BOMMs z!myL8vG`>1)Zsk`e;0(=mqjjLZJR{eO+t-D4c{nk?5Mk; zcCh~|@FxorH3@q<4q+i>4uhPjl@&E*xyHVxJca1ZjO$;n_!cXUJ5Kg$X`R7c^D>_{ zPF_*xo73c;!TV{)!bKI@i69clk__6cR`RA%2MQpN-r1W>P$#UwsMq6{$?xVASMUW1dbX8@@DIn-fl;h5bl)AL5}4iuY^O(X$D=qXzy` zSRgY|=xVX?a{}w>Mya?{n0B^C6M2dQK98qxax<+vj9x-ADT}!aI0Du?2s@r8`3v zh1aw0CAU|ceGD6@e<4Xeoo>5Lairaz2zOV4bFa<&3-TwEuZx_%E79ATc-x6TxKn;A zIMYI}3I|-;~0B zPQSV^Hz?IpZy+idqWy9Pdg14=_n`E<=E>H-zovhMr^^NLiCU`fhjpRx$k%qLBTtuH zWJsHMDU;_{m0h9vM*lcO2fjjKTCbn5&h;Gp0i{(@Z`wK(e$THsSL&8fap`;8b!8p2 zXskt$-K&bA$OI>`>e!L(l%lEseJ3Vl35D)qc_7&Se9rm4^VzxloTs_toSiyw3VzBo z#EetGcTSW68G}hF%r;pp#Rli1Cz8+}f=j#?bzn%Aj0%`YLq)`>g3H*>T=t z3O|&}hKmc%A(Ht#0ofzsL+^L#8PF%Fe$o_b4qaTnbEb~Hy+&#?q`ECl z#K4+pSTSuBTNZ|{V9iX5E6700LPZo4t!%|-jw47$HIk?q1vfIwrJ%y#KcOY3!5!r} zRTqv^==WfQmx$(NnZZar6V6tBl@u8w>V=C^R?GXE6edOPk93`)R^L*Yn~l&<8wQt8 zzX#VzMi}1-cIHH!XbnDDa(Y8KpP3D(&QAyM$%`c_hSY>M@O3ck{}}sWe>}Rqhfm;g z8XFhWTcl#o#Lx=r_iw|8i9dR{pCNE=5#{5?iQD}>TDC^g($Uq_;$UE#JN(|Cw8Pp; z;L{ZZGk+RR`d`E8==RQU1jn`;s@j+@5B^;PVqMZkj0Z#ia5*PcwQuN^``s0dNx{t? z*JDdN;^n$P&o-8@oJ zqeaJV`dKGnF?c5{7RR`1;bA%0?hK#kMti&Moh~$I%M;k4LlZQdmi1? z5V-hbX<=m-bz!egi#OAnnwsCd>dB%5A3wrBK}|NKFL*uZx4>@IyV|>drNaM8A~PEr z5L?h5{8zppEAV_Q8}#3&-DuLA@{WknZf5O-jH-n0b-G*IsS5Ra*oFx;4_lnqIp4ce+-ACu|JrGKW2mQ+u*TAbdGgmCncKpPbyBx>dU5I z8v2-udj_2!(5^mhi$D48roJjm%YEMV`d!nt^E9s7I@hc73)LHGbKA!CyMD#mLxx~X zU1`(lP@)t`mJ)Y-sFIw-W4RoVSdtjyDh^RhqW|9a_5c=(#UZO{Qcot5fPMF|@4a0d z9!INaYisxGE%G(FS-A;WxE>|&GqU59gbR|cD7oJFi!j*0v-xLxNq1l|uD9kxa$(P0 z8j#B{rNP{#F*#hYC*LI;W@jGyM`Ha&7&CN>%=5@Rj5e{mT&2Vg9OAii8YDnCScI`} zr*0UGNaRr)p53{0&EQ_YIy--ReU7LYm+8t*$=Xhc<0fhB&a#v`WbLLacmon7VHVFR z5ONsDyIWg(GR(n06DAhG?|Nvp4vTts^0$DxK>)J4;vKFkKxi2RK{BVElgo ziwQaODE&;G@0PypdUECN)&jXDbI%5<3Y%NMZV~twWixO`@S7k>$;G>?HzzmKAJ4B& z-(8=R2^rkccorsfaL}~)g9fpgwu8MqKYjl_u6O7xTQ)3wi$7lD$^e7KgQa|J?B3Za zHF6F>Z%%$z_@4%$Z{JHQHIN^S;JGmEIG9WYFq5nuiVIkPaWQka5@2s;$3M9a1pS13 z^Y??wyR(%YYfq^krJGa!3ej(Cy!50?$^}RI0-mI_hc3noIM#*fWlWveUSGuY-+*vm zd%2F?l%9oIphJO&ra$4!8`r1WI|w<5?J#hXQ<|0Xm zk96n*eL+G~(BU7BN+hXxUC1$T_nt()5oy_Sf^c*NU^7zN!;N8-_1D#?$ zDYTXYvm)B3P>MJN^cBMYyl_o6VTMHysxyX42#Q`p@1bmUgQZGH$0pJTmbb7Fq(YMH z9hO)shwO#r26HcSa4ioEO8P?$_Z%2xX6xm@osi2PF7p?rv?TIg zo}Iu4E(>NZq_$pCD79Q%VF?kK03!p@;h5Zou470=&l2h_#$zQ1>t0`30QTn3kh+Pn zq$UehFnweUf5OO>oYuL`_vkjMW|r=bQ#Lg>^plO;Xtd>{j0OfeF1f@XXQh~?Ssc_G z>-bnn9kubz;eL;R=9s$}n8&f;1fSF_7AsEVQvSSSWO9Ah#$uU9*Eno8Z`rn-fle`} z2Ao=DH-uY9JJ!WlRrzf})2L4j6U93J8x@)YqH8pqBuO}Tp`5^&Na=mbM<_Pah|{z= zq4pSno5*e+2QXM|urw$ed+5S&NlXJk0xM=v2!w&Rk$7?lC~E*9g5pTq7WIMDJWJBh zm!|XFAdeeswjt}-jv|>JnVp$L{b7qsh>oL>3*y_B+L42$QbKMHZH9>bF4(R@nrnTm zaXBxR#@nb&1A0^OVxSlCvJ@3vloD3H+WrWC&^cIEIcOs&e9%m{jo7uU(R+kQ8ylGRK_Pd#7m=%yyVR_;%1#-BX-e=x8Xju z<9CY%_-6}Ntni`G&Q(i}H9`z;H-ENGytZ$}mAU9$h} zu)tc3REB_9QQ?sEb=YB>)aS6R`@G>YORe^4oJcvb3$5%mCGQxRbu5ebF=V^q>_ZSy zAyJ50G{N-}Tv6YKZ6sL!xg=0MWV>XgW{DE!i9B@J%p-Asp*0y$nGXUPYkwqGcX0L2 zu_awN_8h9!Jh5WgUeCLjL9$gHST4{5+r~Pi!a1V=MM61T2a`b&IO@c-)iUSG z;?9z4Guck!Rta^JS*6t`%%w64?ktQpKkg(FqH70MvY4!D-cb{ex1gZj!o6@3l7;l{)eOk;>B{r$B#f%fx(kT z{6vIJp73}9=MX#14nxy-5}P#(Lr*!%tdT-JfGHMtEn5mj84vl2g72%Zgg%edw!-XA z+}C?Wi_3T+6m-F`GCYTndvx%sgRAaW+IY8uAL!xn3EE$*603-}{;(Eu9HGOv;hb)QU z;kVLiY4-(k1iQQBC6-+=UD~nZv3OmOka;*eJxJ>Of;Ho&hOn9~4E>_f(7?>i3iwaG ze1x6TRpmTvtAWftY8_3c0Ji-xZAZ-1BQ}i0^UySe+z(qpnIXlSSdLYki1Y$XM6zjfnX$J)b)19?b8_jmK-&Ba5D5SV|sa^4Gc? zd%?;8^B&TiLS+F_e@xLef9Zod&1IB8;1ND4X#f)DGd)EcPUF#mF#eq|!*XkXZ?7-J z?CQGpyIE!MqbQi)wMfLY9O_r#A=fiERs@9b`fMe=6A(j-F%q-^Zl#y8&zY< zRgfRq-7z=aRBtadXdy3k6r`emt*v>ksBBQB#>P0fjZJwaOLs0WPWbIIOo&ZKc){5}KVv!hcyp7nz4D!9&P3gaei-yhunwJZ?}N z43AgvvaDS_kI8~SaRYJ&U07juM47C@b(L3pX}dwQ^UR@&jyuF?ZRGradct6!4afAE zf0>o$ISeF^G~S>Y@b)cQfnR_mcXsUB;3A+1`_6WiI~t^t0WnSG9RfcdG#y|H7Ip^W zj%6h>_3h*ls7xhdcb1;cNrizHgr!LqH>P4zHN{H1v&%x_ZXuC}h+sFgnQ=?g-J8rG|{aM+;U55WKsvwQP*8OEZt-`Az_jT zwlNXofQsHnUg%Kk`EBrgRL9VP85QPWc7z0YN1s^u(Y(3{;G{!yp-Cq-+LZJQWUO^tcg0f2{W(oY1jGnZVCO1^oee z@uKH8`i^?<5%vJ^j+^i-^fEuN_8YXP!7+{SYNj&`(t01&0X%FqS>jRrK8Dw_{fobp zd4*Es9~q_=ex4I=FMqh4p1*s&Q@%r?NmrMeD_OSEY?a#gYM*~lEj@()ibB+{U6|%anu1^72H6J~VLk;VG=Kk959(C;q|G*znNAg+mv1=A~ai zM||%zHa*oTJ(#>(zr)vX-*imuI2LYJIdc72;(Y+k&;Soba=aEY$i6xn>H3!6Gni6$ zPaaX6+U!y+B4A;p+_tGEww?@<2}b8MrV+*VMuAn1l1F7C26QYFmKZrKG19Wf=O0z+ z0th&qQI@c8=LL<&w*7{RrnZ)mWDIBLb%jE%wVg>L{EkVdh6@KHMRMcrQ|s=6kuuD~ zsO)0Yv!jGMb#7*|hQKe?$-5bLwXV3BBLz~f-3^-=iRA^N$FRbiQAw=0jaTPH=_(G_ z>?o!DxvVvK&%Z2DJ{#qi2?SH@L=DN|Q(t^y6=+9HuK4hULUZ~kQyEm53#DAFYSAE- zm&pE18qAsc<20yTu4~bt51Ap}JUJHLFfplm z3QN3#BWB^eJz!HYetMtH*y$MmAjgN6(q(^gL}h-Ge0s_@fvImtmg1y<$~21As)nZx zTw{>J&q?9nFMeL?P98@3klGWoSxpx87P~54c`hVorrMdkX_Q*9z@k#2aX8Ts)o6&p zv>aOJEuelKf4d~s3!S1Ol%V#-p2c~4*!mB(S50r*I1s)2SIh=r?D|fK0%Q5eBnKBE^j6qJLS6XXI@C+mR19EaWKQK^hbhM+KLOo4L~EnzKkw zdJF#>soZu+k!29ce5QChHo!y-8IMqCI#?u9O_r@c&6q62K+8f!NC(9Zai`T1Y=W9dEEx^26jv*3L&hS3BVr)m0%g%`<%kSF4GjtGGk@FTnaTsmJ)Zi@T?YGDKv!=V8tZT#cZcMun0+_q+AiX zlsic6(h-h%96&WDg=ylrn#dI<{0Cw59>3mszT2*hr+tpCR6q6>6rX9UQ5jOHVpJY< zd+_1I!l@*C0z)@wYs`}K^D+(oXu;n;6%C4#FiHF9L|=w!*Jj`%NxLrGJvh;D+3Aru zN=uKNI=!Jd3Mxn`n!g-~Hi7bkib$}e=$E;e*8=}JCgnIqlOq^ODR|f5S6es6KP-|2 zRRE!s862Zh^htCfVf3Xm<>dbBlee08?hi|2|M9V&umyW-_tt{W6KI#~{Wb5(!nH=z zZbfyJVNQh#+ec33%gn7i_Pm>Av` z^Ml1uZu=`@c$-SM#NhhCL2}3sQi22Z8S2BC;0`x}!C=u>PQ-g(=1}a_ryVlFzFmf}cP4Ih9(4Pfq1<-cV&%5V!SM?|gd` zYMY-kZFIjCn}d7dR=(GIMGaD8wXuN6@E&lMAYSVc!JaDX*KZY#;;rsuOSP>Kt|aH5 zuj}+>d*fy8u+cfuJsS|)n%8bQ&y7eISEbQt=Y{0uiimW_H0k-X;G0;P77_>Z+ zh)SeDQcjIU{`(FoQnFRsMSH0Zp+nBcdvAur%QtmVN72R02wuXp;2JVsBG6hhWk6+2tx%Jd1_l~kJqmZK!AMvl zP*zWw5m5&vRA<5(Q;_06Q=tj3Nc75OoZT5z%t&>e=L&OX@Y1R*@-vTc>_kmVru7!) zqYl7z*a`d}BCZ0j;@IJe`3W)cU?gBfby}>*+=M>Tt zude4}7s@O0^j#}_M$;%kH%2vRf!R^ghOz&xFyjL4t#Q^}|0w4LODW5v4N@>22OaHv z8S3ZbaIFK-EzZ_qeh~QI=q|p;N@JtJLof#=9$J|~$wv)`X3tO+4MLir%u)8#1xMN2 zK6n;blTxkGuoWCU5H#iwA&fO$d112nblT&5{)c`(0DFFV=7A)8`^U?*w+@HOFj?6# zoHF~mXfFEK174s1c~l)LxqlyGzjhPrz-=Qb^BmP8q_ose{h+=`+sA|`o>FGJd_WrU zD=S2tI4OFlR*A*p!|n9_r?-nmGTORBE%_cuKShu9q3w_0LK9!6ob5ihz9_``P?LHM zhNr(QZ{ExMJ9OObr5|V*G?+~lTT{=mWx3})-6H$qVb%_=>88dnyew}DCUTq~QX;&y z-$~&U+uJp}wl7#`xqAz`G4vGu53N*fPunmM{+?fPnvh5kE#F%xR0ReS3{=>pNtGhw zIE{s4N48UjSpWOZ&P$upf{^A9jeEX(?(VtAK0Yn7A_$HS0yu!jj2lR~V1VC(XbUO@ zn=yEJ%~K^`(MF%iob}P!`G+)uOY+2-gnMO~q?~CuPQB&KR55+3@=@)7skDbnOCf-& z;#Ko`W`W2A1gA_IOe|BSb7HxYhfoMc(6-?0#mC)TPcD8uTsSCSrOk+i7h)jc#%lgl zT9&{Iw;7&b2S$~eGE9{CijRUolAIZAqU~rlQF);xlNNW9+2(&bxug9UG+I=3;2J&h*bYu2&I3uOaa28V~9QT)+ zNMmq_$7#LmYkzV!&j}aJ1doE0OM-(F#2BbBgSP;16`C)IWw56_9mB3Msnd6iwCI#3Ko4jt*tq=;uUgi#_SI&*o1BIgMqh4(ON}om^Dub+L9CQ zEr^Z=;4XrkZ-n{KRi&NEPfy>qBJsYprGyoG4To)k=Ra@n{IvxLpzwb^b zcel6W_~GJyJRLvYO{3wiqIx64>_iErP1qs6H{#};QKeBHNfCBm@i5Kx6I+GuFG`nv>%e*bTH z2Fsusgg)(-bGN8_E8UpjPJ9|6v| zi7V1-3O|MXw%>Q2ecWuvO;}1wVLwHx1cy(Tv~i`D?W%BVxl<=W^}FM}<8q;%Syvq! z?^In)*cDe)#SClsW$+J;QcZ8$FbuuxSMbn78*IrBXxgPHS}emb4CsJedXZ&1CMHvY zM9&L~{P$9F`UMolbg%`IkB^T}>o2j7#;g_w7VxX53>|p{{YRSwLI=_#-0g=h@Lpr? zkKN%?i%b2fJA+%>5HkD>g6s$rth*Z7QV1)vIg6Pp|>@VR|ao@MsH$U!fN~=1h^j2W98CuGcs2K%Ym`HlfsDd2E)QbANUHR z4%8K0G0>p82Zhuv6bs&A0bLW!qvj_&Hg=R=!@q+rBEdIUPu8~-mJ>EDX4>&)H(2sd zmaL3zbZ^!PIB#=)#WQyX{HLzA`AGCKS$=OM^I$+vO!^dDapHtZk!ma9s;`^{JZy-2 zOeAe^hhuOxW5-4xg1!%SReMIMM5k}pb?kgrF*9p9C&l&8mo*0$&-5jAFbDGp#aww) z+ejAwpHI@V`KFD4f1<(IZqgwB`GEFZxNLh$!DaRQ*!aRnC00cyo>Lm zTRMcs*glN=_$_03O2SF$ zH9KCGEQe;@txg|eS|Bsy&k18mc6*i;%c_36e)scbRwWC%cF&JoiWM!#UzQb2SwFwJ z<3;tD(&u_}_Qe0sGUzk|S+CdUqAF>$h;CB)vfhG9^(dZR+4+LTC|dDy&8{z;@b62? zxIT~PIas`UT)W%49WH6PNU|uEW;|PFoHb7mkUN;=nC&45NEDz%%_E$F#A(C;5z2g( zOerIC{+5v{2Y&_5qqtITM+wYVDuDPYT2^y#`gK8Kv>|4)rl$|kZ_0>x-1v2azz?Su ze_)zbRFaYkfB%*Ny2vjh{%=txtEi%+m!M?{Lj!j8PpksSiAj%D)gw6|Rk;LJ`WsA> z?2MgBwv!c=BWdIuu{%a0@*l|rib)d;Z&OoV(rQ^|WRW}obY03;fQalK7`56~^D@6@ z#D)TL#zDH|sGa3x8dVX_32aV5KYVV^IWU2&o3dHn0Q5En60y6`bU-P#0kKS-^m6`U zP-~0y6w7@+w$Ky)Br_7q=0FO_GK(pM7QfT>wT}3sIv%LswhwPaf(lfdIW)OQB*9{DIJi`(Vs{hRq>pJ-iS_mRQ>9x zQEHmeO1H&Xlrq}4$VGi2j*)`{P&G73Zy@#hQai%4cIp!(#}AFbPTeVinRDyrrghT5 z@7JG_48SODLl6i^}hxO$Q6gTzq@KOU4(M zCuhGj2G@gJB8NNy76m~40Ws0+Nc&hGOF@PDq^3(5gMIr(Hg&Dzv&x`$cjpm9J2_fK zNs30}0cg;yX)5}p8legMnJdH(xh`zi69_$?D+TKa@U!trle{L+0WpZUER)4Tva;u& zP;k`Ni@XP7lSOFJ)hD|)sqXMKemb_^b3(r^#!ZhLKh}zF>&fLRanH}{lS^S2E+Q#h z(ZY^EPQIy?{DhV;6XRhbY*C6w3+v6(u$RFa*&C6<;OHhV0VjrmXBwA#$7FSDX|qqk zuCNIt^|^_frzb*@Nz0*ZUl(%J-+Ca%v3b3{Mbf$kZVZ9ut-okb23vDoV~yF8=>ntE zDYS=0Pi2c!n@F-ShD0z0ND(G-NOpjB{%O~ONSP`)pxDcBiJvC_3Zd(PZ+ z?;ut+hJV|FsV_dZge)iVStCeIMF)q)HnB9ZLiTLqUw&>khLy^+ow+-5a5?%o28f$r zIx#`+!`A+ThR!|9xeSjsY|8-p-zFG$+Rva5vF6^mk zu6lRZI8e>#O0c-Hne(veH8j_M1g2Q|Xu}V3N!+lW9?9S?)E*I;DR!qi`yon zy1L-=3cFM&$%#(0Fe=OFak8N0Ee)?+4YUw4Fj`&@RFDz%XOjeF@mi<}uu>iL`?eFb zia<)Y1^ZO=;2?Q z_*E$U-(!0kd0Z3hZzoU;J-Dd&E6nEpxsw4Mh`Y60PN|$aesesUm zJRKl&ladxRs=|OEVAO45sIZSB0H?->b!c^?&)JaDaWS1f*uc$n+L{PgcoQpD402~ za``@NAHsqv3}$LyA#j&dnhW_yfM;U_<+UHu92NtDWZvqt7zx8;z~2T=bZnnI*ymji zgQ0K4VX!}v-`8+yfT?GlT3^HJ1!Sj?P(&rHkyXLl$a=f;CL@7<0nXc*H6|q(0j(5! zS0aXu6*1o{1Bv1yMQoh;*QrL40Cx$6=c6t(AtpY`OScHyy|M64P+m*`N@M1)m|~KnR#q$kXTpjl+P~5Vmi1Q|l${0(TCO z>|$Q*jz)YVA>avSC`!2#ur7#VRW!j0zOhv7Uj@rD33$qYZl{loa=p?UUuz%lZFnAy z$cdfFsipP|?o&*A_w<8e-7}m_8Wf;s;Kyb7! z-=<|4+@w)_7hu?#gD(bsi-vP#JF0oEKS67dQ@A;Uq{P&R4Oy~ft!4nf9j@D-q;6#r z+{5bfz4&iuK;G``c++B_>2Jx35|-R%QA*~ZgA_O1A`;IrN8;N%%gj@D=r9KSF<0Te z7^_yObgMA&){b{T5X9EJC~}56%E=6L!4OtO_r8oS({fZ~S6gK*MToY~&)B`sAx0nFQni+n{t z(ODHj64t;jdKjL|2)EzDuOb@~yA`&1)B_rrEwU)KyaCng<8spndVNKrF1A}a^nktb zc}?Iq`aBZ^9LjyUgnzJ|wfF|B_?j2obJB=a==j1gNInyXawq^ZES4Y#(8I1VuLzW; z9^jo{0lJCq{P?40qCVnIk|~A_9x>48SsWGM

}l0P4LMC&|b7wGjS}lD-5>%Ry>2L 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�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

%D zNKk@B1+?=1)z^nqAvtIMgicty3OuT;k_k;Ss*RbB%fw7Z%mq%dKv^cL7%mmBD4iW0 zEK*X+VZG1B+bCR#W~{CF4v>~fF_YetlXmEE+<%dA1=$-aeZkoqOni~bqg*i3^BDg6 zF3szlDL^nnp^7Uk&5p}-K!K&wd*zojE5EsyhRQzw{iwem zK`@gzr85e-VqRPJQaDDYQHN9DtA4H};{M!7=gudm&1*qrU0e6=PVMd1IT~<*s#FYi z#>OJJ369$(?+@CKL_gYBOqqwX+GODa01h-3FGNr$C5;M{pLo^VGdk|sJ@6j0{v zu7fIG!Iy%Yk!VI%y0XDdB!2x>3@3@tuqW*m(A#gOX`$?_w7LkVpkf~OMUbg)g6MzP z#;%NBb1$lWU*9i&aTf3@AbY5(0PUx@hCmr0aF}%yQw!&+4|# z&0MeX(1Bg+#O;!J#9xN~`N$}YR~E9{rYS}$vFeR`fwIN7TWo0pUqWyeE9HX5PmkSm9vJ+8=axJnl7kJc;Y~OSJh9U~( z0P~UV5?ooewWCkPC-7xN8YT0Y8=0YeP!x-YPJ}R_j48DHA8SV9%YlJgp$~ceA7jcN z3vTp~pFKqMv2!oOB6ea1NeBZ$@0`9g678|NgXIGaSy8p%P_opf7Kif;Un!aM^-!Lx zB!wrU=(Fw?iED~*LDl=(q$m{T^;i!ZX$>hr)1rjT6d=ZIo{6%yWjJ%}lz+atl zU6Bu@{L%i;sI~XA9}xnY+?8KHbu|HfKmgxSI(jHdv;v;6fDmm!B={@Dd{7!_O72d@ z(Q)gyLXfLBx{y?U}&^`J!A zBHyc5IwolAx?Y{vnb509cj$K9xAfsDV$d#HqivJ#aUj@HRu&}l#>PF-&PLp2FKE-v+#z8~-oVC*ggpeP25iu!ervbVdh ztljQ|Q@sb}Ed9p5`YQSqG(SSG8sjDM zgG#n1x;We6>hIGdmZ&UHr=*oGz}9G&M2(cgQ(#O*P~%H9@QIwlxuL8sGWtb9y1KNz z&=oy%a+Uv^(f9usb_W>Pc%RB`=%HOdCa2T$@p=7iFY<^z7cSliL?k#c;->U8sx!;G zxSx7?n>{(3arvD+9X-(i>kp(y4^IABVQYeiGL^5eI!jAeWo>T_-XHuItybS}+cpq> z_g`@Vgh&GHv={~yXd16Y5@3DVvbNaEJOng-vboZtN>Xl&)&F~slqgFUo%LaSlF0k< z-Q9ObzWJrvRFg@`wrDEG5k4T}c5zpl#UC~5{q+_I9Rlx!)n-FjbI z)CK8ZN5t>2K&^2VI~(gy3Q;l%Try)w*y{cL6Y|n+cR$@28 z%;rIuL{7l;gpOv8$lUQEj_->rN#+X!iT^ouPF8AN2J@6WFPt^P(-XJ(v(7r@zQ1GW zqp(+PnJJhOze1>b))~xla0JLMld7qD-cxr=6p)285L5`qGgZJde1mV_AiG$I@c)QU z!dR1~Kg`%Phs#S?Y|(DiDyRn(Q%Jd2P4oN|tq;1Do6Q@sEWaMe9J;?l-g3^XnVNGn zuI|U|Bs(T+Y;)9Qa|)LUeJH(T{PQV<OiS1Pwj=<_2E=j}F_mS$wEVOJQ{}Wg~63(!1Y2Hsb&as#gkEZHi~}6&kL^5~3mm` zaZ#>;NjKw_sfn3XQs8cb3d=uV#f*O4FbfQ%+M(P-C6HR52*A|}FUINBT{5wd=ow0F zU!k`9EbTIzQg>VJM?j=RdNwy`-+8tQnj0Bi3#Y8`g5HFm;IsJ}?Vql}8Un=v>AXXu z$Mm{xt~90*N<~rbsA6tX0SOtkMR@r20bX7G+%R8C6SMo)rQ(*-qbcj}*QL_<(K2mE zvP2gejT<6z3&2qKsd6-o!*ZM#hEkC^slQSJY|_7@({Svfr_nf~@8>jwLnqg7^u=vM zmH*Op%j@1i`uoy%mTQd#)#cH@D6$3tHAbF}YuR6iv#0Ts@$PshUZ?wVb&h_4Ow*QT z(Ww;4$!s=!PYg_l8@Bf_na#iS-U&Iq95#4n@^lmY%$x|rZ#*x~UXA@Ls0VI%1N{KR zIJ5|)es6{s({UuX5VG!hbeMbxomEj!)Ibn^@2?n<*p@&G0x_aR4QfK7M&MpdE;;tv z>9yW=w{*86G5mLDciX#i9E$EeTyJ*foB6((>Aika7q#aJR-vj{ig1oB)#LX;LfgLJBaGTK<(w5e_zB$TS;tN|_Iay+QT1(GF|O?J5r(^f+!DOgBt zuu>^Bqm+4xJX4U%hN@F7*HjgZMxTI*Y+z|D4rEL-2u{B$K%GWm)D`xYmtqcu*0nl{ zV=X0DQHeT_WHXBkUGccd)4kpO!>0;ULw4sN+KZmsP=yE&7ET_qmzRR^PC=`@_sau1 zR$p@ngP6 zsSyG;XK*(9_Vq)!4TeBh_0f^BO{}^~GwSo&L->EzS9i;LA%);Kx+vPiZz zmxWoAtY!_XddVzx_!s4R08=j=O9=)NJx-QY6vuhM|9>dwt*|o&lZkaRn-Xj~R-3Li zmngJRZk8Mg+SHw6OE~GrVdc{DO!^kCT)Og;h3Mw$_MY_bQKd~erB&1gE+sbmw$v|n zSY|B^w!7&NdY}=7%U0L4+2mI-4dkfWx|Rwv)3PbSw-pn#y)0u>?vhxi>33R0aroQ=?$EJJc0egmoMPDKmin$aWgutn9FNnYgVpkRMASIZyTg{mFTB! z1Anrr<`|{2g5X`a0mSmI(KdP)%-HNb-#-X97Eq6Q)0i^jg5cf=ELu41=#wN_ zGlOryx6eLAcikiK>2n0W-|gLULlW=}r$NZdAT^kilfY~9PRzM`Tb>x$z<=PM#t)bA z)H-r1ATU5X$1~I?{mKO)Fx72(atxb47;iBga5tySDb(ITk|cMA{@F7aQv+$Z`em|I zCVpsLcUPf?q{lRH6x#dIwh0UVoRD?4jRp;jQ-@ zbyCY}!!QuM`zw}^f(#DyoV3X$ITT9i>u3m$vaSWTu_4CGavc20W%LZN89OQW`{6msmMT10B|DMn4g_Q)_X^2w{pXVQ~qUA>jo? zjf?XRu-%n{LvAG}p(Jd#TuDRPa$;AeXPczgN#LT^#uDy9+Omv;MU&K@DHX!ZmYs-W zjdBl2txO}gng^Hp`~!)_SKKy=r}x$Q=hNRce)^HJFj$y|%Q&b;vRa0L=(Lq&qx7?7 zqthxRqcF*^kl4WmO6HrAoP)3_#^86O6B$JCN93LY!VM&o997;X>KBD$?S;nwh1Q@S z0v=&ZX2z|8q?}FGPj5{xAa}#KG2o-`!I39P+nCvMkA`cpLl(OdZyk<<{x?k?-l)*( z=tyVIDei`Gihcn-$T13lFbn{|J+H_=6kPNHier}$BNp1Um=qN8?{40B{ZNkzpp?Zb zvEU-a9!9k=H#zSPV2?@(IguHzF-vJaT`bjOQIyL?H^cB3Jn+H?tybM{+cpq?_g`_v zj71Lou@=}c#EqAt=|h1f+qypNAwa-TCyOgZX(Ht`SpC26NRbvT$!Qf>RbEXdiWR6U#t}XsAOD~te@7CNu$H=TgG#2f8Q&Ebw=-g`Elqt%) z8`PR@j}CvY%R*=jPcobd#Uyaav<7QbsO`JY$Qx7EAc{(2fy!tIdk2@3emCDXLOw)R5f%b^Y7ToAGl& za?)+BUcyg55M;Yq)ndmC!W2EQ_3<{h`3bVkgA^RHMsXub1^4&PWZiI+4C3l6&fz%8 z-ssHPY@@epYI30$o1jG?dzd02XTVB$c=l*N4)PyMeB$Vbsrxf%Dcwh-< z7iaVvHqBEt+;m(=&<>y?j7P|s38&F^9Pe=keAb;*g({_rI)uE~Y|$iyeAbz&(KNN9 za(M(_mdPOt$&`wxlslXQz5R{c%)nN2(griPNtk=v^O(BtgX?)4!7NH#jEr)Wqe_m> z?1~T+Z5#bhj>B55Lg3Cudgv1H{-E?nkP9M^GO8bZM->s0w%D}A?#uiXC1G{c_yGrfiUKQ+ zqUT76g0n#lD5#MmO)%=S4QN7&AOb0mgwe%Lb3}2PIVmue`Y@k$W@&p7AXBjXYv}9> z?W5cFnIB^I5t1DvyIP%%a~swPj>Gz+15A~*hdQcBLw&TVH5XsTciDH;!)TccK4xCMilt&GsntWOwMd=IX!nT#<1$;^&v$eD%*L|bEuqm-DQ^{MOzS1Xg8I3L6u;`Q7|7xz`gYF0qMn-0gm9O!a> z{-W+*VYVU%E!w-psPi;R%3b@}K=Ys4NIzmt9}7A!8%b>?B_#!@VnEX+H=8?BbV2(_ z9|k)n8?;Tuc1%e2ATc(6C58F~xiOW#SglN1O1%_lvSnFsSGg(Vs?PYUmp{M!PNPG; z_;L9vy8MhBB$7C!Z>hYSy^BqNO!Q6L_kM-AS?#R(ISpUF1XlYFbWPn_mlnPKkZrjZ`(Ey{@s7YwJ>VCaFeD(H^7~n zWqF_hwysN3Y{NXXj6~U7B~l=%IL6lheMjm=z5Hmi4qK-Hkt`nXj(6XEJlbC$#*4Vu z<0PUgCLV3&faiZD_ z7$+fkAyEp>P*liO?~fkfwg2#;y~9H|mXv6!fWXPiOOP4%fN`Y>M_dL%f?iOVV`#XQ z@hn=h`MH`S1tNf(gT1fz9s|<@g{nLeMU?y02Q45rUJ!VjV(l%6>)$cn)($1UnM`tB z3Q-nPu(d&@@rL+5dZzZ^JaC*z9WggeP!B{xQXD261gFN;Tw$qc3|e7mBvqj@gzV~xDqfZHW4t6D+~(v zjY1)FeV8!KG8>uly;^j?iHRf;q_O)`X=(IAKMR1Fmk#Ao9Xi1up{eeW)+`)WFa-S& zKNcdA>O^vwHL0q2D5e&Z^g@cIg4sF0AtCdRlK6y(}PfRlAjsaxA!=?4w(l*!ab|mv&AvY0zHP7 z=)e?s5{4r?Kdmlv^=VebINsL_rXD@_F((q$H8^XS38dD_x4G5S&f&zGpG@Xd4@aXB z7I|mAseeh{Ol298Iy`wZX*^kIAi;~E=`Q+)Bri5d`6;?LlH`SK# z5F-QhHb!Te4p-^o3%x9W;k{vIIVl5npi!=zy1LV+}AIACGSAyr^G8aB#-qP2zbJ$#{!o_=Jb5dk-MsBm+S`pE8*T9w>9q6QH{NM9ay#O zHq}?e%~gm@CMLXRQbezaUVIx0?;QeTI2t#m)Z&v}E^@Jaw6}oa>>}YB+xU_}`m|mQ zSewj73=E{wq+(q$jY<$I!fXaM^VDxE4V?ZH_&MPQ@RSebuaFhTSZN7i{9EjKL1NM#5zUP3Eu6%S|U;>2ZJwXPGxtp zUe*C-_cCY3qvwvRbzyVauvn0_L}oZRwad=ht0mJ5EKMiMYT#g~h9e7?eRxq86Oupf zMc4!;v3dT&Rb*a7mT&U14q3#s-Nxh41PC7@!vkuCopPjLs3?W+kA5zC^3h)1_Dg}e zK*d3V_%cmr7))@_@)D^`a+u-+(@O|j@#B<8Fd9C#7RW<}88CfFBd{dgHXU4ZTj^;8uE*^30WX7tR+~?P9rT{R^{h=`@N?_jPGc1Z9b4 zDb1R&7Bc-f+Z*i{(Ads{jr#JWk6nuCy1GZ(N1AWzga8y_X3ID z4zVaxy`Kf#b_34elgsv$9k_dMkulRvWhd^|4#cj>+25uGqt>^T@~Q0{Qb}+#muti3 zZpmrfMxBS4te3fqW~ciYayK2%+Je zC;d85*aJj#@Y@I;Jb?Pkv~$*8ytZ|&+6;xAf1zLW2+nnB~dylIxobZ(i z{IBMwvl8w&H*G&-wiK!3L36N@7n_?8%jEmsU$s|TZz4Aoe&<)X5)wlMrO!!Wmxe(? z4X_=^s#OvpGh>3A!85fzA*jlK@9|~s!-i_x(O!goF5kHy|NJT5$E_B_2O?tZ6XX%> z%f|^5j~)?G_)7RqtCfi2#XJf~_&6s*;Ae7Ex%@35{PgI)5kHX;pD{`J4&*kI>3^$N z9`Pd{EFw9L5*D~`K8Yob7{C}@UA52^`Yec|H|R1AXcuuL_XKS*h@C{Zm zxx1R#h*n=)?y2aH(rYv$HRDfGMkrf1{*@hWOiSHfk7p$(2Lk~2 zCjkf3T@KTSu2{gT-AN0WGs1(BpXaFN9On9l%l~X@LXO&NSi&C@fc5*12gU-*SRq>Q_y= zSFZQf^)}P-?C#!kKi0k?Ts811reVU#_v>Gb=kBGJFCx}=->8rJrT!*+HZGml^}I!$~MVmVVD( zSahsak1m4_`q7k4S^j(Jmu@n8Zk*{eP7On6vRIiOs9T~|qkr~C0TDi@TjF%#uw(l- z2^#9#(QK(DK-}&0YMM0q(rK~D=Yy(^nK%+I%KgC}7Umod0=O1Lq{FU1GM)aH(*kz8 zF$>l(ES*$bFSAQ+e)%swf(vu9)as4|1vG$$E7dR|^pzm2<_T3^P-2l|MziXB`n-p> ziBuih4xen!C_NC$Bn;42jUNb0x76-_LPKbEK*6Mw8`rINv;Q^5xv^%1Rcu`>b<0rI zznqNM<8J4IcoxUu=GD&o+`eJo0Oet63Aq{09@DP_-97wC*pfv-@*=xicY z)GA=#n(2emzMRe3rW~}pWuA#P1)J7CoqtA|-epQFOqxuJAEFYNta2cIFgxYxq~!;B zUF>KG8-l^)RA3ZWN25*D8BHZ=sVVHrthTJ@mp&!#fMXNB39K(UPh;AEAE1h09`Ng0GR*f!7t6FX@ z3rZ@+mw3xf9l{JrzfTpwMkTDcrq!kpHB(~;!kVNkH6qgXrTBKQbHb1^qn@r4)^Yo}aMA7L;uY9My% z82;D6t34_8DI^FqM;V0?@Hm$8rV82QkkM9vnm_*RS^DHFD?U^HR{yY!zzFJ(jEwV7 zzM3z}rDT1Pc9Z5v*wVmp;TdaL&Ve?!Fe5=p0b37M8rOU4z4Z_6R!wgkHxRw+R}4@C zmJC_B6g}9fQ=@TE0gWrjz65oUrMQ%rHJ99yTsuOL|K1sXth7=jBxr*6kcFU?$l>tK z&mj(RY3cDIjlE>`0 zC<+3b{vFu_<@6%`8Xj8$k2Vuy?~g~P7l=R)m#yYr8V$oE*^J;rc0iBdm4V~w43@^i z=4y}*j$s101ixp$&E8%8@%wpR`f+r=0cs28ZG~&`W3&LX3@n7;YvC(X;*`cQoJYDJ z*u9v*)PoZmXBfP^zKOwSXM}4%k1NyKu*M0COaRj*M&Vnl-6qG`Stc5}a4qNfbDQF6 z#Jk~g6B#aUjCL3gE=A~Q%RF$SJ%Vyj8ykjn_C^dKw|Uzb3q~Fy9E0@mB$Wb-uuZL2 z&`AEUN!t!`Osb_db(qXxCIlLZfG4JXm|3>yR7vN_&w791I$Smxn-CsGSIXs5SV3cy zgSakXB*(5Yttz2)6rIRU{wz}3T`Dyk6>o<>r2kB*Q95iqYv%}Zb~tZ%%*K4t>Q1iiDF-&<6{l3 zf?_X;E?x;dqMVc+P%=FbBR6&3YC=zCxMWhfumjDf_)CL9K6nvIY}TA{HedFbZ>axLIZE zpFg8-oo~6yi%%~il;NT7^Gm}ltHF6oAXCHWCS!AeyV&Jt(QkftJ^guHJ-+M6yVz`+ zHaGZ`T3w&{M1z6QSLsMxcP5=zvJ07fPlhCCKg3ptTYv*gZWWF_Lwou+oOO z5q_epL*n$Wu;cS(@PGQ+@c+-+8ssG=v{Kn&Kl8qk%7)Nw5ZnH~2Lv`&{TAvz+>Vr8 zeSL!(NR2TGAQb&fIVlL7^QfpUXapj)rX%I4lDz86YDBf5=CAz(P?J)Sn;OQ{6I;18 z<=I~r_8$5%ELsnka8++SZd-~b&}(#n-^+ne`0xse6Ym-3rwFX&P2(kGr!af>RFsWz z=PlZAS3t{|Z)>aTo1$}9{Ca))`l<-2SIlnb-RdxcO}gcX6IH5Yo&_HU zz1nOwfg6EcPC2uQFI@x*lw97{cmPS2Q%)gUo&@^)mF4@DW&f4sGxg)YzsWFb*=pZK zX5PQZ?A#r`$u)+kOTmoe#REzBIQR$ESZ#CLxDo!YU$N(Lk5X#uC5|tNbB>cbo{49Y zp2shj52qU)L_#8JkYE8&irUM6?=C=6BqiBSr(f#HL=v(4U|*hHEco+T7H6GK$`Woe z7IL`eEVSbr72b3Erqjs{hl>SIdBRgWrf>El5!Q13#;tjA_xzJm*_i&jOmTUJV0Doj zt2s-?AM#A{uh-nDT!-90+#+^oh1~M^ix!qmC4W@E6!br926YC{o^{|E+{PSGK4%g_ zm8LwjLZu)Qw2nMw?&nNtIImVK6x8<+!ayjQF<@eq%Lr5|S1{#(=0qS!JY`a@4#04} z4G3k78gfqI74?wGBp|Ly?(xq#5$Gq^0afSF`- zSjODOh+@f4{Kw!f6<;Az2@@$8#}Me=eYok>LRdhRh&8L-gMs_Z@~IRd?B|4c3Nt1R zrRGW2@HEt`%=sKMgVE;bd`h{d_zOjipk}BPW~9{rt}v}#z9<~sh}jyUt!#=C@ej3F zFw0?Iq*-puhhB1)r{2-Y1g%H4Jha_?T~yiuG%6eRCI0L=eNQ82$N;WBUct}svVYV+ zf-Xy=>cR8==(q7Fw-hQLQQj*SdHQ1YS!&RBIdEJ<4q;<43@&iFd7d30_RtE zm_9b=l{$jWGlxPlP4mb z;{wNDR5lnT#N%SY8|FCs0hysvi~_>4g%S}M%Or=0S%&F$#&}87_iY0I-KT1a{8V+g zx=k^J>%RDu+@3MY9}+{n4vk<&eS>k1vYERLmPG_Q}LX z;&Q7nc#dnn#!X4f?pLXSb6ENamF1xQrub($av9jFLNy!MeCx6Nuy7RBG zdC7fuFfwPsVPOFUgBm!4R9O*HUqgCmL{1o$R)*x1b_Hb*_kbI`>BAMK6^Wl`5p}i| zcB{Hko93`AlLCF9+C@s2v72&VKon1`ETVdOtVl+OX$$KHkLr?ub8Jufw2xdJXqrNh ze*=F$4uml|H-pjecuhnXbed53xlicnCe?^e!_lkVG#u@w;b{1xSLfkAW&7~0>-o4> z%9pTh4C_`3PO0kr&BxUDTaUIC))^d*-~`fK%BD2!zI}|VA2xm)uf8Q9nWN6AfIYG)TnU37#WV-cW9e9)jtQyT$-GHhtIDh~flKaqFY5EdMWjKAw zMCLvtjU!U9GYN-pRobnzJb1BF@sw0a>)ZAtS{R&mBMM=+eFpn6rL|pM{t@6ZH%|p# z%RdO5QE_cxHo*#+2XQcqdGZ)gDfF;Kn5*uNdjjl7+}I*Du&**d$(OCnoZi51- zgm~B_*MLz4Y4)TY>hcc)BVoN5m48(-yTVsVKMd-a`bZ`UnK$j_7~8+(=Q~z4Pw;Ge zFXbnJqjQR#{E=KX;93TW8FYUb3o|JjK)2BvdcB(LI?`*KzBLZ?TYr{P%cC>R#Mn|J z8tjVu5FKk`o+=z^S-Jw(BIpW$Llhn^imotqI3pqylxRq_@&S$daD$-kPu@v*?;(=US-7grRd|&_&(SoR)l_;|A^amZwz6!>u?;pxT^x$hh};ba z%G>6qgu>A>nvFy84ktA&SES=Bs(qtg(iCagJ&qX+LxhtI0h9bp$j0_QrOy0i5xAv5 z6Ye?B{P?19L;$)xtW9_~_DP+1BPWy|3Su+m2Qa?5y}o$=d2;jd?sjth;mdW6gB1ko zm$7Q=yW7{pl$>*WjWo9WeH3A=%>Rg&u6(zWv)LgsrcJeVD=KK(gkJcxy}~OWf8^jn z)lVv9^8d#vpQ@Hu#WlEgI@N&png6oQw{i_mPm4SF_j=?|yovPsqpgn2_uUV(!GxsB z2$ghqUAiI^yVLyr@#C+baojuVk6xctljzanh3qRm9~_^Lq-rDMq|N<%4a>tg#i?6j z58FH0^RIUncu$MUJzV9jiw*lkCh26XDzO1hUX4vY#i&;?I=~UI=K>X+1a4N1_)Mfc z>IP(cZE6jAZn^c8oEyC!4%;E3zjYp;tS4%cUFXy{5;jcT7-B({6AOF<0gYGgpZMiod?t%B!p}G9K z6`o{xQ7V?Yo-Uq5n9V7E^fq$U;BgSpHKTm=+wgbybZ`81h&yhJex2k0MRW`GfcTH$ z2%ukWzU$ZxV;9!gcAG~v_o7Y zH?CrIw(1jj4;O>qPqxdr-Tw+tsDRCeTehgpSC3~9SZM;hdj&Sk0%yV2B!26B>--0; zSZ#0HHW2>qUvVjnNJ8DX?FJM`=C+v|Y{9l9NV#8m{Xk9_f@7d9_03u8D}BP6A>CF1x%;NsEtZO<2Mhfh#f$~`cin{ zWTzV0)i+C~U%fAwVboBtLY7OhRHeF>VArm6Cd%(8iZzawiY=T+Q5wE4Ph)fNCunLc zwc{LscRCz;0gOf?m=msPP?6(gAr*@8Oc+~AIN6ivXkwxepb<>)LDOlXc&b;O%pT6P zrl_=Ixc79pL~y-_VEE4!51w5Y16 zNtA#*&K3R3!XoGfCYNGOIE&8JBC#QS@pnjL3!dMw)%%65senIkFX4srae?3ocrSoy zV5uzdFD|dXoc|tpgNBevL@|$OA5$eO{9Vb;VH8#Z=LlV+ZrS;n%$FS)Gi8`>*iuGPpnf@L)}}6T%3$jvrnQ zJxu!k8~ocxj2G1Wk;?Rgy|Uam+#c&{;=bD5ZqJujS1xZswlZRRGftz^bTc!sSs0tz zIOWGOLd~B;evl;Sh`M}XLXow^(!C&RW&u!iP8CHMHO#hzx#h zUevZKgA#JwduWvI7?KVjUExj@z~|>m$rZ6YwZbz_L-c#(*yZHlAbCA=1Cq_y31U5U zL%*MDhAAC*hhwF>cF&@Gn(8pc;kWJaaUr7Tq)8s=gDeFO zU9}(8nown~=m=%>On3y@ycCu`AjZ&D+^iIC$a2Ki5$?dmF}PVPOtg_J+$LIz z0Z6n~ZS3HpY;`X$f9@Vw)ni7v+%yhzSzHcEqjU`YZvb}&;h`>_>DY!o-e<&%aVjtHrt{|Y5AE|=TWmG6457jvwnd|Y%n*pFi1y4FJ_mIN zL_UO8O6q}cBV8z=R<_`56f@Kf3NsuND%}rzfbDbdUShcL?Eo7emI=CrNV=wo0o#m| zOfFi3!v|6~o2!U&0U@z@Lm-xEn}={4+V2y^Y|}on^rz_u4j1~3>rjodxJsl>_d9B1 zWvEZ3?Gx0?clj&GKd)VBb(tmS%z zY9)c9{6LX^uek9maZz2okT}DcA^rJFXhKmq)nW`vBRrzg{QTtgZ{%4~l%r7rBX~gV zNijxH4sdTG8@GY)-Z|9l3D|?OJ9UVVB7%b2?6Dd{pp0|1*(AaW7LW7HC3L?U6G3OH zH430k7V6BBYh!AWB5c?z=MV;qho>O~#f>l-7a3IrzCHoPW{0h?R>?A`sv?XzhbU4j zSRW*k#%vm-iN!5i`1W%?JsMrDR+4Z2>gjV>ci?dMCg|rMlGlRFInjY&r>Yx5v3emJO5JdF6jheljZ9Fn@eX#zS{a1dI8QRQOp}zogcl`& z+w3}5fqZN7$nUNUPVSGNgTD1z*~Ukne)`z&1V|+Lr!2J15yFjeFm15dqRVa1mvhHR zbzaZnPa$>#nQh)i=p{0M`Md3oibTVOdO_!<@`m*H|LyUUcaX(1l}pKI8Wyn2z-|!?V@LRYVlJ11;Snj3@=>gWxI(DN2RN=;nk0;rK->cz<;c zYAzBM0v8%46eML4?o49AjVO_5a~Q-FoM-#EY99QY$-*z4hEq1wl9ENA2XbXCYW&dv ze8n()`H9(zJ4z;%9_9k7mY7$k11gDQAvKIHhRcKf?jB555Yj10n6|jm zyMQGK8KW~2tYA32SRQuF`-}aunD@$ndiC)N-s~Ulfu2)Xkcfi?Pk;l)22T^NF?3d{ z0>YS44QQ7_Jk&RYzS@87gjVHYJ`k8hdO_4p8rO8wf990;I^gPYWA8_qw7V#UHYaOejPUpq)CEFKr*7@mbI2`5sqA7T3 z&|0OSmtvb5*MsqJblrdd$v?gR?P@geKlMi+2WLL2_lN!K&;9FC&@;(nbl1m6!}GzV ze}0CZzv&)!yYTcW)E}Mn;8pi^w_CSj-IDt)rYsNqZfXwPZ{2qAecKK*=PaUu2&$y7ZV(UZx?Exr5=J~gPo?e{yFGv3yK%F^{0{UIs4m0O|5YUEu-^g&3lL@2V zsoO}I)eJy5KYF@gx?bz>lo1*l@x*{Y|_pGiFos5ZTLfEtt>?3YF zR6)h=*M3aitz!=Mz*=ebWQL;q-v7d97 zP>7)>(>;|oI?+c>|Nir@!t^k0*O>jB-a^*By&Pe$p00W>#jV{uu6K8@RWzc98Vob4 zYmhq>VTyx8Jqjgg-KJgvvirL(yh`0xstF{$(-=o%9X1vTCh{{TCdLe^wZSjj>N>KJ zh4P#jD&<*fwwVH~S7(-=uJ~w?pQ`mzCraQL=7Ha zfx@Uqj+SCkfQ6nAoq1Fq8*H(hIt+VI4!?mc^Pyd2OkQE_%%--JzM*XqofWs!@Ll4{ z$#h)tARB+4pI}+x_!+vftt7Rqtel7j_$QSaY2DhgovqCvX0umeN=Zk?X_;rp3vM>{ zT8P4&a&H5=8ENGnq?2GuVs#^(_mVDopl0}u% z%06brn1j^LQ^(sy?}gm%;g37^h?V8Xj;Wj(Rbnc|b8|K)U(%T2{lOzrl9jhJmOE|O8S|Z1 z8=BB8MAo8+%;}Iesu;GK0tRy_bj;`!;T2KgNU%2lc)PJssTuew4LWLX9pP^ap7fAR z2##JGr=G%zWP$?n(^lvnyr>2Ap%TObXcK-`W?>gL-;E)DQ0JU=qA8+-vakoxT7>Ex zVkQ&lp>L_~weS?hj~fJAR+2LvMvWkg%{ECGBQuWK*#WygV-phG0Fg6Hc#ikqDFTRt z=9@ixH?bEYDQ*s~qm{^W5mUGn>)}UFi=#n65r0ks-6&2*a7^ zG-Z1yrmJUjVZemKEny-}&o^;Za~!|cbJB+FcRc0U8RuL7tMJxNnpd+liK0TC=`(l2 zTqk(_)4}ECb${3&wVLgXg2sqh#BmU74hN^d^hbViq}hUZIMLUa;Rp`8FV}>%>NT|K zB9x+8SXcsd3jzFhyj+wYH+uU$4o&A2&0S#O+EKZUmg7wvyOdn5-B=zP{{Zb*+in{- z5PjEI3=jj73`Og-0UF57#Z6O0fRh-GgQ9SPEX^HxiR_XKl51Ni0`zP8Vf~WMkh?3b zq{L~_^re*_Eb($?=FFAfKd$m>FwmkzR|$!5ibDFguZ{eG{%|m;UAN>dit_D`byeU^ z{4v)a?SgL6!DN4b0Q+#Hm!PyXrP7xmbOxsOmxg~xqcuvej0WYvVr9`G0c3Eo1fSEI zYT+h~5y?rEdnalU ze{>d)*%p|4*4YcCN!=_{tU4K9SyQ3)3LPxSKA$5LM$!iJYq2yQ`8e_EU?dAg>caeF z9L&klVq|xXjhtw`K-7Saja4ouFL;wItSMVkUl_;Ql%>(dazX^tQ7uV@juNIgAg50| z=oJ?rNHCVllZP3PoGgk0WFef}MnU5AHQFn*>ula}VQIxu>m`cH>@dtKPYnparKbbK8_C? z*ex*BSr2Oyg%4mhycNb;V|zf)ZX{OW>mF`{^6?oAVM@DqA6=qzMXTll?*x=up_MiZ#=Q(J|U7EL!Z!K__I%?*w3sZGYTq>x)quA$+SG}^_FCwNeFsv^od(%QaXca-fYTOE@&pk`KuYiWV}K@>QE_4b;AZ@m`e(qo$p< zuwp^C0`e|yV(gEp?0a}|^b1L6!l{L(FW(#=r*I{T8beQ@_Bq|q_!XhrYvnLpzgEFN z;eO|@zN12ur%>d=9gruX`FE;Phw-wac)s_|chdvH@u{ORCuQ2&jieGjPpB34PP7)nOZGt=40NWhR7SNH$Odkd zmC>;tQ_zX3DwGs~R9B%?3nfFL&agsmVG+*gjV1!#3hgRmJvV)Cq$xJp4e`Lk5|h@9 zL>Gel;hG~^6n72o-Eb|mUyq^r$s}x+V%dUnXK{wR2rE&j4>50M|8!35sftdMr^`_# zti$)UEk-TQBxJ*z)8qHgU%ft~;2WO58-7tf5$czu(vv0(A2+eKvuaQiS%Lo^B@=&+fDuv$o-V+yHdEIK%gs;Br$JSsPgt84G?h>?o#G35m2b zS;c`S?Or+@fRs`+n1pwwhO#caA}v?%RB}5`FQ-&K!vi2E6IX#fLJbxuV!stI4T}8|leCRLX_qahM-#84Y*sb?&~(j1K(?MHq1YB@Hn%B!)FI2KvxhheVUZ=FmW3dob<&W9%59rq9Xfzo z451&>zc7X*i{k+>A=q|z7ER|9uIJ^48b|c#t5qZqPj*^Kvgwy4*7Qstho52An0AdV zr^mU8$Hz-lt~Y=MizRw3rIn3UX!P<^cYq4(+?7+ylQ94e&9NO1h3QJCHe4 z15DUMj6rTJcRbJ9uZKXDi3AE9`U3yfr)f9+ZaBJ*6_A80kXf2?LC^!5*z!z38Z))v zVh!&3`TMu<8eSd!cIwgDBNz_h_mIyCgBuiVi5JU+3*1>$1fg`!Cs$G~bLR)(91n+% z2jlU$h;73aEk$8QFG$NAvtwdN!ojEx!2e~9+J1b1r+^l<)+h*;p=?FGCjy`(?R3y35{Mh&>ri>vo% zm!30d?f2(Mq=0kRnO#r*n%)IQl#D$EzcvNO@bYDCzvp$w(?WF(<`(?X&Z9jUHmYe% zaz=yVx~;X;#IJUm$>H5+J!~3Cfj|Ogh;9iGLKOW}iIw|zc%oLAxV!u-S&6>ev_z90 zX#RD}01RwDjq(BfP#Ua1cYZaoL8;+pNwHfm-%W0Y7dKFyMX45sh;y9Rac_r;s1!%N z+PXoqr6wZAWl4y90TauSFD;~4n<%g`m*`seUk>MDUr=B(IhtG%+=A?`@?6l@VsrOsn zD6s{_!EiZL2si76*`zQn#7P1TZB3U|uKqew#ib|JU>Fcs` zeZitwBl84u0PP6M!Xr!OrSbX6--*NLfOwlFDq7<+EUJfN0gl3JlWA%9ocxqmoKWp^y_QrH05;3oH{cvg})2Z zY{LntOC}z4Oav}a5U`239=2d2qoF~~Q4VeDtabT?P)|_Y!%s(DN0L5EK zBcysl_oJJlgLc@&E^N4nO+2W1NKvRQHDYB9^*t!T+Pr9V5c!}wqtYQ|q$xnxh%Uig zg{BRI)ttf!Mth=DLDB4EMdu>v3v+H~8_J=av2^X?#H2UpH}LDxF9w)#EW7k}^oKJ= z4OUCGV(h{IN#&I%oh+?~PKu(7BdL3b43^Zv?GvvbVeK#n(f4yZ%LBDsEe|IKD&N|x zN4}Rj$?J!_P1H%?)4c?FZFG$VL{*;CzDs*N?Op9&Y0tK2y6rU;mKg%*+KJE zt1m1Y#l7939yy+#l`sLfUKQWRwt75Q3quXwcwafBx5ni9>gw#x_3hpCkFFO-IodA| zYh(TWVJ*-r&DHBW7}s;b;sArH$ zV^JimZ%AC1(&4BxPo>Bp&V(`Gj{#Q}Wn!T20;J14W6w&pieTq+2k6OldPiKKYgkM? z-6?Z*&mLU7ulQaPO;0cgOP%vYY62NtrG|{nm4;tWL8CBA8c;HO03j1F3sqzZNM+#~ zfkKqf@xxMS9JVlLvzbd=_-{0Vr?{1eUBh94V~}{?$m`VejK=+=-IaR>Z+;k#>F40^ z$MJaF`tU>xBkiI{%{5|1`%dpW4$-g?5H<&s-#>o(@E-pBcmF45C1blOsARF5y5mWDT3K4sZfN-x?M;m-QbV8O_b{NkF@ z1M@=0E?RJPMJCCQBDRrpV6cg^Ye1f8o^8pJj`<+!_ZizS74{?C@_*kRGU(yq4ce$5 zwhV8Y5f~v;oBrn$+RkJ;=Vg&=m7}JD;>49JfF6=Z6`9wsA$pY>LpI8@iykGgciDHc zbx~%vi3*vnNY?MyT&kz1a-8wu_+)K%(ev2wlZcZ8Wp}n5to01HNoURA_oc-KpUQkl z!=NQ454TI%$(p#5)-%*K@q%6<$YHki7N&EGRY->)BtSDJ>UQ5u zf_7%tKdg4wIj7F$JC`c|^d?(m8yg9ah03@u*oEMJJ{hO}oyd1LHVP%!(Y;7SERuXe zPx(e??%@xaO-K@%mj#@L z6~nYX)PRLKdkCY533w9gvz2-?Cdgq}&KJa4Eoc)HmGcBKs(eD~&kif1l~+dV zjM&~!6W3YEbp~u+B>IuLJ(Aewiq>QQB1!ZS{vu`0dBj5ye#&c#8vi1dr8YPoWS9%rS%@e~DfCi2b5=ZF#q|5Xf1}4Q?Es90 zU_4Uk8rTp(;#5-Pa~?*j4EtLJz7}=$zQ;j&EwmWMkKx8V#FIsDi4UMH7fGO4J%j4l zZtn+_OTH{rbgr9)ZISdzVYQSA2gqUhw6X-mo&lWqB0;CGS zvxrwld88Nv^d$6LNkOQ|v$r8EYUhv@SjxRzAUmyqRZ>zig^8cW?F@ZP@=htU8QvQH zbOOy-kopC=Rs`6j9|NVR9w;=_FO$gp`sQj-F}K7W&uiwre@B%oOzwFU1`LX%Mb6SW zlRUWu_RFUj$g@mviTa(g z8^QGM19k&D8(@N|bMiiORpF!fsZv~M#6eJy0-Q;jo7zp@s@_O32T-v?3%g$B!&01e zC7WFoD4?-;x(C~gu*&Du^6DyTg#=aWmPSwU^NWGW^2fY=ilPe5curn|5<*Hi1_=>_ zCY@rwgwy2`@Xkht0MreGVU@JRIuCCP$%(y@ZxjYmS&fN7@mry*gP#VX zlSho-5Sob##uX@vTDRIhM#Xl%z0J7fF_I$xta3^E>gF&H@C_FyMSO!;Ta>Wb>lq;d zPaiK%%3OykF{Kd&a5NmwgW>C0OZ=P0Kw|t{k=RI2)+I{`$`yjS>1(xY?g;DP20~i( z6x^jCn+!ZcQ4W@57(q7?0qe1oKvzVO5oB5o zeV~s!$)vcQ#ys~IuJheLEC0EZ;JLT?9p(isbTjt68fO`xJ?0{89+t0OUhh`RUm9CH zn}li#GE&cDpFeBPpV*7?aet3ZsLdarUQRz8{G+{(NnlEvwc&9a4D@jcme0KQvqsyrwbv*WlO&YJ*h`oB%;P>jrSC5+%;q84J0uzci zBORg92qTi~?RJPw>j(MU$vi~@yG|7oJ!Mfe9QoX-?MP16EuQV|?KS1Jor$XUfnrUm z3DB774bFEId*D(7)8_e3o6l&oN-%H4-UG8}xG2N4hL#WP#v^v5OHxo|J>xcez00yx z(bT@AQcVRkacqenv8%sakJw*%&_7|6o-#ELu+a}wcyfyIOS`iX&^oq1g@ot_Ej8AeWBt4;9I=l+ZmZ3R;?XoI*(~PqY+-~BH|ijy>4!pg>Qj;jAlTgF<{WK zp;yy@=iF^#vx(qmrK>=FA~UQ(fQ@!+3Bf1PMG63j&R#% zf3?#9Y6)!{J3=_!r!+A(U}(w0(*V`A`Hx2C@tE{&H7ETJ;CcDthd&RPHllF0J%)+k z|A9|q?0*Z-1Enxa)WG+Vj?_UKb4*}%WOqNl8++_wA?VbidWOIfQJ6FVC{AL`^g$!4 zz1zuB`R4=q-PwnO(uKq&!ca3V9u;cUlA1Ww5EJ93oVd6&x zrY9B`Q66R(rTjFa!yz5RQBc&c1;@edMsf{}mGJNM|KD6k6e^zxH%x?OaxNBuN<_vhGWmpu5E&aQ_k z<{r#l$F~U%uzkKRV}seEH#BR2no)B0W3)UBl+~jj4PQG)P{PE}{sO1Ov4-c`p{l)M z^P+H#0cAS&SkRG&q3r3Ix6VLLS0h?L*8*)f+`rD~`la?}dGMhs>1x596Qx|X-ssKH zuEymZO>;grmzb64W^4U|+Ds=Zw|n5{c5$c+fstsN8(GwnQrzI$|9&$h zWxYC054YzJsZ0&$eV&c;&9DblrLs7y5;%F!9k(Rqsbjl^K&V) z1^qeM`(~QvTrH7Ro#aZ%jnM9Bn%=QQ#BbE9*x=2{=ZI&ykg2;+q`BDe+Udbkq%46b zVOqmH%EmHHd6Y{9Vv{ADcxc!i?&Kf*`vCBhDRIYg4u^?RyKxjrB>qfxn&aXo5fLnl zG$O$ehWK9Rs)%yGVVUIxr;rv&G61F&yWcUxV{_mKf#GVkpwD5x7W&yMch~Yb8v(H% zjaEGOgOfIG#k10tUVrV^II>Rg4+|yQ(!~<|1zM9yZQc*S8yy{a0i2$m!jdJL2Q_M= z15%-6FOM>!grPa9baYA>(u^q#!YM59LG!RsiB;mHA^(Y^`|<^z2(8g%d+^cI(HaBk zeHuV{vX(lpf6t`C?*ZLyUxFv6R!y&Mg5r6hQgG?FQ2Y;aPs+Ej*q4QVg8_ZKe+bNQ z`0aWMKa^g;f4m<+Xb_eS_><|yhd1YeH|X47#2ho2$G$ha9RG7N4=pJwdj^Zf5scu) zi^lyR==Zmv6k6m;Z2Y#vypNx}mfv45P<|d}Ihu!8ABg#1?66pJ4XMm2Q*$O#U|`)x z%ER>P|Ln%2BOu5rt88V|7N(AD-Ah%uyj|Z70iHI9>A~r%R_*S{f|G_|Qz*#FdQ-y^ zT@HU1T-~GiO(s)31-T?IRyrWLt^lSP2-wM)-22LW?bME2?@LBN|Vtk z*Ex?%Jd;WfKo`*(P!y{(dYkI18z@c~A<`8H^k+xWmIk~Qcxe(Dc`G!B;~&Zah6JQO zs>)M#lb}8cb`1pxw8lR4A!nOm%SY}CC3)l8z+R#XNWC1^g+c<6qqt#T7%3FCrb+jn zK$iK4FsKv6z}~bpsX4othE5fepP1RaTV7tqxeARilf-QWn)Ou6WoP<1U$N*OuHIe2 zukdpC3y4)J6_)#sFQ!k7LHe^0bevfFb_fJk9%u2e%^m{=WQgYKuH@IeYZ4K&=!R3q z**M0CJeUu=dPcHAn={+#Lb{h)v-F;zslZ3#WUAVzK9;BuTk)y6Im@xA8g!=d zBJ1$O z$pH(lctgV$YYf|rMb?`lClMLT*N7-63n3c=Omn1IqM*Wxq1>rJSMiO+X|Xv8HJUCp zw^9Ar4lA`HIkaGbOkOYSV`w`@7$pMjX-3zHY=-TSE0xOb8M1309yh-(X7lUGoA=@P zd^)+9hvUnOi^+HnU)nF;%>H#TE?>7;IF(&$h7o?txnHJg(A(oE@6C*1rVZzS@0d5* zi$D*uIqaw6$Dr3o4U-By9@#_dC491b&CJxxXoSZG8GP&7pj#&P#Un?FEfcwEdeKg; zD*olvU+n-D8|MVFx^#s5*WZoyKIVj$$sHe1c953>(`kLfc~JUyU_8+26-4vw6^rBF zmBNuCf6BUeb z;zZSPB6*2Om{7ZeQ7aeEx|xaUa1g0P_{s@Z-l+$d1Dc!@)e@-Ht{NRm{Vcae)CZbHmm` z4Q41C*d2P9Hl#C{OI#t^3rMf!-5(@qc)Fha{kPfVZS!Y|+6%M{gZCJ}c-;V>d3&7j z9pFzhc`x~5X)5y@n0fepGg|ri>u0sP1Jmx5K%bz;rU&z<9DR(nl?4?Xn1QF4ZF5(u z4~_MK>-&eehi0ofc{iH>)%HrOTD2X&9R7ruz2OveUG4G=5sL;92kj9{67V(0j)FU$ z4jK⁢0VbAH$D7!b0efoL;D?(!HPnoP(i6iU0lDA5bzLhRnQR;h{%6!c@tE_7F@$EH>F}D$=+OfM_Z*#^gc76SJ ziY27^1k$A7jbW)46{|G6-LY-Si^6GIeoTtSM44BH=Wz5klS#(5T*6Gdwc-*celhlJ z7gzH)S1i$a4j;=ok zwioT2U}gNx^XJc}XHP8ex<2;nW-PCjnlWCMd>4}f`sQCzB9@S*uo~fl+B^A-NyD~MDJFnTa(L^3B@+Ze(z%r;BYk16 z4MuBdX+Bi}q znP!o5eD@ryQg0%5(v>xQazKU8g7bW_9+#a5e+louX-slFmlv#C>z@SyF9*<*gb&Impr4M791&PvN34%hM zr<9r$xxKV`B05%eFED{;*hK6({?aZdKMU*LcQ^!Ji=kupy>cxC~f#R7}asB%JPj7!9owbj|8nG{BGIBynG{Mv6V6Q4TWUwfV zkE8?U=0_`;bLEfSbp->b2q1`ct5dfK3^zhl@fD@K=kVFYB&b-u5dnAZe6{IKcm_ia zvb08Zh`wj+q7=O znhNPJwFJemd#+^4K9Pn2*?*ojLe5OUjqKd$%CK8r0W_8yHhjmF)^|Aa2Au(&R>?a; z7l1A;bR&4TuB;y#l~fzTB7dYJIwkZ) zN+(<`$l!>*IA@XXCJM2Mnsw85U&|)Fqx9)vcyLFgxrToQe9Fl=q2w9q7~-}D;ZppG zYn|2+Tw)BkMQs0#7*p6f0S;jJXhVdoleR>2;_4kF9VYgyE4axj25?zDl&02RoukQ0 zI2fhT%kyCgpbD=zCApCsaWYJrl_RnyY4602SkmV-oZ#Dl0z6V=C9i~|vy9&hV#Eqv zr(8iM2xeSM_x|DQ< zoEcM8r}Oz5=&x^2kmK``@CE?StwqPQ?rZun?dP=J&R2W(F_BUFc@Q53R@%S#ir{NUhXtPe)54f}^ww4YFwDsH4)sr# zC@di^0gr9p;^J|jl#XcV9JWzL2m^Z};@$(PhEZ*GB#VF?wVRFgZ-hjm8{z2N*U*%W zvd*5h)g84;Z9Rg!pa=0 zfGdJy3*qDrftcB{VVSy76Xb2CTy$<pJ|(k?lZx-xom=(Pcaw|^;h-5tWxDBK8(1{qo^ zI_)TWy0@hLD^kZn2X0FH-CQH{%3^-lH2)TYW*g?g;+H*cbhJ2FVry3Dpu;2qXj>h4 z39@{s#F{5N_WJeD@7TBO?Q$i+tX6G*zW&He8b2F#8p)P z+rl24gke|dr&GI^ySLDXPB{MRrrC5MzR1c{apc%w;jViNkyC+Q*tSPU(`iSZKI?hg zcifD7KaMWLJ;-v0ceLvxU5|w}%=YbZ8=jZbXnICZKCh@DztC_2IOEMa#|1YS@Ng7< z#mc5q*~~A@uG5=Yip0M3fWdCj<=hc^JM*}rLL_JlzWdvYUYq2ha;JvIKwU2T40Puct#=s48m z13bD1$EO}i#~5;w>_7FQU|jT{R{LnQ$vuKbOO%KHDG^8C6Bqg0TvOF8?88CZU483e z`;3t$4piL%qcyAhLfdm`-}R$F1V7vNn|Q!DXg??PZy%z;iS6-+-njAg#7ivDsxEXf zB!}a3w+xs@;Uqwl)>)%-)FyB~QV&+s^E7Kx?N*Sj?ybze=Jp<<(5WTl36EHJ)Q*W(Q)-l&VY~~Bg0@o1Hm4%dsehc2H}60 z9olk_fM;D_%o-PsT4H5=dAs>g=k(grLVj;OeNhMH^iK(9U(0mO?QJTrz9hd#<;4 zgQy#cp%e>Uu(KigodB)Ih&7SJK(_A1n4e2hwe*SyQ81fPJ=Ph|UAALo%z_e>mojg2 zBWqX#w-WZ`VuOgt%K`#HQ9Pi_@^OoOe)-akh1sBCZne)XmXKAXsL?h8hL9GcQJO

LlKxzkEWa-_P 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 literal 0 HcmV?d00001 diff --git a/docs/KNOWN_BUGS.md b/docs/KNOWN_BUGS.md deleted file mode 100644 index 90202922d..000000000 --- a/docs/KNOWN_BUGS.md +++ /dev/null @@ -1,59 +0,0 @@ -# Known Bugs - -## Ubuntu 14.04, Coreutils 8.21 - -There are known bugs with relative symlinks `ln --relative`, which may cause the rollback command to fail. - -Add the following line to your _deploy.php_ file: - -```php -set('use_relative_symlink', false); -``` - -## OpenSSH_7.2p2 - -ControlPersist causes stderr to be left open until the master connection times out. - -- https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=714526 -- https://bugzilla.mindrot.org/show_bug.cgi?id=1988 - -## cURL 7.29.0 - -Certificate verification fails with multiple https urls. - -- https://bugzilla.redhat.com/show_bug.cgi?id=1241172 - -## Rsync (3.1.3) - -Artifact upload with `rsync` is interrupted after the first chunk of data upload. - -``` -The command "rsync -azP -e 'ssh -A -p *** -o UserKnownHostsFile=/dev/null - -o StrictHostKeyChecking=no' 'artifacts/artifact.tar.gz' 'deploy@ssh.XXX.io:/srv/releases/2009076181'" failed. - -Exit Code: 255(Unknown error) - -Output: -================ -sending incremental file list -artifact.tar.gz - 32,768 0% 0.00kB/s 0:00:00 - -Error Output: -================ -client_loop: send disconnect: Broken pipe - -rsync: [sender] write error: Broken pipe (32) -``` - -In order to resolve (workaround) the issue, you need to add `--bwlimit=4096` to the list of options. - -Example: - -```php -task('artifact:upload', function () { - upload(get('artifact_path'), '{{release_path}}', ['options' => ['--bwlimit=4096']]); -}); -``` - -The issue was also described in the [Github Action](https://github.com/deployphp/action/issues/35). diff --git a/docs/UPGRADE.md b/docs/UPGRADE.md deleted file mode 100644 index 726fbfd49..000000000 --- a/docs/UPGRADE.md +++ /dev/null @@ -1,274 +0,0 @@ -# Upgrade a major version - -## Upgrade from 6.x to 7.x - -### Step 1: Update deploy.php - -1. Change config `hostname` to `alias`. -2. Change config `real_hostname` to `hostname`. -3. Change config `user` to `remote_user`. -4. Update `host()` definitions: - 1. Add `set` prefix to all setters: `identityFile` -> `setIdentityFile` or `set('identity_file')` - 2. Update `host(...)->addSshOption('UserKnownHostsFile', '/dev/null')` to `host(...)->setSshArguments(['-o UserKnownHostsFile=/dev/null']);` - 3. Replace _stage_ with labels, i.e. - ```php - host('deployer.org') - ->set('labels', ['stage' => 'prod']); - ``` - When deploying instead of `dep deploy prod` use `dep deploy stage=prod`. - 4. `alias()` is deleted, `host()` itself sets alias and hostname, to override hostname use `setHostname()`. -5. Update `task()` definitions. - 1. Replace `onRoles()` with `select()`: - ```php - task(...) - ->select('stage=prod'); - ``` - 2. Don't use string-based task definition, it's not available anymore. Don't forget to set correct working directory. - ```php - # from - task('deploy:npm-install', 'npm clean-install'); - - # to - task('deploy:npm-install', function() { - cd('{{release_path}}'); - run('npm clean-install'); - }); - ``` -6. Third party recipes now live inside main Deployer repo in _contrib_: - ```php - require 'contrib/rsync.php'; - ``` -7. Replace `inventory()` with `import()`. It now can import hosts, configs, tasks: - - ```yaml - import: recipe/common.php - - config: - application: deployer - shared_dirs: - - uploads - - storage/logs/ - - storage/db - shared_files: - - .env - - config/test.yaml - keep_releases: 3 - http_user: false - - hosts: - prod: - local: true - - tasks: - deploy: - - deploy:prepare - - deploy:vendors - - deploy:publish - - deploy:vendors: - - run: "cd {{release_path}} && echo {{bin/composer}} {{composer_options}} 2>&1" - ``` - -8. Rename task `success` to `deploy:success` and `cleanup` to `deploy:cleanup`. -9. Verbosity functions (`isDebug()`, etc) got deleted. Use `output()->isDebug()` instead. -10. `runLocally()` commands are executed relative to the recipe file directory. This behaviour can be overridden via an environment variable: - ``` - DEPLOYER_ROOT=. vendor/bin/dep taskname` - ``` -11. Replace `local()` tasks with combination of `once()` and `runLocally()` func. -12. Replace `locateBinaryPath()` with `which()` func. -13. Replace `default_stage` with `default_selector`, and adjust the value accordingly (for example: "prod" to "stage=prod"). -14. Replace `onHosts()` and `onStage()` with [labels & selectors](selector.md). -15. Replace `setPrivate()` with [`hidden()`](tasks.md#hidden). -16. Configuration property `writable_recursive` defaults to `false`. This behaviour can be overridden with: - ```php - set('writable_recursive', true); - ``` -17. `.git` directory is not present in release directory anymore. The previous behavior can be restored with: - ```php - set('update_code_strategy', 'clone'); - ``` - -### Step 2: Deploy - -Since the release history numbering is not compatible between v6 and v7, you need to specify the `release_name` manually for the first time. Otherwise you start with release 1. - -1. Find out next release name (ssh to the host, `ls` releases dir, find the biggest number). Example: `42`. -2. Deploy with release_name: - ``` - dep deploy -o release_name=43 - ``` - -:::note -In case a rollback is needed, manually change the `current` symlink: - -``` -ln -nfs releases/42 current -``` - -::: - -:::note -In case there are multiple hosts with different release names, you should create a `{{deploy_path}}/.dep/latest_release` file in each host with the current release number of that particular host. -::: - -## Upgrade from 5.x to 6.x - -1. Changed branch option priority - - If you have host definition with `branch(...)` parameter, adding `--branch` option will not override it any more. - If no `branch(...)` parameter persists, branch will be fetched from current local git branch. - - ```php - host('prod') - ->set('branch', 'production') - ``` - - In order to return to old behavior add checking of `--branch` option. - - ```php - host('prod') - ->set('branch', function () { - return input()->getOption('branch') ?: 'production'; - }) - ``` - -2. Add `deploy:info` task to the beginning to `deploy` task. -3. `run` returns string instead of `Deployer\Type\Result` - - Now `run` and `runLocally` returns `string` instead of `Deployer\Type\Result`. - Replace method calls as: - - - `run('command')->toString()` → `run('command')` - - `run('if command; then echo "true"; fi;')->toBool()` → `test('command')` - -4. `env_vars` renamed to `env` - - - `set('env_vars', 'FOO=bar');` → `set('env', ['FOO' => 'bar']);` - - If your are using Symfony recipe, then you need to change `env` setting: - - - `set('env', 'prod');` → `set('symfony_env', 'prod');` - -## Upgrade from 4.x to 5.x - -1. Servers to Hosts - - - `server($hostname)` to `host($hostname)`, and `server($name, $hostname)` to `host($name)->hostname($hostname)` - - `localServer($name)` to `localhost()` - - `cluster($name, $nodes, $port)` to `hosts(...$hodes)` - - `serverList($file)` to `inventory($file)` - - If you need to deploy to same server use [host aliases](https://deployer.org/docs/hosts#host-aliases): - - ```php - host('domain.com/green', 'domain.com/blue') - ->set('deploy_path', '~/{{hostname}}') - ... - ``` - - Or you can define different hosts with same hostname: - - ```php - host('production') - ->hostname('domain.com') - ->set('deploy_path', '~/production') - ... - - host('beta') - ->hostname('domain.com') - ->set('deploy_path', '~/beta') - ... - ``` - -2. Configuration options - - - Rename `{{server.name}}` to `{{hostname}}` - -3. DotArray syntax - - In v5 access to nested arrays in config via dot notation was removed. - If you was using it, consider to move to plain config options. - - Refactor this: - - ```php - set('a', ['b' => 1]); - - // ... - - get('a.b'); - ``` - - To: - - ```php - set('a_b', 1); - - // ... - - get('a_b'); - ``` - -4. Credentials - - Best practice in new v5 is to omit credentials for connection in `deploy.php` and write them in `~/.ssh/config` instead. - - - `identityFile($publicKeyFile,, $privateKeyFile, $passPhrase)` to `identityFile($privateKeyFile)` - - `pemFile($pemFile)` to `identityFile($pemFile)` - - `forwardAgent()` to `forwardAgent(true)` - -5. Tasks constraints - - - `onlyOn` to `onHosts` - - `onlyOnStage` to `onStage` - -## Upgrade from 3.x to 4.x - -1. Namespace for functions - - Add to beginning of _deploy.php_ next line: - - ```php - use function Deployer\{server, task, run, set, get, add, before, after}; - ``` - - If you are using PHP version less than 5.6, you can use this: - - ```php - namespace Deployer; - ``` - -2. `env()` to `set()`/`get()` - - Rename all calls `env($name, $value)` to `set($name, $value)`. - - Rename all rvalue `env($name)` to `get($name)`. - - Rename all `server(...)->env(...)` to `server(...)->set(...)`. - -3. Moved _NonFatalException_ - - Rename `Deployer\Task\NonFatalException` to `Deployer\Exception\NonFatalException`. - -4. Prior release cleanup - - Due to changes in release management, the new cleanup task will ignore any prior releases deployed with 3.x. These will need to be manually removed after migrating to and successfully releasing via 4.x. - -## Upgrade from 2.x to 3.x - -1. ### `->path('...')` - - Replace your server paths configuration: - - ```php - server(...) - ->path(...); - ``` - - to: - - ```php - server(...) - ->env('deploy_path', '...'); - ``` diff --git a/docs/api.md b/docs/api.md deleted file mode 100644 index f5b758189..000000000 --- a/docs/api.md +++ /dev/null @@ -1,584 +0,0 @@ - - - - -# API Reference - -## host() - -```php -host(string ...$hostname) -``` - -Defines a host or hosts. -```php -host('example.org'); -host('prod.example.org', 'staging.example.org'); -``` - -Inside task can be used to get `Host` instance of an alias. -```php -task('test', function () { - $port = host('example.org')->get('port'); -}); -``` - - - -## localhost() - -```php -localhost(string ...$hostnames) -``` - - - -## currentHost() - -```php -currentHost(): Host -``` - -Returns current host. - - -## select() - -```php -select(string $selector): array -``` - -Returns hosts based on provided selector. - -```php -on(select('stage=prod, role=db'), function (Host $host) { - ... -}); -``` - - - -## selectedHosts() - -```php -selectedHosts(): array -``` - -Returns array of hosts selected by user via CLI. - - - -## import() - -```php -import(string $file): void -``` - -Import other php or yaml recipes. - -```php -import('recipe/common.php'); -``` - -```php -import(__DIR__ . '/config/hosts.yaml'); -``` - - - -## desc() - -```php -desc(?string $title = null): ?string -``` - -Set task description. - - -## task() - -```php -task(string $name, $body = null): Task -``` - -Define a new task and save to tasks list. - -Alternatively get a defined task. - - - -| Argument | Type | Comment | -|---|---|---| -| `$name` | `string` | Name of current task. | -| `$body` | `callable():void` or `array` or `null` | Callable task, array of other tasks names or nothing to get a defined tasks | - -## before() - -```php -before(string $task, $do) -``` - -Call that task before specified task runs. - - - - -| Argument | Type | Comment | -|---|---|---| -| `$task` | `string` | The task before $that should be run. | -| `$do` | `string` or `callable():void` | The task to be run. | - -## after() - -```php -after(string $task, $do) -``` - -Call that task after specified task runs. - - - - -| Argument | Type | Comment | -|---|---|---| -| `$task` | `string` | The task after $that should be run. | -| `$do` | `string` or `callable():void` | The task to be run. | - -## fail() - -```php -fail(string $task, $do) -``` - -Setup which task run on failure of $task. -When called multiple times for a task, previous fail() definitions will be overridden. - - - - -| Argument | Type | Comment | -|---|---|---| -| `$task` | `string` | The task which need to fail so $that should be run. | -| `$do` | `string` or `callable():void` | The task to be run. | - -## option() - -```php -option(string $name, $shortcut = null, ?int $mode = null, string $description = '', $default = null): void -``` - -Add users options. - - - -| Argument | Type | Comment | -|---|---|---| -| `$name` | `string` | The option name | -| `$shortcut` | `string` or `array` or `null` | The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts | -| `$mode` | `int` or `null` | The option mode: One of the VALUE_* constants | -| `$description` | `string` | A description text | -| `$default` | `string` or `string[]` or `int` or `bool` or `null` | The default value (must be null for self::VALUE_NONE) | - -## cd() - -```php -cd(string $path): void -``` - -Change the current working directory. - - -## become() - -```php -become(string $user): \Closure -``` - -Change the current user. - -Usage: -```php -$restore = become('deployer'); - -// do something - -$restore(); // revert back to the previous user -``` - - - -## within() - -```php -within(string $path, callable $callback) -``` - -Execute a callback within a specific directory and revert back to the initial working directory. - - - -## run() - -```php -run(string $command, ?array $options = [], ?int $timeout = null, ?int $idle_timeout = null, ?string $secret = null, ?array $env = null, ?bool $real_time_output = false, ?bool $no_throw = false): string -``` - -Executes given command on remote host. - -Examples: - -```php -run('echo hello world'); -run('cd {{deploy_path}} && git status'); -run('password %secret%', secret: getenv('CI_SECRET')); -run('curl medv.io', timeout: 5); -``` - -```php -$path = run('readlink {{deploy_path}}/current'); -run("echo $path"); -``` - - - - -| Argument | Type | Comment | -|---|---|---| -| `$command` | `string` | Command to run on remote host. | -| `$options` | `array` or `null` | Array of options will override passed named arguments. | -| `$timeout` | `int` or `null` | Sets the process timeout (max. runtime). The timeout in seconds (default: 300 sec; see {{default_timeout}}, `null` to disable). | -| `$idle_timeout` | `int` or `null` | Sets the process idle timeout (max. time since last output) in seconds. | -| `$secret` | `string` or `null` | Placeholder `%secret%` can be used in command. Placeholder will be replaced with this value and will not appear in any logs. | -| `$env` | `array` or `null` | Array of environment variables: `run('echo $KEY', env: ['key' => 'value']);` | -| `$real_time_output` | `bool` or `null` | Print command output in real-time. | -| `$no_throw` | `bool` or `null` | Don't throw an exception of non-zero exit code. | - -## runLocally() - -```php -runLocally(string $command, ?array $options = [], ?int $timeout = null, ?int $idle_timeout = null, ?string $secret = null, ?array $env = null, ?string $shell = null): string -``` - -Execute commands on a local machine. - -Examples: - -```php -$user = runLocally('git config user.name'); -runLocally("echo $user"); -``` - - - - -| Argument | Type | Comment | -|---|---|---| -| `$command` | `string` | Command to run on localhost. | -| `$options` | `array` or `null` | Array of options will override passed named arguments. | -| `$timeout` | `int` or `null` | Sets the process timeout (max. runtime). The timeout in seconds (default: 300 sec, `null` to disable). | -| `$idle_timeout` | `int` or `null` | Sets the process idle timeout (max. time since last output) in seconds. | -| `$secret` | `string` or `null` | Placeholder `%secret%` can be used in command. Placeholder will be replaced with this value and will not appear in any logs. | -| `$env` | `array` or `null` | Array of environment variables: `runLocally('echo $KEY', env: ['key' => 'value']);` | -| `$shell` | `string` or `null` | Shell to run in. Default is `bash -s`. | - -## test() - -```php -test(string $command): bool -``` - -Run test command. -Example: - -```php -if (test('[ -d {{release_path}} ]')) { -... -} -``` - - - -## testLocally() - -```php -testLocally(string $command): bool -``` - -Run test command locally. -Example: - - testLocally('[ -d {{local_release_path}} ]') - - - -## on() - -```php -on($hosts, callable $callback): void -``` - -Iterate other hosts, allowing to call run a func in callback. - -```php -on(select('stage=prod, role=db'), function ($host) { - ... -}); -``` - -```php -on(host('example.org'), function ($host) { - ... -}); -``` - -```php -on(Deployer::get()->hosts, function ($host) { - ... -}); -``` - - - -## invoke() - -```php -invoke(string $taskName): void -``` - -Runs a task. -```php -invoke('deploy:symlink'); -``` - - - -## upload() - -```php -upload($source, string $destination, array $config = []): void -``` - -Upload files or directories to host. - -> To upload the _contents_ of a directory, include a trailing slash (eg `upload('build/', '{{release_path}}/public');`). -> Without the trailing slash, the build directory itself will be uploaded (resulting in `{{release_path}}/public/build`). - - The `$config` array supports the following keys: - -- `flags` for overriding the default `-azP` passed to the `rsync` command -- `options` with additional flags passed directly to the `rsync` command -- `timeout` for `Process::fromShellCommandline()` (`null` by default) -- `progress_bar` to display upload/download progress -- `display_stats` to display rsync set of statistics - -Note: due to the way php escapes command line arguments, list-notation for the rsync `--exclude={'file','anotherfile'}` option will not work. -A workaround is to add a separate `--exclude=file` argument for each exclude to `options` (also, _do not_ wrap the filename/filter in quotes). -An alternative might be to write the excludes to a temporary file (one per line) and use `--exclude-from=temporary_file` argument instead. - - - - -## download() - -```php -download(string $source, string $destination, array $config = []): void -``` - -Download file or directory from host - - - - -## info() - -```php -info(string $message): void -``` - -Writes an info message. - - -## warning() - -```php -warning(string $message): void -``` - -Writes an warning message. - - -## writeln() - -```php -writeln(string $message, int $options = 0): void -``` - -Writes a message to the output and adds a newline at the end. - - -## parse() - -```php -parse(string $value): string -``` - -Parse set values. - - -## set() - -```php -set(string $name, $value): void -``` - -Setup configuration option. - - -## add() - -```php -add(string $name, array $array): void -``` - -Merge new config params to existing config array. - - - -## get() - -```php -get(string $name, $default = null) -``` - -Get configuration value. - - - - -## has() - -```php -has(string $name): bool -``` - -Check if there is such configuration option. - - -## ask() - -```php -ask(string $message, ?string $default = null, ?array $autocomplete = null): ?string -``` - - - -## askChoice() - -```php -askChoice(string $message, array $availableChoices, $default = null, bool $multiselect = false) -``` - - - -## askConfirmation() - -```php -askConfirmation(string $message, bool $default = false): bool -``` - - - -## askHiddenResponse() - -```php -askHiddenResponse(string $message): string -``` - - - -## input() - -```php -input(): InputInterface -``` - - - -## output() - -```php -output(): OutputInterface -``` - - - -## commandExist() - -```php -commandExist(string $command): bool -``` - -Check if command exists - - - -## commandSupportsOption() - -```php -commandSupportsOption(string $command, string $option): bool -``` - - - -## which() - -```php -which(string $name): string -``` - - - -## remoteEnv() - -```php -remoteEnv(): array -``` - -Returns remote environments variables as an array. -```php -$remotePath = remoteEnv()['PATH']; -run('echo $PATH', env: ['PATH' => "/home/user/bin:$remotePath"]); -``` - - -## error() - -```php -error(string $message): Exception -``` - -Creates a new exception. - - -## timestamp() - -```php -timestamp(): string -``` - -Returns current timestamp in UTC timezone in ISO8601 format. - - -## fetch() - -```php -fetch(string $url, string $method = 'get', array $headers = [], ?string $body = null, ?array &$info = null, bool $nothrow = false): string -``` - -Example usage: -```php -$result = fetch('{{domain}}', info: $info); -var_dump($info['http_code'], $result); -``` - - diff --git a/docs/avoid-php-fpm-reloading.md b/docs/avoid-php-fpm-reloading.md deleted file mode 100644 index 971f3e372..000000000 --- a/docs/avoid-php-fpm-reloading.md +++ /dev/null @@ -1,62 +0,0 @@ -# Avoid PHP-FPM Reloading - -Deployer symlinks _current_ to latest release dir. - -``` -current -> releases/3/ -releases/ - 1/ - 2/ - 3/ -``` - -## The problem - -PHP Opcodes get cached. And if `SCRIPT_FILENAME` contains _current_ symlink, on -new deploy nothing updates. Usually, a solution is simple to reload **php-fpm** -after deploy, but such reload can lead to **dropped** or **failed** requests. -The correct fix is to configure your server set `SCRIPT_FILENAME` to a resolved path. -You can check your server configuration by printing `SCRIPT_FILENAME`. - -```php -echo $_SERVER['SCRIPT_FILENAME']; -``` - -If it prints something like `/home/deployer/example.com/current/index.php` with -_current_ in the path, your server configured incorrectly. - -## Fix for Nginx - -Nginx has special variable `$realpath_root`, use it to set up `SCRIPT_FILENAME`: - -```diff -location ~ \.php$ { - include fastcgi_params; - fastcgi_pass unix:/var/run/php/php-fpm.sock; -- fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; -+ fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; -} -``` - -## Fix for Caddy - -:::tip -If you're already using servers provisioned by Deployer, you don't need to fix -anything, as everything is already configured properly. -::: - -Use `resolve_root_symlink`: - -``` -php_fastcgi * unix//run/php/php-fpm.sock { - resolve_root_symlink -} -``` - -## Fix for Apache - -Enable `revalidate_path` in `php.ini`: - -```ini -opcache.revalidate_path=1 -``` diff --git a/docs/basics.md b/docs/basics.md deleted file mode 100644 index f68cd75af..000000000 --- a/docs/basics.md +++ /dev/null @@ -1,245 +0,0 @@ -# Basics - -Deployer has two main concepts: [**hosts**](hosts.md) and [**tasks**](tasks.md). - -A **recipe** is a file containing definitions for **hosts** and **tasks**. - -Deployer CLI requires two arguments to run: a **task** to run and a **selector**. - -Hosts can also be [selected via labels](hosts.md#labels), also a default host selection can be configured. - -``` -$ dep deploy deployer.org - --- ------ ------------ - | | | - | | `--- Selector - | `------------- Task - `------------------ CLI -``` - -Deployer uses the [selector](selector.md) to choose hosts. Next, it takes the given -task, performs some preparation (described later), and executes the task on all -selected hosts. - -If a selector is not specified, Deployer will ask you to choose a host from a list. -If your recipe contains only one host, Deployer will automatically choose it. -To select all hosts, specify a special selector: `all`. - -The `dep` CLI looks for a `deploy.php` or `deploy.yaml` file in the current directory. - -Or a recipe can be specified explicitly via `-f` or `--file` option. - -``` -$ dep --file=deploy.php deploy deployer.org -``` - -Let's write a recipe. - -```php -// We are going to use functions declared primarily in the Deployer namespace, -// to simplify the recipe, we will also use the Deployer namespace. Alternatively, -// you can import individual functions via "use function". -namespace Deployer; - -host('deployer.org'); - -task('my_task', function () { - run('whoami'); -}); -``` - -Let's try to run our task on deployer.org. - -``` -$ dep my_task -task my_task -$ -``` - -If no host is provided and no default_selector is set, Deployer will show an interactive prompt for selecting hosts. -If your recipe contains only one host, Deployer will automatically choose it. -To select all hosts specify `all`. - -But where is our `whoami` command output? By default, Deployer runs with normal verbosity -level and shows only the names of executed tasks. Let's increase verbosity to verbose, and -rerun our task. - -Add `-v` option to increase verbosity. Read more about [CLI usage](cli.md). - -``` -$ dep my_task -v -task my_task -[deployer.org] run whoami -[deployer.org] deployer -$ -``` - -Now let's add a second host: - -```php -host('deployer.org'); -host('medv.io'); -``` - -How does Deployer know how to connect to a host? It uses the same `~/.ssh/config` file as -the `ssh` command. Alternatively, you can specify [connection options](hosts.md) in the recipe. - -Let's run `my_task` task on both hosts: - -``` -$ dep my_task -v all -task my_task -[deployer.org] run whoami -[medv.io] run whoami -[medv.io] anton -[deployer.org] deployer -``` - -Deployer runs a task in parallel on each host. This is why the output is mixed. -We can limit it to run only on one host at a time. - -``` -$ dep my_task -v all --limit 1 -task my_task -[deployer.org] run whoami -[deployer.org] deployer -[medv.io] run whoami -[medv.io] deployer -``` - -It is also possible to specify a [limit level](tasks.md#limit) for each individual task. -By specifying the limit level for each task, you can control the degree of parallelism -for each part of your deployment process. - -Each host has a configuration: a list of key-value pairs. Let's define our first -configuration option for both our hosts: - -```php -host('deployer.org') - ->set('my_config', 'foo'); -host('medv.io') - ->set('my_config', 'bar'); -``` - -In the task we can get the currently executing host using the [currentHost](api.md#currenthost) function: - -```php -task('my_task', function () { - $myConfig = currentHost()->get('my_config'); - writeln("my_config: " . $myConfig); -}); -``` - -Or with the [get](api.md#get) function: - -```diff -task('my_task', function () { -- $myConfig = currentHost()->get('my_config'); -+ $myConfig = get('my_config'); - writeln("my_config: " . $myConfig); -}); -``` - -Or via the [parse](api.md#parse) function which replaces the `{{ ... }}` brackets -and their enclosed values with the corresponding configuration option. - -All functions (writeln, run, runLocally, cd, upload, etc) call the **parse** function -internally. So you don't need to call the **parse** function by yourself. - -```diff -task('my_task', function () { -- $myConfig = get('my_config'); -- writeln("my_config: " . $myConfig); -+ writeln("my_config: {{my_config}}"); -}); -``` - -Let's try to run our task: - -``` -$ dep my_task all -task my_task -[deployer.org] my_config: foo -[medv.io] my_config: bar -``` - -Awesome! Each host configuration inherits global configuration. Let's refactor -our recipe to define one global config option: - -```php -set('my_config', 'global'); - -host('deployer.org'); -host('medv.io'); -``` - -The config option `my_config` will be equal to `global` on both hosts. - -Additionally, the value of a config option can be defined as a callback. -This callback is executed upon its first access, and the returned result -is then stored in the host configuration. - -```php -set('whoami', function () { - return run('whoami'); -}); - -task('my_task', function () { - writeln('Who am I? {{whoami}}'); -}); -``` - -Let's try to run it: - -``` -$ dep my_task all -task my_task -[deployer.org] Who am I? deployer -[medv.io] Who am I? anton -``` - -We can use this to create a dynamic configuration which uses information from the current host. - -Only the first call will trigger the callback execution. All subsequent checks use the previously -saved value. - - -Here is an example: - -```php -set('current_date', function () { - return run('date'); -}); - -task('my_task', function () { - writeln('What time is it? {{current_date}}'); - run('sleep 5'); - writeln('What time is it? {{current_date}}'); -}); -``` - -If we run my_task, we will see that `date` is called only once on -`{{current_date}}` access. - -``` -$ dep my_task deployer.org -v -task my_task -[deployer.org] run date -[deployer.org] Wed 03 Nov 2021 01:16:53 PM UTC -[deployer.org] What time is it? Wed 03 Nov 2021 01:16:53 PM UTC -[deployer.org] run sleep 5 -[deployer.org] What time is it? Wed 03 Nov 2021 01:16:53 PM UTC -``` - -We can override a config option via CLI option `-o` like this: - -``` -$ dep my_task deployer.org -v -o current_date="I don't know" -task my_task -[deployer.org] What time is it? I don't know -[deployer.org] run sleep 5 -[deployer.org] What time is it? I don't know -``` - -Since the `current_date` config option is overridden there is no need to call the callback. -So there is no 'run date'. diff --git a/docs/ci-cd.md b/docs/ci-cd.md deleted file mode 100755 index f478b6a03..000000000 --- a/docs/ci-cd.md +++ /dev/null @@ -1,99 +0,0 @@ -# CI/CD - -## GitHub Actions - -Use official [GitHub Action for Deployer](https://github.com/deployphp/action). - -Create `.github/workflows/deploy.yml` file with following content: - -```yaml -name: deploy - -on: - push: - branches: [master] - -concurrency: production_environment - -jobs: - deploy: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: "8.1" - - - name: Install dependencies - run: composer install - - - name: Deploy - uses: deployphp/action@v1 - with: - private-key: ${{ secrets.PRIVATE_KEY }} - dep: deploy -``` - -:::warning -The `concurrency: production_environment` is important as it prevents concurrent -deploys. -::: - -## GitLab CI/CD - -Set the following variables in your GitLab project: - -- `SSH_KNOWN_HOSTS`: Content of `~/.ssh/known_hosts` file. - The public SSH keys for a host may be obtained using the utility `ssh-keyscan`. - For example: `ssh-keyscan deployer.org`. -- `SSH_PRIVATE_KEY`: Private key for connecting to remote hosts. - To generate a private key: `ssh-keygen -t ed25519 -C 'gitlab@deployer.org'`. - -Create a .gitlab-ci.yml file with the following content: - -```yml -stages: - - deploy - -deploy: - stage: deploy - image: - name: deployphp/deployer:7 - entrypoint: [""] - before_script: - - mkdir -p ~/.ssh - - eval $(ssh-agent -s) - - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts - - chmod 644 ~/.ssh/known_hosts - - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null - script: - - dep deploy -vvv - resource_group: production - only: - - master -``` - -### Deployment concurrency - -Only one deployment job runs at a time with the [`resource_group` keyword](https://docs.gitlab.com/ee/ci/yaml/index.html#resource_group) in .gitlab-ci.yml. - -In addition, you can ensure that older deployment jobs are cancelled automatically when a newer deployment runs by enabling the [skip outdated deployment jobs](https://docs.gitlab.com/ee/ci/pipelines/settings.html#prevent-outdated-deployment-jobs) feature (enabled by default). - -### Deploy secrets - -It is not recommended to commit secrets to the repository, you could use a GitLab variable to store them instead. - -Many frameworks use dotenv to store secrets, let's create a GitLab file variable named `DOTENV`, so it can be deployed along with the code. - -Set up a deployer task to copy secrets to the server: - -```php -task('deploy:secrets', function () { - upload(getenv('DOTENV'), '{{deploy_path}}/shared/.env'); -}); -``` - -Run the task immediately after updating the code. diff --git a/docs/cli.md b/docs/cli.md deleted file mode 100755 index d32d8e6a7..000000000 --- a/docs/cli.md +++ /dev/null @@ -1,148 +0,0 @@ -# CLI Usage - -We recommend adding the following alias to your .bashrc file: - -```bash -alias dep='vendor/bin/dep' -``` - -It is also recommended to install the completion script for Deployer. Completion supports: - -- tasks, -- options, -- host names, -- and configs. - -For example, on macOS run the following commands: - -```bash -brew install bash-completion -dep completion bash > /usr/local/etc/bash_completion.d/deployer -``` - -## Overriding configuration options - -For example, if your _deploy.php_ file contains this configuration: - -```php -set('ssh_multiplexing', false); -``` - -And you want to enable [ssh multiplexing](https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing) without modifying the recipe, you can pass the `-o` option to the `dep` command: - -``` -dep deploy -o ssh_multiplexing=true -``` - -To override multiple config options, you can pass multiple `-o` args: - -``` -dep deploy -o ssh_multiplexing=true -o branch=master -``` - -## Running arbitrary commands - -Run any command on one or more hosts: - -``` -dep run 'uptime -p' -``` - -## Tree command - -Deployer supports [task grouping](tasks.md#task-grouping) and [before/after hooks](tasks.md#addbefore). -To visualize the task hierarchy, use the **dep tree** command. - -``` -$ dep tree deploy -The task-tree for deploy: -└── deploy - ├── deploy:prepare - │ ├── deploy:info - │ ├── deploy:setup - │ ├── deploy:lock - │ ├── deploy:release - │ ├── deploy:update_code - │ ├── build // after deploy:update_code - │ ├── deploy:shared - │ └── deploy:writable - ├── deploy:vendors - ├── artisan:storage:link - ├── artisan:config:cache - ├── artisan:route:cache - ├── artisan:view:cache - ├── artisan:migrate - └── deploy:publish - ├── deploy:symlink - ├── deploy:unlock - ├── deploy:cleanup - └── deploy:success -``` - -## Execution plan - -Before executing tasks, Deployer needs to flatten the task tree and decide in which order it will be executing tasks -on which hosts. Use the `--plan` option to output a table with tasks/hosts: - -``` -$ dep deploy --plan all -┌──────────────────────┬──────────────────────┬──────────────────────┬──────────────────────┐ -│ prod01 │ prod02 │ prod03 │ prod04 │ -├──────────────────────┼──────────────────────┼──────────────────────┼──────────────────────┤ -│ deploy:info │ deploy:info │ deploy:info │ deploy:info │ -│ deploy:setup │ deploy:setup │ deploy:setup │ deploy:setup │ -│ deploy:lock │ deploy:lock │ deploy:lock │ deploy:lock │ -│ deploy:release │ deploy:release │ deploy:release │ deploy:release │ -│ deploy:update_code │ deploy:update_code │ deploy:update_code │ deploy:update_code │ -│ build │ build │ build │ build │ -│ deploy:shared │ deploy:shared │ deploy:shared │ deploy:shared │ -│ deploy:writable │ deploy:writable │ deploy:writable │ deploy:writable │ -│ deploy:vendors │ deploy:vendors │ deploy:vendors │ deploy:vendors │ -│ artisan:storage:link │ artisan:storage:link │ artisan:storage:link │ artisan:storage:link │ -│ artisan:config:cache │ artisan:config:cache │ artisan:config:cache │ artisan:config:cache │ -│ artisan:route:cache │ artisan:route:cache │ artisan:route:cache │ artisan:route:cache │ -│ artisan:view:cache │ artisan:view:cache │ artisan:view:cache │ artisan:view:cache │ -│ artisan:migrate │ artisan:migrate │ artisan:migrate │ artisan:migrate │ -│ deploy:symlink │ - │ - │ - │ -│ - │ deploy:symlink │ - │ - │ -│ - │ - │ deploy:symlink │ - │ -│ - │ - │ - │ deploy:symlink │ -│ deploy:unlock │ deploy:unlock │ deploy:unlock │ deploy:unlock │ -│ deploy:cleanup │ deploy:cleanup │ deploy:cleanup │ deploy:cleanup │ -│ deploy:success │ deploy:success │ deploy:success │ deploy:success │ -└──────────────────────┴──────────────────────┴──────────────────────┴──────────────────────┘ -``` - -The **deploy.php**: - -```php -host('prod[01:04]'); -task('deploy:symlink')->limit(1); -``` - -## The `runLocally` working dir - -By default, `runLocally()` commands are executed relative to the recipe file directory. -This can be overridden globally by setting an environment variable: - -``` -DEPLOYER_ROOT=. dep taskname` -``` - -Alternatively, the root directory can be overridden per command via the cwd configuration. - -```php -runLocally('ls', ['cwd' => '/root/directory']); -``` - -## Play blackjack - -> Yeah, well. I'm gonna go build my own theme park... with blackjack and hookers! -> -> In fact, forget the park! -> -> — Bender - -``` -dep blackjack -``` diff --git a/docs/contrib/README.md b/docs/contrib/README.md deleted file mode 100644 index c75174196..000000000 --- a/docs/contrib/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# All Contrib Recipes - -* [Bugsnag Recipe](/docs/contrib/bugsnag.md) -* [Cachetool Recipe](/docs/contrib/cachetool.md) -* [Chatwork Recipe](/docs/contrib/chatwork.md) -* [Cimonitor Recipe](/docs/contrib/cimonitor.md) -* [Cloudflare Recipe](/docs/contrib/cloudflare.md) -* [Cpanel Recipe](/docs/contrib/cpanel.md) -* [Crontab Recipe](/docs/contrib/crontab.md) -* [Directadmin Recipe](/docs/contrib/directadmin.md) -* [Discord Recipe](/docs/contrib/discord.md) -* [Grafana Recipe](/docs/contrib/grafana.md) -* [Hangouts Recipe](/docs/contrib/hangouts.md) -* [Hipchat Recipe](/docs/contrib/hipchat.md) -* [Ispmanager Recipe](/docs/contrib/ispmanager.md) -* [Mattermost Recipe](/docs/contrib/mattermost.md) -* [Ms-teams Recipe](/docs/contrib/ms-teams.md) -* [Newrelic Recipe](/docs/contrib/newrelic.md) -* [Npm Recipe](/docs/contrib/npm.md) -* [Ntfy Recipe](/docs/contrib/ntfy.md) -* [Phinx Recipe](/docs/contrib/phinx.md) -* [Php-fpm Recipe](/docs/contrib/php-fpm.md) -* [Rabbit Recipe](/docs/contrib/rabbit.md) -* [Raygun Recipe](/docs/contrib/raygun.md) -* [Rocketchat Recipe](/docs/contrib/rocketchat.md) -* [Rollbar Recipe](/docs/contrib/rollbar.md) -* [Rsync Recipe](/docs/contrib/rsync.md) -* [Sentry Recipe](/docs/contrib/sentry.md) -* [Slack Recipe](/docs/contrib/slack.md) -* [Supervisord-monitor Recipe](/docs/contrib/supervisord-monitor.md) -* [Telegram Recipe](/docs/contrib/telegram.md) -* [Webpack_encore Recipe](/docs/contrib/webpack_encore.md) -* [Workplace Recipe](/docs/contrib/workplace.md) -* [Yammer Recipe](/docs/contrib/yammer.md) -* [Yarn Recipe](/docs/contrib/yarn.md) \ No newline at end of file diff --git a/docs/contrib/bugsnag.md b/docs/contrib/bugsnag.md deleted file mode 100644 index 901dad95c..000000000 --- a/docs/contrib/bugsnag.md +++ /dev/null @@ -1,36 +0,0 @@ - - - - -# Bugsnag Recipe - -```php -require 'contrib/bugsnag.php'; -``` - -[Source](/contrib/bugsnag.php) - - - -## Configuration -- *bugsnag_api_key* – the API Key associated with the project. Informs Bugsnag which project has been deployed. This is the only required field. -- *bugsnag_provider* – the name of your source control provider. Required when repository is supplied and only for on-premise services. -- *bugsnag_app_version* – the app version of the code you are currently deploying. Only set this if you tag your releases with semantic version numbers and deploy infrequently. (Optional.) -## Usage -Since you should only notify Bugsnag of a successful deployment, the `bugsnag:notify` task should be executed right at the end. -```php -after('deploy', 'bugsnag:notify'); -``` - - - -## Tasks - -### bugsnag:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/bugsnag.php#L24) - -Notifies Bugsnag of deployment. - - - - diff --git a/docs/contrib/cachetool.md b/docs/contrib/cachetool.md deleted file mode 100644 index e87461699..000000000 --- a/docs/contrib/cachetool.md +++ /dev/null @@ -1,159 +0,0 @@ - - - - -# Cachetool Recipe - -```php -require 'contrib/cachetool.php'; -``` - -[Source](/contrib/cachetool.php) - - - -## Configuration -- **cachetool** *(optional)*: accepts a *string* or an *array* of strings with the unix socket or ip address to php-fpm. If `cachetool` is not given, then the application will look for a configuration file. The file must be named .cachetool.yml or .cachetool.yaml. CacheTool will look for this file on the current directory and in any parent directory until it finds one. If the paths above fail it will try to load /etc/cachetool.yml or /etc/cachetool.yaml configuration file. - ```php - set('cachetool', '/var/run/php-fpm.sock'); - // or - set('cachetool', '127.0.0.1:9000'); - // or - set('cachetool', ['/var/run/php-fpm.sock', '/var/run/php-fpm-other.sock']); - ``` -You can also specify different cachetool settings for each host: -```php -host('staging') - ->set('cachetool', '127.0.0.1:9000'); -host('production') - ->set('cachetool', '/var/run/php-fpm.sock'); -``` -By default, if no `cachetool` parameter is provided, this recipe will fallback to the global setting. -If your deployment user does not have permission to access the php-fpm.sock, you can alternatively use -the web adapter that creates a temporary php file and makes a web request to it with a configuration like -```php -set('cachetool_args', '--web --web-path=./public --web-url=https://{{hostname}}'); -``` -## Usage -Since APCu and OPcache deal with compiling and caching files, they should be executed right after the symlink is created for the new release: -```php -after('deploy:symlink', 'cachetool:clear:opcache'); -or -after('deploy:symlink', 'cachetool:clear:apcu'); -``` -## Read more -Read more information about cachetool on the website: -http://gordalina.github.io/cachetool/ - - -## Configuration -### cachetool -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L51) - -## Configuration -- **cachetool** *(optional)*: accepts a *string* or an *array* of strings with the unix socket or ip address to php-fpm. If `cachetool` is not given, then the application will look for a configuration file. The file must be named .cachetool.yml or .cachetool.yaml. CacheTool will look for this file on the current directory and in any parent directory until it finds one. If the paths above fail it will try to load /etc/cachetool.yml or /etc/cachetool.yaml configuration file. - ```php - set('cachetool', '/var/run/php-fpm.sock'); - // or - set('cachetool', '127.0.0.1:9000'); - // or - set('cachetool', ['/var/run/php-fpm.sock', '/var/run/php-fpm-other.sock']); - ``` -You can also specify different cachetool settings for each host: -```php -host('staging') - ->set('cachetool', '127.0.0.1:9000'); -host('production') - ->set('cachetool', '/var/run/php-fpm.sock'); -``` -By default, if no `cachetool` parameter is provided, this recipe will fallback to the global setting. -If your deployment user does not have permission to access the php-fpm.sock, you can alternatively use -the web adapter that creates a temporary php file and makes a web request to it with a configuration like -```php -set('cachetool_args', '--web --web-path=./public --web-url=https://{{hostname}}'); -``` -## Usage -Since APCu and OPcache deal with compiling and caching files, they should be executed right after the symlink is created for the new release: -```php -after('deploy:symlink', 'cachetool:clear:opcache'); -or -after('deploy:symlink', 'cachetool:clear:apcu'); -``` -## Read more -Read more information about cachetool on the website: -http://gordalina.github.io/cachetool/ - - - -### cachetool_url -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L59) - -URL to download cachetool from if it is not available - -CacheTool 9.x works with PHP >=8.1 -CacheTool 8.x works with PHP >=8.0 -CacheTool 7.x works with PHP >=7.3 - -```php title="Default value" -'https://github.com/gordalina/cachetool/releases/download/9.0.0/cachetool.phar' -``` - - -### cachetool_args -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L60) - - - - - -### bin/cachetool -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L61) - - - -```php title="Default value" -if (!test('[ -f {{release_or_current_path}}/cachetool.phar ]')) { -run("cd {{release_or_current_path}} && curl -sLO {{cachetool_url}}"); -} -return '{{release_or_current_path}}/cachetool.phar'; -``` - - -### cachetool_options -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L67) - - -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - - -## Tasks - -### cachetool:clear:opcache -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L89) - -Clears OPcode cache. - -Clear opcache cache - - -### cachetool:clear:apcu -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L100) - -Clears APCu system cache. - -Clear APCu cache - - -### cachetool:clear:stat -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cachetool.php#L111) - -Clears file status and realpath caches. - -Clear file status cache, including the realpath cache - - diff --git a/docs/contrib/chatwork.md b/docs/contrib/chatwork.md deleted file mode 100644 index 8bcefed84..000000000 --- a/docs/contrib/chatwork.md +++ /dev/null @@ -1,190 +0,0 @@ - - - - -# Chatwork Recipe - -```php -require 'contrib/chatwork.php'; -``` - -[Source](/contrib/chatwork.php) - - - -# Chatwork Recipe -## Installing - 1. Create chatwork account by any manual in the internet - 2. Take chatwork token (Like: b29a700e2d15bef3f26ae6a5c142d1ea) and set `chatwork_token` parameter - 3. Take chatwork room id from url after clicked on the room, and set `chatwork_room_id` parameter - 4. If you want, you can edit `chatwork_notify_text`, `chatwork_success_text` or `chatwork_failure_text` - 5. Require chatwork recipe in your `deploy.php` file -```php -# https://deployer.org/recipes.html -require 'recipe/chatwork.php'; -``` -Add hook on deploy: -```php -before('deploy', 'chatwork:notify'); -``` -## Configuration -- `chatwork_token` – chatwork bot token, **required** -- `chatwork_room_id` — chatwork room to push messages to **required** -- `chatwork_notify_text` – notification message template - ``` - [info] - [title](*) Deployment Status: Deploying[/title] - Repo: {{repository}} - Branch: {{branch}} - Server: {{hostname}} - Release Path: {{release_path}} - Current Path: {{current_path}} - [/info] - ``` -- `chatwork_success_text` – success template, default: - ``` - [info] - [title](*) Deployment Status: Successfully[/title] - Repo: {{repository}} - Branch: {{branch}} - Server: {{hostname}} - Release Path: {{release_path}} - Current Path: {{current_path}} - [/info]" - ``` -- `chatwork_failure_text` – failure template, default: - ``` - [info] - [title](*) Deployment Status: Failed[/title] - Repo: {{repository}} - Branch: {{branch}} - Server: {{hostname}} - Release Path: {{release_path}} - Current Path: {{current_path}} - [/info]" - ``` -## Tasks -- `chatwork:notify` – send message to chatwork -- `chatwork:notify:success` – send success message to chatwork -- `chatwork:notify:failure` – send failure message to chatwork -## Usage -If you want to notify only about beginning of deployment add this line only: -```php -before('deploy', 'chatwork:notify'); -``` -If you want to notify about successful end of deployment add this too: -```php -after('success', 'chatwork:notify:success'); -``` -If you want to notify about failed deployment add this too: -```php -after('deploy:failed', 'chatwork:notify:failure'); -``` - - -## Configuration -### chatwork_token -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L93) - -Chatwork settings -:::info Required -Throws exception if not set. -::: - - - - -### chatwork_room_id -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L96) - - -:::info Required -Throws exception if not set. -::: - - - - -### chatwork_api -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L99) - - - -```php title="Default value" -return 'https://api.chatwork.com/v2/rooms/' . get('chatwork_room_id') . '/messages'; -``` - - -### chatwork_notify_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L104) - -The Messages - -```php title="Default value" -"[info]\n[title](*) Deployment Status: Deploying[/title]\nRepo: {{repository}}\nBranch: {{branch}}\nServer: {{hostname}}\nRelease Path: {{release_path}}\nCurrent Path: {{current_path}}\n[/info]" -``` - - -### chatwork_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L105) - - - -```php title="Default value" -"[info]\n[title](*) Deployment Status: Successfully[/title]\nRepo: {{repository}}\nBranch: {{branch}}\nServer: {{hostname}}\nRelease Path: {{release_path}}\nCurrent Path: {{current_path}}\n[/info]" -``` - - -### chatwork_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L106) - - - -```php title="Default value" -"[info]\n[title](*) Deployment Status: Failed[/title]\nRepo: {{repository}}\nBranch: {{branch}}\nServer: {{hostname}}\nRelease Path: {{release_path}}\nCurrent Path: {{current_path}}\n[/info]" -``` - - - -## Tasks - -### chatwork_send_message -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L109) - - - -Helpers - - -### chatwork:test -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L118) - -Tests messages. - -Tasks - - -### chatwork:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L129) - -Notifies Chatwork. - - - - -### chatwork:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L144) - -Notifies Chatwork about deploy finish. - - - - -### chatwork:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/chatwork.php#L160) - -Notifies Chatwork about deploy failure. - - - - diff --git a/docs/contrib/cimonitor.md b/docs/contrib/cimonitor.md deleted file mode 100644 index cfaf3eb0f..000000000 --- a/docs/contrib/cimonitor.md +++ /dev/null @@ -1,209 +0,0 @@ - - - - -# Cimonitor Recipe - -```php -require 'contrib/cimonitor.php'; -``` - -[Source](/contrib/cimonitor.php) - - - -Monitor your deployments on [CIMonitor](https://github.com/CIMonitor/CIMonitor). -![CIMonitorGif](https://www.steefmin.xyz/deployer-example.gif) -Add tasks on deploy: -```php -before('deploy', 'cimonitor:notify'); -after('deploy:success', 'cimonitor:notify:success'); -after('deploy:failed', 'cimonitor:notify:failure'); -``` -## Configuration -- `cimonitor_webhook` – CIMonitor server webhook url, **required** - ``` - set('cimonitor_webhook', 'https://cimonitor.enrise.com/webhook/deployer'); - ``` -- `cimonitor_title` – the title of application, default the username\reponame combination from `{{repository}}` - ``` - set('cimonitor_title', ''); - ``` -- `cimonitor_user` – User object with name and email, default gets information from `git config` - ``` - set('cimonitor_user', function () { - return [ - 'name' => 'John Doe', - 'email' => 'john@enrise.com', - ]; - }); - ``` -Various cimonitor statusses are set, in case you want to change these yourselves. See the [CIMonitor documentation](https://cimonitor.readthedocs.io/en/latest/) for the usages of different states. -## Usage -If you want to notify only about beginning of deployment add this line only: -```php -before('deploy', 'cimonitor:notify'); -``` -If you want to notify about successful end of deployment add this too: -```php -after('deploy:success', 'cimonitor:notify:success'); -``` -If you want to notify about failed deployment add this too: -```php -after('deploy:failed', 'cimonitor:notify:failure'); -``` - - -## Configuration -### cimonitor_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L64) - -Title of project based on git repo - -```php title="Default value" -$repo = get('repository'); -$pattern = '/\w+\/\w+/'; -return preg_match($pattern, $repo, $titles) ? $titles[0] : $repo; -``` - - -### cimonitor_user -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L69) - - - -```php title="Default value" -return [ -'name' => runLocally('git config --get user.name'), -'email' => runLocally('git config --get user.email'), -]; -``` - - -### cimonitor_status_info -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L77) - -CI monitor status states and job states - -```php title="Default value" -'info' -``` - - -### cimonitor_status_warning -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L78) - - - -```php title="Default value" -'warning' -``` - - -### cimonitor_status_error -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L79) - - - -```php title="Default value" -'error' -``` - - -### cimonitor_status_success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L80) - - - -```php title="Default value" -'success' -``` - - -### cimonitor_job_state_info -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L81) - - - -```php title="Default value" -get('cimonitor_status_info') -``` - - -### cimonitor_job_state_pending -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L82) - - - -```php title="Default value" -'pending' -``` - - -### cimonitor_job_state_running -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L83) - - - -```php title="Default value" -'running' -``` - - -### cimonitor_job_state_warning -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L84) - - - -```php title="Default value" -get('cimonitor_status_warning') -``` - - -### cimonitor_job_state_error -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L85) - - - -```php title="Default value" -get('cimonitor_status_error') -``` - - -### cimonitor_job_state_success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L86) - - - -```php title="Default value" -get('cimonitor_status_success') -``` - - - -## Tasks - -### cimonitor:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L89) - -Notifies CIMonitor. - - - - -### cimonitor:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L115) - -Notifies CIMonitor about deploy finish. - - - - -### cimonitor:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cimonitor.php#L143) - -Notifies CIMonitor about deploy failure. - - - - diff --git a/docs/contrib/cloudflare.md b/docs/contrib/cloudflare.md deleted file mode 100644 index e9b2b1404..000000000 --- a/docs/contrib/cloudflare.md +++ /dev/null @@ -1,48 +0,0 @@ - - - - -# Cloudflare Recipe - -```php -require 'contrib/cloudflare.php'; -``` - -[Source](/contrib/cloudflare.php) - - - -### Configuration -- `cloudflare` – array with configuration for cloudflare - - `service_key` – Cloudflare Service Key. If this is not provided, use api_key and email. - - `api_key` – Cloudflare API key generated on the "My Account" page. - - `email` – Cloudflare Email address associated with your account. - - `api_token` – Cloudflare API Token generated on the "My Account" page. - - `domain` – The domain you want to clear (optional if zone_id is provided). - - `zone_id` – Cloudflare Zone ID (optional). -### Usage -Since the website should be built and some load is likely about to be applied to your server, this should be one of, -if not the, last tasks before cleanup - - - -## Tasks - -### deploy:cloudflare -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cloudflare.php#L24) - -Clears Cloudflare Cache. - -### Configuration -- `cloudflare` – array with configuration for cloudflare - - `service_key` – Cloudflare Service Key. If this is not provided, use api_key and email. - - `api_key` – Cloudflare API key generated on the "My Account" page. - - `email` – Cloudflare Email address associated with your account. - - `api_token` – Cloudflare API Token generated on the "My Account" page. - - `domain` – The domain you want to clear (optional if zone_id is provided). - - `zone_id` – Cloudflare Zone ID (optional). -### Usage -Since the website should be built and some load is likely about to be applied to your server, this should be one of, -if not the, last tasks before cleanup - - diff --git a/docs/contrib/cpanel.md b/docs/contrib/cpanel.md deleted file mode 100644 index 8a59d7318..000000000 --- a/docs/contrib/cpanel.md +++ /dev/null @@ -1,141 +0,0 @@ - - - - -# Cpanel Recipe - -```php -require 'contrib/cpanel.php'; -``` - -[Source](/contrib/cpanel.php) - - - -### Description -This is a recipe that uses the [cPanel 2 API](https://documentation.cPanel.net/display/DD/Guide+to+cPanel+API+2). -Unfortunately the [UAPI](https://documentation.cPanel.net/display/DD/Guide+to+UAPI) that is recommended does not have support for creating addon domains. -The main idea behind is for staging purposes but I guess you can use it for other interesting concepts. -The idea is, every branch possibly has its own staging domain/subdomain (staging-neat-feature.project.com) and database db_neat-feature_project so it can be tested. -This recipe can make the domain/subdomain and database creation part of the deployment process so you don't have to manually create them through an interface. -### Configuration -The example uses a .env file and Dotenv for configuration, but you can set the parameters as you wish -``` -set('cpanel', [ - 'host' => getenv('CPANEL_HOST'), - 'port' => getenv('CPANEL_PORT'), - 'username' => getenv('CPANEL_USERNAME'), - 'auth_type' => getenv('CPANEL_AUTH_TYPE'), - 'token' => getenv('CPANEL_TOKEN'), - 'user' => getenv('CPANEL_USER'), - 'db_user' => getenv('CPANEL_DB_USER'), - 'db_user_privileges' => getenv('CPANEL_DB_PRIVILEGES'), - 'timeout' => 500, - 'allowInStage' => ['staging', 'beta', 'alpha'], - 'create_domain_format' => '%s-%s-%s', - 'create_domain_values' => ['staging', 'master', get('application')], - 'subdomain_prefix' => substr(md5(get('application')), 0,4) . '-', - 'subdomain_suffix' => getenv('SUDOMAIN_SUFFIX'), - 'create_db_format' => '%s_%s-%s-%s', - 'create_db_values' => ['apps', 'staging','master', get('application')], -]); -``` -- `cpanel` – array with configuration for cPanel - - `username` – WHM account - - `user` – cPanel account that you want in charge of the domain - - `token` – WHM API token - - `create_domain_format` – Format for name creation of domain - - `create_domain_values` – The actual value reference for naming - - `subdomain_prefix` – cPanel has a weird way of dealing with addons and subdomains, you cannot create 2 addons with the same subdomain, so you need to change it in some way, example uses first 4 chars of md5(app_name) - - `subdomain_suffix` – cPanel has a weird way of dealing with addons and subdomains, so the suffix needs to be your main domain for that account for deletion purposes - - `addondir` – addon dir is different from the deploy path because cPanel "injects" /home/user/ into the path, so tilde cannot be used - - `allowInStage` – Define the stages that cPanel recipe actions are allowed in -#### .env file example -``` -CPANEL_HOST=xxx.xxx.xxx.xxx -CPANEL_PORT=2087 -CPANEL_USERNAME=root -CPANEL_TOKEN=xxxx -CPANEL_USER=xxx -CPANEL_AUTH_TYPE=hash -CPANEL_DB_USER=db_user -CPANEL_DB_PRIVILEGES="ALL PRIVILEGES" -SUDOMAIN_SUFFIX=.mymaindomain.com -``` -### Tasks -- `cpanel:createaddondomain` Creates an addon domain -- `cpanel:deleteaddondomain` Removes an addon domain -- `cpanel:createdb` Creates a new database -### Usage -A complete example with configs, staging and deployment -``` -load(); // this is used just so an .env file can be used for credentials -require 'cpanel.php'; -Project name -set('application', 'myproject.com'); -Project repository -set('repository', 'git@github.com:myorg/myproject.com'); -set('cpanel', [ - 'host' => getenv('CPANEL_HOST'), - 'port' => getenv('CPANEL_PORT'), - 'username' => getenv('CPANEL_USERNAME'), - 'auth_type' => getenv('CPANEL_AUTH_TYPE'), - 'token' => getenv('CPANEL_TOKEN'), - 'user' => getenv('CPANEL_USER'), - 'db_user' => getenv('CPANEL_DB_USER'), - 'db_user_privileges' => getenv('CPANEL_DB_PRIVILEGES'), - 'timeout' => 500, - 'allowInStage' => ['staging', 'beta', 'alpha'], - 'create_domain_format' => '%s-%s-%s', - 'create_domain_values' => ['staging', 'master', get('application')], - 'subdomain_prefix' => substr(md5(get('application')), 0,4) . '-', - 'subdomain_suffix' => getenv('SUDOMAIN_SUFFIX'), - 'create_db_format' => '%s_%s-%s-%s', - 'create_db_values' => ['apps', 'staging','master', get('application')], -]); -host('myproject.com') - ->stage('staging') - ->set('cpanel_createdb', vsprintf(get('cpanel')['create_db_format'], get('cpanel')['create_db_values'])) - ->set('branch', 'dev-branch') - ->set('deploy_path', '~/staging/' . vsprintf(get('cpanel')['create_domain_format'], get('cpanel')['create_domain_values'])) - ->set('addondir', 'staging/' . vsprintf(get('cpanel')['create_domain_format'], get('cpanel')['create_domain_values'])); -Tasks -task('build', function () { - run('cd {{release_path}} && build'); -}); -after('deploy:prepare', 'cpanel:createaddondomain'); -after('deploy:prepare', 'cpanel:createdb'); -``` - - - -## Tasks - -### cpanel:createdb -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cpanel.php#L196) - -Creates database though CPanel API. - - - - -### cpanel:createaddondomain -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cpanel.php#L224) - -Creates addon domain though CPanel API. - - - - -### cpanel:deleteaddondomain -[Source](https://github.com/deployphp/deployer/blob/master/contrib/cpanel.php#L247) - -Deletes addon domain though CPanel API. - - - - diff --git a/docs/contrib/crontab.md b/docs/contrib/crontab.md deleted file mode 100644 index f7395cf88..000000000 --- a/docs/contrib/crontab.md +++ /dev/null @@ -1,84 +0,0 @@ - - - - -# Crontab Recipe - -```php -require 'contrib/crontab.php'; -``` - -[Source](/contrib/crontab.php) - - - -Recipe for adding crontab jobs. -This recipe creates a new section in the crontab file with the configured jobs. -The section is identified by the *crontab:identifier* variable, by default the application name. -## Configuration -- *crontab:jobs* - An array of strings with crontab lines. -## Usage -```php -require 'contrib/crontab.php'; -after('deploy:success', 'crontab:sync'); -add('crontab:jobs', [ - '* * * * * cd {{current_path}} && {{bin/php}} artisan schedule:run >> /dev/null 2>&1', -]); -``` - - -## Configuration -### bin/crontab -[Source](https://github.com/deployphp/deployer/blob/master/contrib/crontab.php#L28) - -Recipe for adding crontab jobs. -This recipe creates a new section in the crontab file with the configured jobs. -The section is identified by the *crontab:identifier* variable, by default the application name. -## Configuration -- *crontab:jobs* - An array of strings with crontab lines. -## Usage -```php -require 'contrib/crontab.php'; -after('deploy:success', 'crontab:sync'); -add('crontab:jobs', [ - '* * * * * cd {{current_path}} && {{bin/php}} artisan schedule:run >> /dev/null 2>&1', -]); -``` -Get path to bin - -```php title="Default value" -return which('crontab'); -``` - - -### crontab:identifier -[Source](https://github.com/deployphp/deployer/blob/master/contrib/crontab.php#L33) - -Set the identifier used in the crontab, application name by default - -```php title="Default value" -return get('application', 'application'); -``` - - -### crontab:use_sudo -[Source](https://github.com/deployphp/deployer/blob/master/contrib/crontab.php#L38) - -Use sudo to run crontab. When running crontab with sudo, you can use the `-u` parameter to change a crontab for a different user. - -```php title="Default value" -false -``` - - - -## Tasks - -### crontab:sync -[Source](https://github.com/deployphp/deployer/blob/master/contrib/crontab.php#L41) - -Sync crontab jobs. - - - - diff --git a/docs/contrib/directadmin.md b/docs/contrib/directadmin.md deleted file mode 100644 index 21089cf24..000000000 --- a/docs/contrib/directadmin.md +++ /dev/null @@ -1,82 +0,0 @@ - - - - -# Directadmin Recipe - -```php -require 'contrib/directadmin.php'; -``` - -[Source](/contrib/directadmin.php) - - - -### Configuration -- `directadmin` – array with configuration for DirectAdmin - - `host` – DirectAdmin host - - `port` – DirectAdmin port (default: 2222, not required) - - `scheme` – DirectAdmin scheme (default: http, not required) - - `username` – DirectAdmin username - - `password` – DirectAdmin password (it is recommended to use login keys!) - - `db_user` – Database username (required when using directadmin:createdb or directadmin:deletedb) - - `db_name` – Database namse (required when using directadmin:createdb) - - `db_password` – Database password (required when using directadmin:createdb) - - `domain_name` – Domain to create, delete or edit (required when using directadmin:createdomain, directadmin:deletedomain, directadmin:symlink-private-html or directadmin:php-version) - - `domain_ssl` – Enable SSL, options: ON/OFF, default: ON (optional when using directadmin:createdb) - - `domain_cgi` – Enable CGI, options: ON/OFF, default: ON (optional when using directadmin:createdb) - - `domain_php` – Enable PHP, options: ON/OFF, default: ON (optional when using directadmin:createdb) - - `domain_php_version` – Domain PHP Version, default: 1 (required when using directadmin:php-version) - - - -## Tasks - -### directadmin:createdb -[Source](https://github.com/deployphp/deployer/blob/master/contrib/directadmin.php#L76) - -Creates a database on DirectAdmin. - - - - -### directadmin:deletedb -[Source](https://github.com/deployphp/deployer/blob/master/contrib/directadmin.php#L96) - -Deletes a database on DirectAdmin. - - - - -### directadmin:createdomain -[Source](https://github.com/deployphp/deployer/blob/master/contrib/directadmin.php#L111) - -Creates a domain on DirectAdmin. - - - - -### directadmin:deletedomain -[Source](https://github.com/deployphp/deployer/blob/master/contrib/directadmin.php#L129) - -Deletes a domain on DirectAdmin. - - - - -### directadmin:symlink-private-html -[Source](https://github.com/deployphp/deployer/blob/master/contrib/directadmin.php#L145) - -Symlink your private_html to public_html. - - - - -### directadmin:php-version -[Source](https://github.com/deployphp/deployer/blob/master/contrib/directadmin.php#L161) - -Changes the PHP version from a domain. - - - - diff --git a/docs/contrib/discord.md b/docs/contrib/discord.md deleted file mode 100644 index 197c5da37..000000000 --- a/docs/contrib/discord.md +++ /dev/null @@ -1,148 +0,0 @@ - - - - -# Discord Recipe - -```php -require 'contrib/discord.php'; -``` - -[Source](/contrib/discord.php) - - - -## Installing -Add hook on deploy: -```php -before('deploy', 'discord:notify'); -``` -## Configuration -- `discord_channel` – Discord channel ID, **required** -- `discord_token` – Discord channel token, **required** -- `discord_notify_text` – notification message template, markdown supported, default: - ```markdown - :​information_source: **{{user}}** is deploying branch `{{branch}}` to _{{where}}_ - ``` -- `discord_success_text` – success template, default: - ```markdown - :​white_check_mark: Branch `{{branch}}` deployed to _{{where}}_ successfully - ``` -- `discord_failure_text` – failure template, default: - ```markdown - :​no_entry_sign: Branch `{{branch}}` has failed to deploy to _{{where}}_ -## Usage -If you want to notify only about beginning of deployment add this line only: -```php -before('deploy', 'discord:notify'); -``` -If you want to notify about successful end of deployment add this too: -```php -after('deploy:success', 'discord:notify:success'); -``` -If you want to notify about failed deployment add this too: -```php -after('deploy:failed', 'discord:notify:failure'); -``` - - -## Configuration -### discord_webhook -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L54) - - - -```php title="Default value" -return 'https://discordapp.com/api/webhooks/{{discord_channel}}/{{discord_token}}/slack'; -``` - - -### discord_notify_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L59) - -Deploy messages - -```php title="Default value" -return [ -'text' => parse(':​information_source: **{{user}}** is deploying branch `{{what}}` to _{{where}}_'), -]; -``` - - -### discord_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L64) - - - -```php title="Default value" -return [ -'text' => parse(':​white_check_mark: Branch `{{what}}` deployed to _{{where}}_ successfully'), -]; -``` - - -### discord_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L69) - - - -```php title="Default value" -return [ -'text' => parse(':​no_entry_sign: Branch `{{what}}` has failed to deploy to _{{where}}_'), -]; -``` - - -### discord_message -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L76) - -The message - -```php title="Default value" -'discord_notify_text' -``` - - - -## Tasks - -### discord_send_message -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L79) - - - -Helpers - - -### discord:test -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L87) - -Tests messages. - -Tasks - - -### discord:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L98) - -Notifies Discord. - - - - -### discord:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L106) - -Notifies Discord about deploy finish. - - - - -### discord:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/discord.php#L114) - -Notifies Discord about deploy failure. - - - - diff --git a/docs/contrib/grafana.md b/docs/contrib/grafana.md deleted file mode 100644 index d79b6147c..000000000 --- a/docs/contrib/grafana.md +++ /dev/null @@ -1,46 +0,0 @@ - - - - -# Grafana Recipe - -```php -require 'contrib/grafana.php'; -``` - -[Source](/contrib/grafana.php) - - - -## Configuration options -- **url** *(required)*: the URL to the creates annotation api endpoint. -- **token** *(required)*: authentication token. Can be created at Grafana Console. -- **time** *(optional)* – set deploy time of annotation. specify epoch milliseconds. (Defaults is set to the current time in epoch milliseconds.) -- **tags** *(optional)* – set tag of annotation. -- **text** *(optional)* – set text of annotation. (Defaults is set to "Deployed " + git log -n 1 --format="%h") -```php -deploy.php -set('grafana', [ - 'token' => 'eyJrIj...', - 'url' => 'http://grafana/api/annotations', - 'tags' => ['deploy', 'production'], -]); -``` -## Usage -If you want to create annotation about successful end of deployment. -```php -after('deploy:success', 'grafana:annotation'); -``` - - - -## Tasks - -### grafana:annotation -[Source](https://github.com/deployphp/deployer/blob/master/contrib/grafana.php#L38) - -Creates Grafana annotation of deployment. - - - - diff --git a/docs/contrib/hangouts.md b/docs/contrib/hangouts.md deleted file mode 100644 index 64f0ee6ca..000000000 --- a/docs/contrib/hangouts.md +++ /dev/null @@ -1,118 +0,0 @@ - - - - -# Hangouts Recipe - -```php -require 'contrib/hangouts.php'; -``` - -[Source](/contrib/hangouts.php) - - - -Add hook on deploy: -```php -before('deploy', 'chat:notify'); -``` -## Configuration -- `chat_webhook` – chat incoming webhook url, **required** -- `chat_title` – the title of your notification card, default `{{application}}` -- `chat_subtitle` – the subtitle of your card, default `{{hostname}}` -- `chat_favicon` – an image for the header of your card, default `http://{{hostname}}/favicon.png` -- `chat_line1` – first line of the text in your card, default: `{{branch}}` -- `chat_line2` – second line of the text in your card, default: `{{stage}}` -## Usage -If you want to notify only about beginning of deployment add this line only: -```php -before('deploy', 'chat:notify'); -``` -If you want to notify about successful end of deployment add this too: -```php -after('deploy:success', 'chat:notify:success'); -``` -If you want to notify about failed deployment add this too: -```php -after('deploy:failed', 'chat:notify:failure'); -``` - - -## Configuration -### chat_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L46) - -Title of project - -```php title="Default value" -return get('application', 'Project'); -``` - - -### chat_subtitle -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L50) - - - -```php title="Default value" -get('hostname') -``` - - -### favicon -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L53) - -If 'favicon' is set Google Hangouts Chat will decorate your card with an image. - -```php title="Default value" -'http://{{hostname}}/favicon.png' -``` - - -### chat_line1 -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L56) - -Deploy messages - -```php title="Default value" -'{{branch}}' -``` - - -### chat_line2 -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L57) - - - -```php title="Default value" -'{{stage}}' -``` - - - -## Tasks - -### chat:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L60) - -Notifies Google Hangouts Chat. - - - - -### chat:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L102) - -Notifies Google Hangouts Chat about deploy finish. - - - - -### chat:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hangouts.php#L144) - -Notifies Google Hangouts Chat about deploy failure. - - - - diff --git a/docs/contrib/hipchat.md b/docs/contrib/hipchat.md deleted file mode 100644 index 1d7b88dba..000000000 --- a/docs/contrib/hipchat.md +++ /dev/null @@ -1,80 +0,0 @@ - - - - -# Hipchat Recipe - -```php -require 'contrib/hipchat.php'; -``` - -[Source](/contrib/hipchat.php) - - - -## Configuration -- `hipchat_token` – Hipchat V1 auth token -- `hipchat_room_id` – Room ID or name -- `hipchat_message` – Deploy message, default is `_{{user}}_ deploying `{{what}}` to *{{where}}*` -- `hipchat_from` – Default to target -- `hipchat_color` – Message color, default is **green** -- `hipchat_url` – The URL to the message endpoint, default is https://api.hipchat.com/v1/rooms/message -## Usage -Since you should only notify Hipchat room of a successful deployment, the `hipchat:notify` task should be executed right at the end. -```php -after('deploy', 'hipchat:notify'); -``` - - -## Configuration -### hipchat_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hipchat.php#L26) - - - -```php title="Default value" -'green' -``` - - -### hipchat_from -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hipchat.php#L27) - - - -```php title="Default value" -'{{where}}' -``` - - -### hipchat_message -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hipchat.php#L28) - - - -```php title="Default value" -'_{{user}}_ deploying `{{what}}` to *{{where}}*' -``` - - -### hipchat_url -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hipchat.php#L29) - - - -```php title="Default value" -'https://api.hipchat.com/v1/rooms/message' -``` - - - -## Tasks - -### hipchat:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/hipchat.php#L32) - -Notifies Hipchat channel of deployment. - - - - diff --git a/docs/contrib/ispmanager.md b/docs/contrib/ispmanager.md deleted file mode 100644 index 00cfe80df..000000000 --- a/docs/contrib/ispmanager.md +++ /dev/null @@ -1,245 +0,0 @@ - - - - -# Ispmanager Recipe - -```php -require 'contrib/ispmanager.php'; -``` - -[Source](/contrib/ispmanager.php) - - - -This recipe for work with ISPManager Lite panel by API. - - -## Configuration -### ispmanager_owner -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L11) - - - -```php title="Default value" -'www-root' -``` - - -### ispmanager_doc_root -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L12) - - - -```php title="Default value" -'/var/www/' . get('ispmanager_owner') . '/data/' -``` - - -### ispmanager -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L15) - -ISPManager default configuration - -```php title="Default value" -[ - 'api' => [ - 'dsn' => 'https://root:password@localhost:1500/ispmgr', - 'secure' => true, - ], - 'createDomain' => null, - 'updateDomain' => null, - 'deleteDomain' => null, - 'createDatabase' => null, - 'deleteDatabase' => null, - 'phpSelect' => null, - 'createAlias' => null, - 'deleteAlias' => null, -] -``` - - -### vhost -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L31) - -Vhost default configuration - -```php title="Default value" -[ - 'name' => '{{domain}}', - 'php_enable' => 'on', - 'aliases' => 'www.{{domain}}', - 'home' => 'www/{{domain}}', - 'owner' => get('ispmanager_owner'), - 'email' => 'webmaster@{{domain}}', - 'charset' => 'off', - 'dirindex' => 'index.php uploaded.html', - 'ssi' => 'on', - 'php' => 'on', - 'php_mode' => 'php_mode_mod', - 'basedir' => 'on', - 'php_apache_version' => 'native', - 'cgi' => 'off', - 'log_access' => 'on', - 'log_error' => 'on', -] -``` - - -### ispmanager_session -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L51) - -Storage - - - -### ispmanager_databases -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L52) - - - -```php title="Default value" -[ - 'servers' => [], - 'hosts' => [], - 'dblist' => [], -] -``` - - -### ispmanager_domains -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L58) - - - - - -### ispmanager_phplist -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L59) - - - - - -### ispmanager_aliaslist -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L60) - - - - - - -## Tasks - -### ispmanager:init -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L63) - -Installs ispmanager. - - - - -### ispmanager:db-server-list -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L86) - -Takes database servers list. - - - - -### ispmanager:db-list -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L123) - -Takes databases list. - - - - -### ispmanager:domain-list -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L145) - -Takes domain list. - - - - -### ispmanager:db-create -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L161) - -Creates new database. - - - - -### ispmanager:db-delete -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L231) - -Deletes database. - - - - -### ispmanager:domain-create -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L282) - -Creates new domain. - - - - -### ispmanager:get-php-list -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L328) - -Gets allowed PHP modes and versions. - - - - -### ispmanager:print-php-list -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L374) - -Prints allowed PHP modes and versions. - - - - -### ispmanager:domain-php-select -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L412) - -Switches PHP version for domain. - - - - -### ispmanager:domain-alias-create -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L481) - -Creates new domain alias. - - - - -### ispmanager:domain-alias-delete -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L550) - -Deletes domain alias. - - - - -### ispmanager:domain-delete -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L618) - -Deletes domain. - - - - -### ispmanager:process -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ispmanager.php#L665) - -Auto task processing. - - - - diff --git a/docs/contrib/mattermost.md b/docs/contrib/mattermost.md deleted file mode 100644 index 8e3cea31f..000000000 --- a/docs/contrib/mattermost.md +++ /dev/null @@ -1,185 +0,0 @@ - - - - -# Mattermost Recipe - -```php -require 'contrib/mattermost.php'; -``` - -[Source](/contrib/mattermost.php) - - - -## Installing -Create a Mattermost incoming webhook, through the administration panel. -Add hook on deploy: -``` -before('deploy', 'mattermost:notify'); -``` -## Configuration - - `mattermost_webhook` - incoming mattermost webook **required** - ``` - set('mattermost_webook', 'https://{your-mattermost-site}/hooks/xxx-generatedkey-xxx'); - ``` - - `mattermost_channel` - overrides the channel the message posts in - ``` - set('mattermost_channel', 'town-square'); - ``` - - `mattermost_username` - overrides the username the message posts as - ``` - set('mattermost_username', 'deployer'); - ``` - - `mattermost_icon_url` - overrides the profile picture the message posts with - ``` - set('mattermost_icon_url', 'https://domain.com/your-icon.png'); - ``` - - `mattermost_text` - notification message - ``` - set('mattermost_text', '_{{user}}_ deploying `{{what}}` to **{{where}}**'); - ``` - - `mattermost_success_text` – success template, default: - ``` - set('mattermost_success_text', 'Deploy to **{{where}}** successful {{mattermost_success_emoji}}'); - ``` - - `mattermost_failure_text` – failure template, default: - ``` - set('mattermost_failure_text', 'Deploy to **{{where}}** failed {{mattermost_failure_emoji}}'); - ``` - - `mattermost_success_emoji` – emoji added at the end of success text - - `mattermost_failure_emoji` – emoji added at the end of failure text - For detailed information about Mattermost hooks see: https://developers.mattermost.com/integrate/incoming-webhooks/ -## Usage -If you want to notify only about beginning of deployment add this line only: -```php -before('deploy', 'mattermost:notify'); -``` -If you want to notify about successful end of deployment add this too: -```php -after('deploy:success', 'mattermost:notify:success'); -``` -If you want to notify about failed deployment add this too: -```php -after('deploy:failed', 'mattermost:notify:failure'); -``` - - -## Configuration -### mattermost_webhook -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L81) - - - -```php title="Default value" -null -``` - - -### mattermost_channel -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L82) - - - -```php title="Default value" -null -``` - - -### mattermost_username -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L83) - - - -```php title="Default value" -'deployer' -``` - - -### mattermost_icon_url -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L84) - - - -```php title="Default value" -null -``` - - -### mattermost_success_emoji -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L86) - - - -```php title="Default value" -':​white_check_mark:' -``` - - -### mattermost_failure_emoji -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L87) - - - -```php title="Default value" -':​x:' -``` - - -### mattermost_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L89) - - - -```php title="Default value" -'_{{user}}_ deploying `{{what}}` to **{{where}}**' -``` - - -### mattermost_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L90) - - - -```php title="Default value" -'Deploy to **{{where}}** successful {{mattermost_success_emoji}}' -``` - - -### mattermost_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L91) - - - -```php title="Default value" -'Deploy to **{{where}}** failed {{mattermost_failure_emoji}}' -``` - - - -## Tasks - -### mattermost:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L94) - -Notifies mattermost. - - - - -### mattermost:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L115) - -Notifies mattermost about deploy finish. - - - - -### mattermost:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/mattermost.php#L136) - -Notifies mattermost about deploy failure. - - - - diff --git a/docs/contrib/ms-teams.md b/docs/contrib/ms-teams.md deleted file mode 100644 index 79fba0277..000000000 --- a/docs/contrib/ms-teams.md +++ /dev/null @@ -1,171 +0,0 @@ - - - - -# Ms-teams Recipe - -```php -require 'contrib/ms-teams.php'; -``` - -[Source](/contrib/ms-teams.php) - - - -## Installing -Require ms-teams recipe in your `deploy.php` file: -Setup: -1. Open MS Teams -2. Navigate to Teams section -3. Select existing or create new team -4. Select existing or create new channel -5. Hover over channel to get three dots, click, in menu select "Connectors" -6. Search for and configure "Incoming Webhook" -7. Confirm/create and copy your Webhook URL -8. Setup deploy.php - Add in header: -```php -require 'contrib/ms-teams.php'; -set('teams_webhook', 'https://outlook.office.com/webhook/...'); -``` -Add in content: -```php -before('deploy', 'teams:notify'); -after('deploy:success', 'teams:notify:success'); -after('deploy:failed', 'teams:notify:failure'); -``` -9.) Sip your coffee -## Configuration -- `teams_webhook` – teams incoming webhook url, **required** - ``` - set('teams_webhook', 'https://outlook.office.com/webhook/...'); - ``` -- `teams_title` – the title of application, default `{{application}}` -- `teams_text` – notification message template, markdown supported - ``` - set('teams_text', '_{{user}}_ deploying `{{what}}` to *{{where}}*'); - ``` -- `teams_success_text` – success template, default: - ``` - set('teams_success_text', 'Deploy to *{{where}}* successful'); - ``` -- `teams_failure_text` – failure template, default: - ``` - set('teams_failure_text', 'Deploy to *{{where}}* failed'); - ``` -- `teams_color` – color's attachment -- `teams_success_color` – success color's attachment -- `teams_failure_color` – failure color's attachment -## Usage -If you want to notify only about beginning of deployment add this line only: -```php -before('deploy', 'teams:notify'); -``` -If you want to notify about successful end of deployment add this too: -```php -after('deploy:success', 'teams:notify:success'); -``` -If you want to notify about failed deployment add this too: -```php -after('deploy:failed', 'teams:notify:failure'); -``` - - -## Configuration -### teams_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L79) - -Title of project - -```php title="Default value" -return get('application', 'Project'); -``` - - -### teams_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L84) - -Deploy message - -```php title="Default value" -'_{{user}}_ deploying `{{what}}` to *{{where}}*' -``` - - -### teams_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L85) - - - -```php title="Default value" -'Deploy to *{{where}}* successful' -``` - - -### teams_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L86) - - - -```php title="Default value" -'Deploy to *{{where}}* failed' -``` - - -### teams_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L89) - -Color of attachment - -```php title="Default value" -'#4d91f7' -``` - - -### teams_success_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L90) - - - -```php title="Default value" -'#00c100' -``` - - -### teams_failure_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L91) - - - -```php title="Default value" -'#ff0909' -``` - - - -## Tasks - -### teams:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L94) - -Notifies Teams. - - - - -### teams:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L109) - -Notifies Teams about deploy finish. - - - - -### teams:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ms-teams.php#L124) - -Notifies Teams about deploy failure. - - - - diff --git a/docs/contrib/newrelic.md b/docs/contrib/newrelic.md deleted file mode 100644 index c0859584b..000000000 --- a/docs/contrib/newrelic.md +++ /dev/null @@ -1,79 +0,0 @@ - - - - -# Newrelic Recipe - -```php -require 'contrib/newrelic.php'; -``` - -[Source](/contrib/newrelic.php) - - - -## Configuration -- `newrelic_app_id` – newrelic's app id -- `newrelic_api_key` – newrelic's api key -- `newrelic_description` – message to send -- `newrelic_endpoint` – newrelic's REST API endpoint -## Usage -Since you should only notify New Relic of a successful deployment, the `newrelic:notify` task should be executed right at the end. -```php -after('deploy', 'newrelic:notify'); -``` - - -## Configuration -### newrelic_app_id -[Source](https://github.com/deployphp/deployer/blob/master/contrib/newrelic.php#L24) - - -:::info Required -Throws exception if not set. -::: - - - - -### newrelic_description -[Source](https://github.com/deployphp/deployer/blob/master/contrib/newrelic.php#L28) - - - -```php title="Default value" -return runLocally('git log -n 1 --format="%an: %s" | tr \'"\' "\'"'); -``` - - -### newrelic_revision -[Source](https://github.com/deployphp/deployer/blob/master/contrib/newrelic.php#L32) - - - -```php title="Default value" -return runLocally('git log -n 1 --format="%h"'); -``` - - -### newrelic_endpoint -[Source](https://github.com/deployphp/deployer/blob/master/contrib/newrelic.php#L36) - - - -```php title="Default value" -'api.newrelic.com' -``` - - - -## Tasks - -### newrelic:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/newrelic.php#L39) - -Notifies New Relic of deployment. - - - - diff --git a/docs/contrib/npm.md b/docs/contrib/npm.md deleted file mode 100644 index 5b5425143..000000000 --- a/docs/contrib/npm.md +++ /dev/null @@ -1,53 +0,0 @@ - - - - -# Npm Recipe - -```php -require 'contrib/npm.php'; -``` - -[Source](/contrib/npm.php) - - - -## Configuration -- `bin/npm` *(optional)*: set npm binary, automatically detected otherwise. -## Usage -```php -after('deploy:update_code', 'npm:install'); -``` - - -## Configuration -### bin/npm -[Source](https://github.com/deployphp/deployer/blob/master/contrib/npm.php#L17) - -## Configuration -- `bin/npm` *(optional)*: set npm binary, automatically detected otherwise. -## Usage -```php -after('deploy:update_code', 'npm:install'); -``` - -```php title="Default value" -return which('npm'); -``` - - - -## Tasks - -### npm:install -[Source](https://github.com/deployphp/deployer/blob/master/contrib/npm.php#L27) - -Installs npm packages. - -Uses `npm ci` command. This command is similar to npm install, -except it's meant to be used in automated environments such as -test platforms, continuous integration, and deployment -- or -any situation where you want to make sure you're doing a clean -install of your dependencies. - - diff --git a/docs/contrib/ntfy.md b/docs/contrib/ntfy.md deleted file mode 100644 index 7da89e92f..000000000 --- a/docs/contrib/ntfy.md +++ /dev/null @@ -1,184 +0,0 @@ - - - - -# Ntfy Recipe - -```php -require 'contrib/ntfy.php'; -``` - -[Source](/contrib/ntfy.php) - - - -## Installing -Require ntfy.sh recipe in your `deploy.php` file: -Setup: -1. Setup deploy.php - Add in header: -```php -require 'contrib/ntfy.php'; -set('ntfy_topic', 'ntfy.sh/mytopic'); -``` -Add in content: -```php -before('deploy', 'ntfy:notify'); -after('deploy:success', 'ntfy:notify:success'); -after('deploy:failed', 'ntfy:notify:failure'); -``` -9.) Sip your coffee -## Configuration -- `ntfy_server` – ntfy server url, default `ntfy.sh` - ``` - set('ntfy_server', 'ntfy.sh'); - ``` -- `ntfy_topic` – ntfy topic, **required** - ``` - set('ntfy_topic', 'mysecrettopic'); - ``` -- `ntfy_title` – the title of the message, default `{{application}}` -- `ntfy_text` – notification message template - ``` - set('ntfy_text', '_{{user}}_ deploying `{{what}}` to *{{where}}*'); - ``` -- `ntfy_tags` – notification message tags / emojis (comma separated) - ``` - set('ntfy_tags', `information_source`); - ``` -- `ntfy_priority` – notification message priority (integer) - ``` - set('ntfy_priority', 5); - ``` -- `ntfy_success_text` – success template, default: - ``` - set('ntfy_success_text', 'Deploy to *{{where}}* successful'); - ``` -- `ntfy_success_tags` – success tags / emojis (comma separated) - ``` - set('ntfy_success_tags', `white_check_mark,champagne`); - ``` -- `ntfy_success_priority` – success notification message priority -- `ntfy_failure_text` – failure template, default: - ``` - set('ntfy_failure_text', 'Deploy to *{{where}}* failed'); - ``` -- `ntfy_failure_tags` – failure tags / emojis (comma separated) - ``` - set('ntfy_failure_tags', `warning,skull`); - ``` -- `ntfy_failure_priority` – failure notification message priority -## Usage -If you want to notify only about beginning of deployment add this line only: -```php -before('deploy', 'ntfy:notify'); -``` -If you want to notify about successful end of deployment add this too: -```php -after('deploy:success', 'ntfy:notify:success'); -``` -If you want to notify about failed deployment add this too: -```php -after('deploy:failed', 'ntfy:notify:failure'); -``` - - -## Configuration -### ntfy_server -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ntfy.php#L90) - - - -```php title="Default value" -'ntfy.sh' -``` - - -### ntfy_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ntfy.php#L93) - -Title of project - -```php title="Default value" -return get('application', 'Project'); -``` - - -### ntfy_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ntfy.php#L98) - -Deploy message - -```php title="Default value" -'_{{user}}_ deploying `{{what}}` to *{{where}}*' -``` - - -### ntfy_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ntfy.php#L99) - - - -```php title="Default value" -'Deploy to *{{where}}* successful' -``` - - -### ntfy_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ntfy.php#L100) - - - -```php title="Default value" -'Deploy to *{{where}}* failed' -``` - - -### ntfy_tags -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ntfy.php#L103) - -Message tags - - - -### ntfy_success_tags -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ntfy.php#L104) - - - - - -### ntfy_failure_tags -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ntfy.php#L105) - - - - - - -## Tasks - -### ntfy:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ntfy.php#L108) - -Notifies ntfy server. - - - - -### ntfy:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ntfy.php#L126) - -Notifies ntfy server about deploy finish. - - - - -### ntfy:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/ntfy.php#L144) - -Notifies ntfy server about deploy failure. - - - - diff --git a/docs/contrib/phinx.md b/docs/contrib/phinx.md deleted file mode 100644 index aa2a16d4e..000000000 --- a/docs/contrib/phinx.md +++ /dev/null @@ -1,114 +0,0 @@ - - - - -# Phinx Recipe - -```php -require 'contrib/phinx.php'; -``` - -[Source](/contrib/phinx.php) - - - -## Configuration options -All options are in the config parameter `phinx` specified as an array (instead of the `phinx_path` variable). -All parameters are *optional*, but you can specify them with a dictionary (to change all parameters) -or by deployer dot notation (to change one option). -### Phinx params -- `phinx.environment` -- `phinx.date` -- `phinx.configuration` N.B. current directory is the project directory -- `phinx.target` -- `phinx.seed` -- `phinx.parser` -- `phinx.remove-all` (pass empty string as value) -### Phinx path params -- `phinx_path` Specify phinx path (by default phinx is searched for in $PATH, ./vendor/bin and ~/.composer/vendor/bin) -### Example of usage -```php -$phinx_env_vars = [ - 'environment' => 'development', - 'configuration' => './migration/.phinx.yml', - 'target' => '20120103083322', - 'remove-all' => '', -]; -set('phinx_path', '/usr/local/phinx/bin/phinx'); -set('phinx', $phinx_env_vars); -after('cleanup', 'phinx:migrate'); -or set it for a specific server -host('dev') - ->user('user') - ->set('deploy_path', '/var/www') - ->set('phinx', $phinx_env_vars) - ->set('phinx_path', ''); -``` -## Suggested Usage -You can run all tasks before or after any -tasks (but you need to specify external configs for phinx). -If you use internal configs (which are in your project) you need -to run it after the `deploy:update_code` task is completed. -## Read more -For further reading see [phinx.org](https://phinx.org). Complete descriptions of all possible options can be found on the [commands page](http://docs.phinx.org/en/latest/commands.html). - - -## Configuration -### bin/phinx -[Source](https://github.com/deployphp/deployer/blob/master/contrib/phinx.php#L81) - -Phinx recipe for Deployer - -@author Alexey Boyko -@contributor Security-Database -@copyright 2016 Alexey Boyko -@license MIT https://github.com/deployphp/recipes/blob/master/LICENSE - -@link https://github.com/deployphp/recipes - -@see http://deployer.org -@see https://phinx.org - -Path to Phinx -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - - -## Tasks - -### phinx:migrate -[Source](https://github.com/deployphp/deployer/blob/master/contrib/phinx.php#L149) - -Migrats database with phinx. - - - - -### phinx:rollback -[Source](https://github.com/deployphp/deployer/blob/master/contrib/phinx.php#L170) - -Rollbacks database migrations with phinx. - - - - -### phinx:seed -[Source](https://github.com/deployphp/deployer/blob/master/contrib/phinx.php#L191) - -Seeds database with phinx. - - - - -### phinx:breakpoint -[Source](https://github.com/deployphp/deployer/blob/master/contrib/phinx.php#L211) - -Sets a migrations breakpoint with phinx. - - - - diff --git a/docs/contrib/php-fpm.md b/docs/contrib/php-fpm.md deleted file mode 100644 index 50367c5ee..000000000 --- a/docs/contrib/php-fpm.md +++ /dev/null @@ -1,84 +0,0 @@ - - - - -# Php-fpm Recipe - -```php -require 'contrib/php-fpm.php'; -``` - -[Source](/contrib/php-fpm.php) - - - -:::caution -Do **not** reload php-fpm. Some user requests could fail or not complete in the -process of reloading. -Instead, configure your server [properly](https://ï.at/avoid-php-fpm-reloading). If you're using Deployer's provision -recipe, it's already configured the right way and no php-fpm reload is needed. -::: -## Configuration -- `php_fpm_version` – The PHP-fpm version. For example: `8.0`. -- `php_fpm_service` – The full name of the PHP-fpm service. Defaults to `php{{php_fpm_version}}-fpm`. -- `php_fpm_command` – The command to run to reload PHP-fpm. Defaults to `sudo systemctl reload {{php_fpm_service}}`. -## Usage -Start by explicitely providing the current version of PHP-version using the `php_fpm_version`. -Alternatively, you may use any of the options above to configure how PHP-fpm should reload. -Then, add the `php-fpm:reload` task at the end of your deployments by using the `after` method like so. -```php -set('php_fpm_version', '8.0'); -after('deploy', 'php-fpm:reload'); -``` - - -## Configuration -### php_fpm_version -[Source](https://github.com/deployphp/deployer/blob/master/contrib/php-fpm.php#L35) - -:::caution -Do **not** reload php-fpm. Some user requests could fail or not complete in the -process of reloading. -Instead, configure your server [properly](https://ï.at/avoid-php-fpm-reloading). If you're using Deployer's provision -recipe, it's already configured the right way and no php-fpm reload is needed. -::: -## Configuration -- `php_fpm_version` – The PHP-fpm version. For example: `8.0`. -- `php_fpm_service` – The full name of the PHP-fpm service. Defaults to `php[php_fpm_version](/docs/contrib/php-fpm.md#php_fpm_version)-fpm`. -- `php_fpm_command` – The command to run to reload PHP-fpm. Defaults to `sudo systemctl reload [php_fpm_service](/docs/contrib/php-fpm.md#php_fpm_service)`. -## Usage -Start by explicitely providing the current version of PHP-version using the `php_fpm_version`. -Alternatively, you may use any of the options above to configure how PHP-fpm should reload. -Then, add the `php-fpm:reload` task at the end of your deployments by using the `after` method like so. -```php -set('php_fpm_version', '8.0'); -after('deploy', 'php-fpm:reload'); -``` -Automatically detects by using [bin/php](/docs/recipe/common.md#bin/php). - -```php title="Default value" -return run('{{bin/php}} -r "printf(\'%d.%d\', PHP_MAJOR_VERSION, PHP_MINOR_VERSION);"'); -``` - - -### php_fpm_service -[Source](https://github.com/deployphp/deployer/blob/master/contrib/php-fpm.php#L39) - - - -```php title="Default value" -'php{{php_fpm_version}}-fpm' -``` - - - -## Tasks - -### php-fpm:reload -[Source](https://github.com/deployphp/deployer/blob/master/contrib/php-fpm.php#L42) - -Reloads the php-fpm service. - - - - diff --git a/docs/contrib/rabbit.md b/docs/contrib/rabbit.md deleted file mode 100644 index da83225f1..000000000 --- a/docs/contrib/rabbit.md +++ /dev/null @@ -1,59 +0,0 @@ - - - - -# Rabbit Recipe - -```php -require 'contrib/rabbit.php'; -``` - -[Source](/contrib/rabbit.php) - - - -### Installing -```php -deploy.php -require 'recipe/rabbit.php'; -``` -### Configuration options -- **rabbit** *(required)*: accepts an *array* with the connection information to [rabbitmq](http://www.rabbitmq.com) server token and team name. -You can provide also other configuration options: - - *host* - default is localhost - - *port* - default is 5672 - - *username* - default is *guest* - - *password* - default is *guest* - - *channel* - no default value, need to be specified via config - - *message* - default is **Deployment to '$host' on *$prod* was successful\n$releasePath** - - *vhost* - default is -```php -deploy.php -set('rabbit', [ - 'host' => 'localhost', - 'port' => '5672', - 'username' => 'guest', - 'password' => 'guest', - 'channel' => 'notify-channel', - 'vhost' => '/my-app' -]); -``` -### Suggested Usage -Since you should only notify RabbitMQ channel of a successful deployment, the `deploy:rabbit` task should be executed right at the end. -```php -deploy.php -before('deploy:end', 'deploy:rabbit'); -``` - - - -## Tasks - -### deploy:rabbit -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rabbit.php#L58) - -Notifies RabbitMQ channel about deployment. - - - - diff --git a/docs/contrib/raygun.md b/docs/contrib/raygun.md deleted file mode 100644 index 20f571a3a..000000000 --- a/docs/contrib/raygun.md +++ /dev/null @@ -1,40 +0,0 @@ - - - - -# Raygun Recipe - -```php -require 'contrib/raygun.php'; -``` - -[Source](/contrib/raygun.php) - - - -## Configuration -- `raygun_api_key` – the API key of your Raygun application -- `raygun_version` – the version of your application that this deployment is releasing -- `raygun_owner_name` – the name of the person creating this deployment -- `raygun_email` – the email of the person creating this deployment -- `raygun_comment` – the deployment notes -- `raygun_scm_identifier` – the commit that this deployment was built off -- `raygun_scm_type` - the source control system you use -## Usage -To notify Raygun of a successful deployment, you can use the 'raygun:notify' task after a deployment. -```php -after('deploy', 'raygun:notify'); -``` - - - -## Tasks - -### raygun:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/raygun.php#L28) - -Notifies Raygun of deployment. - - - - diff --git a/docs/contrib/rocketchat.md b/docs/contrib/rocketchat.md deleted file mode 100644 index a9ff12e22..000000000 --- a/docs/contrib/rocketchat.md +++ /dev/null @@ -1,214 +0,0 @@ - - - - -# Rocketchat Recipe - -```php -require 'contrib/rocketchat.php'; -``` - -[Source](/contrib/rocketchat.php) - - - -## Installing -Create a RocketChat incoming webhook, through the administration panel. -Add hook on deploy: -``` -before('deploy', 'rocketchat:notify'); -``` -## Configuration - - `rocketchat_webhook` - incoming rocketchat webook **required** - ``` - set('rocketchat_webhook', 'https://rocketchat.yourcompany.com/hooks/XXXXX'); - ``` - - `rocketchat_title` - the title of the application, defaults to `{{application}}` - - `rocketchat_text` - notification message - ``` - set('rocketchat_text', '_{{user}}_ deploying {{what}} to {{where}}'); - ``` - - `rocketchat_success_text` – success template, default: - ``` - set('rocketchat_success_text', 'Deploy to *{{where}}* successful'); - ``` - - `rocketchat_failure_text` – failure template, default: - ``` - set('rocketchat_failure_text', 'Deploy to *{{where}}* failed'); - ``` - - `rocketchat_color` – color's attachment - - `rocketchat_success_color` – success color's attachment - - `rocketchat_failure_color` – failure color's attachment -## Usage -If you want to notify only about beginning of deployment add this line only: -```php -before('deploy', 'rocketchat:notify'); -``` -If you want to notify about successful end of deployment add this too: -```php -after('deploy:success', 'rocketchat:notify:success'); -``` -If you want to notify about failed deployment add this too: -```php -after('deploy:failed', 'rocketchat:notify:failure'); -``` - - -## Configuration -### rockchat_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L65) - - - -```php title="Default value" -return get('application', 'Project'); -``` - - -### rocketchat_icon_emoji -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L69) - - - -```php title="Default value" -':robot:' -``` - - -### rocketchat_icon_url -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L70) - - - -```php title="Default value" -null -``` - - -### rocketchat_channel -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L72) - - - -```php title="Default value" -null -``` - - -### rocketchat_room_id -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L73) - - - -```php title="Default value" -null -``` - - -### rocketchat_username -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L74) - - - -```php title="Default value" -null -``` - - -### rocketchat_webhook -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L75) - - - -```php title="Default value" -null -``` - - -### rocketchat_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L77) - - - -```php title="Default value" -'#000000' -``` - - -### rocketchat_success_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L78) - - - -```php title="Default value" -'#00c100' -``` - - -### rocketchat_failure_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L79) - - - -```php title="Default value" -'#ff0909' -``` - - -### rocketchat_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L81) - - - -```php title="Default value" -'_{{user}}_ deploying `{{what}}` to *{{where}}*' -``` - - -### rocketchat_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L82) - - - -```php title="Default value" -'Deploy to *{{where}}* successful' -``` - - -### rocketchat_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L83) - - - -```php title="Default value" -'Deploy to *{{where}}* failed' -``` - - - -## Tasks - -### rocketchat:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L86) - -Notifies RocketChat. - - - - -### rocketchat:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L116) - -Notifies RocketChat about deploy finish. - - - - -### rocketchat:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rocketchat.php#L146) - -Notifies RocketChat about deploy failure. - - - - diff --git a/docs/contrib/rollbar.md b/docs/contrib/rollbar.md deleted file mode 100644 index 0959c506a..000000000 --- a/docs/contrib/rollbar.md +++ /dev/null @@ -1,50 +0,0 @@ - - - - -# Rollbar Recipe - -```php -require 'contrib/rollbar.php'; -``` - -[Source](/contrib/rollbar.php) - - - -## Configuration -- `rollbar_token` – access token to rollbar api -- `rollbar_comment` – comment about deploy, default to - ```php - set('rollbar_comment', '_{{user}}_ deploying `{{what}}` to *{{where}}*'); - ``` -- `rollbar_username` – rollbar user name -## Usage -Since you should only notify Rollbar channel of a successful deployment, the `rollbar:notify` task should be executed right at the end. -```php -after('deploy', 'rollbar:notify'); -``` - - -## Configuration -### rollbar_comment -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rollbar.php#L27) - - - -```php title="Default value" -'_{{user}}_ deploying `{{what}}` to *{{where}}*' -``` - - - -## Tasks - -### rollbar:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rollbar.php#L30) - -Notifies Rollbar of deployment. - - - - diff --git a/docs/contrib/rsync.md b/docs/contrib/rsync.md deleted file mode 100644 index 94d5c9b72..000000000 --- a/docs/contrib/rsync.md +++ /dev/null @@ -1,208 +0,0 @@ - - - - -# Rsync Recipe - -```php -require 'contrib/rsync.php'; -``` - -[Source](/contrib/rsync.php) - - - -:::warning -This must not be confused with `/src/Utility/Rsync.php`, deployer's built-in rsync. Their configuration options are also very different, read carefully below. -::: -## Configuration options -- **rsync**: Accepts an array with following rsync options (all are optional and defaults are ok): - - *exclude*: accepts an *array* with patterns to be excluded from sending to server - - *exclude-file*: accepts a *string* containing absolute path to file, which contains exclude patterns - - *include*: accepts an *array* with patterns to be included in sending to server - - *include-file*: accepts a *string* containing absolute path to file, which contains include patterns - - *filter*: accepts an *array* of rsync filter rules - - *filter-file*: accepts a *string* containing merge-file filename. - - *filter-perdir*: accepts a *string* containing merge-file filename to be scanned and merger per each directory in rsync list on files to send - - *flags*: accepts a *string* of flags to set when calling rsync command. Please **avoid** flags that accept params, and use *options* instead. - - *options*: accepts an *array* of options to set when calling rsync command. **DO NOT** prefix options with `--` as it's automatically added. - - *timeout*: accepts an *int* defining timeout for rsync command to run locally. -### Sample Configuration: -Following is default configuration. By default rsync ignores only git dir and `deploy.php` file. -```php -deploy.php -set('rsync',[ - 'exclude' => [ - '.git', - 'deploy.php', - ], - 'exclude-file' => false, - 'include' => [], - 'include-file' => false, - 'filter' => [], - 'filter-file' => false, - 'filter-perdir'=> false, - 'flags' => 'rz', // Recursive, with compress - 'options' => ['delete'], - 'timeout' => 60, -]); -``` -If You have multiple excludes, You can put them in file and reference that instead. If You use `deploy:rsync_warmup` You could set additional options that could speed-up and/or affect way things are working. For example: -```php -deploy.php -set('rsync',[ - 'exclude' => ['excludes_file'], - 'exclude-file' => '/tmp/localdeploys/excludes_file', //Use absolute path to avoid possible rsync problems - 'include' => [], - 'include-file' => false, - 'filter' => [], - 'filter-file' => false, - 'filter-perdir' => false, - 'flags' => 'rzcE', // Recursive, with compress, check based on checksum rather than time/size, preserve Executable flag - 'options' => ['delete', 'delete-after', 'force'], //Delete after successful transfer, delete even if deleted dir is not empty - 'timeout' => 3600, //for those huge repos or crappy connection -]); -``` -### Parameter -- **rsync_src**: per-host rsync source. This can be server, stage or whatever-dependent. By default it's set to current directory -- **rsync_dest**: per-host rsync destination. This can be server, stage or whatever-dependent. by default it's equivalent to release deploy destination. -### Sample configurations: -This is default configuration: -```php -set('rsync_src', __DIR__); -set('rsync_dest','{{release_path}}'); -``` -If You use local deploy recipe You can set src to local release: -```php -host('hostname') - ->hostname('10.10.10.10') - ->port(22) - ->set('deploy_path','/your/remote/path/app') - ->set('rsync_src', '/your/local/path/app') - ->set('rsync_dest','{{release_path}}'); -``` -## Usage -- `rsync` task - Set `rsync_src` to locally cloned repository and rsync to `rsync_dest`. Then set this task instead of `deploy:update_code` in Your `deploy` task if Your hosting provider does not allow git. -- `rsync:warmup` task - If Your deploy task looks like: - ```php - task('deploy', [ - 'deploy:prepare', - 'deploy:release', - 'rsync', - 'deploy:vendors', - 'deploy:symlink', - ])->desc('Deploy your project'); - ``` - And Your `rsync_dest` is set to `{{release_path}}` then You could add this task to run before `rsync` task or after `deploy:release`, whatever is more convenient. - - -## Configuration -### rsync -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L120) - - - -```php title="Default value" -[ - 'exclude' => [ - '.git', - 'deploy.php', - ], - 'exclude-file' => false, - 'include' => [], - 'include-file' => false, - 'filter' => [], - 'filter-file' => false, - 'filter-perdir' => false, - 'flags' => 'rz', - 'options' => ['delete'], - 'timeout' => 300, -] -``` - - -### rsync_src -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L136) - - - -```php title="Default value" -__DIR__ -``` - - -### rsync_dest -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L137) - - - -```php title="Default value" -'{{release_path}}' -``` - - -### rsync_excludes -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L139) - - -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### rsync_includes -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L154) - - -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### rsync_filter -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L169) - - -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### rsync_options -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L187) - - -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - - -## Tasks - -### rsync:warmup -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L199) - -Warmups remote Rsync target. - - - - -### rsync -[Source](https://github.com/deployphp/deployer/blob/master/contrib/rsync.php#L214) - -Rsync local->remote. - - - - diff --git a/docs/contrib/sentry.md b/docs/contrib/sentry.md deleted file mode 100644 index 434131fa3..000000000 --- a/docs/contrib/sentry.md +++ /dev/null @@ -1,60 +0,0 @@ - - - - -# Sentry Recipe - -```php -require 'contrib/sentry.php'; -``` - -[Source](/contrib/sentry.php) - - - -### Configuration options -- **organization** *(required)*: the slug of the organization the release belongs to. -- **projects** *(required)*: array of slugs of the projects to create a release for. -- **token** *(required)*: authentication token. Can be created at [https://sentry.io/settings/account/api/auth-tokens/] -- **version** *(required)* – a version identifier for this release. -Can be a version number, a commit hash etc. (Defaults is set to git log -n 1 --format="%h".) -- **version_prefix** *(optional)* - a string prefixed to version. -Releases are global per organization so indipentent projects needs to prefix version number with unique string to avoid conflicts -- **environment** *(optional)* - the environment you’re deploying to. By default framework's environment is used. -For example for symfony, *symfony_env* configuration is read otherwise defaults to 'prod'. -- **ref** *(optional)* – an optional commit reference. This is useful if a tagged version has been provided. -- **refs** *(optional)* - array to indicate the start and end commits for each repository included in a release. -Head commits must include parameters *repository* and *commit*) (the HEAD sha). -They can optionally include *previousCommit* (the sha of the HEAD of the previous release), -which should be specified if this is the first time you’ve sent commit data. -- **commits** *(optional)* - array commits data to be associated with the release. -Commits must include parameters *id* (the sha of the commit), and can optionally include *repository*, -*message*, *author_name*, *author_email* and *timestamp*. By default will send all new commits, -unless it's a first release, then only first 200 will be sent. -- **url** *(optional)* – a URL that points to the release. This can be the path to an online interface to the sourcecode for instance. -- **date_released** *(optional)* – date that indicates when the release went live. If not provided the current time is assumed. -- **sentry_server** *(optional)* – sentry server (if you host it yourself). defaults to hosted sentry service. -- **date_deploy_started** *(optional)* - date that indicates when the deploy started. Defaults to current time. -- **date_deploy_finished** *(optional)* - date that indicates when the deploy ended. If not provided, the current time is used. -- **deploy_name** *(optional)* - name of the deploy -- **git_version_command** *(optional)* - the command that retrieves the git version information (Defaults is set to git log -n 1 --format="%h", other options are git describe --tags --abbrev=0) -```php -deploy.php -set('sentry', [ - 'organization' => 'exampleorg', - 'projects' => [ - 'exampleproj' - ], - 'token' => 'd47828...', - 'version' => '0.0.1', -]); -``` -### Suggested Usage -Since you should only notify Sentry of a successful deployment, the deploy:sentry task should be executed right at the end. -```php -deploy.php -after('deploy', 'deploy:sentry'); -``` - - - diff --git a/docs/contrib/slack.md b/docs/contrib/slack.md deleted file mode 100644 index 203617f55..000000000 --- a/docs/contrib/slack.md +++ /dev/null @@ -1,204 +0,0 @@ - - - - -# Slack Recipe - -```php -require 'contrib/slack.php'; -``` - -[Source](/contrib/slack.php) - - - -## Installing -Add to Slack -Add hook on deploy: -```php -before('deploy', 'slack:notify'); -``` -## Configuration -- `slack_webhook` – slack incoming webhook url, **required** - ``` - set('slack_webhook', 'https://hooks.slack.com/...'); - ``` -- `slack_channel` - channel to send notification to. The default is the channel configured in the webhook -- `slack_title` – the title of application, default `{{application}}` -- `slack_text` – notification message template, markdown supported - ``` - set('slack_text', '_{{user}}_ deploying `{{what}}` to *{{where}}*'); - ``` -- `slack_success_text` – success template, default: - ``` - set('slack_success_text', 'Deploy to *{{where}}* successful'); - ``` -- `slack_failure_text` – failure template, default: - ``` - set('slack_failure_text', 'Deploy to *{{where}}* failed'); - ``` -- `slack_color` – color's attachment -- `slack_success_color` – success color's attachment -- `slack_failure_color` – failure color's attachment -- `slack_fields` - set attachments fields for pretty output in Slack, default: - ``` - set('slack_fields', []); - ``` -## Usage -If you want to notify only about beginning of deployment add this line only: -```php -before('deploy', 'slack:notify'); -``` -If you want to notify about successful end of deployment add this too: -```php -after('deploy:success', 'slack:notify:success'); -``` -If you want to notify about failed deployment add this too: -```php -after('deploy:failed', 'slack:notify:failure'); -``` - - -## Configuration -### slack_channel -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L70) - -Channel to publish to, when false the default channel the webhook will be used - -```php title="Default value" -false -``` - - -### slack_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L73) - -Title of project - -```php title="Default value" -return get('application', 'Project'); -``` - - -### slack_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L78) - -Deploy message - -```php title="Default value" -'_{{user}}_ deploying `{{what}}` to *{{where}}*' -``` - - -### slack_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L79) - - - -```php title="Default value" -'Deploy to *{{where}}* successful' -``` - - -### slack_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L80) - - - -```php title="Default value" -'Deploy to *{{where}}* failed' -``` - - -### slack_rollback_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L81) - - - -```php title="Default value" -'_{{user}}_ rolled back changes on *{{where}}*' -``` - - -### slack_fields -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L82) - - - - - -### slack_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L85) - -Color of attachment - -```php title="Default value" -'#4d91f7' -``` - - -### slack_success_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L86) - - - -```php title="Default value" -'#00c100' -``` - - -### slack_failure_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L87) - - - -```php title="Default value" -'#ff0909' -``` - - -### slack_rollback_color -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L88) - - - -```php title="Default value" -'#eba211' -``` - - - -## Tasks - -### slack:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L100) - -Notifies Slack. - - - - -### slack:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L120) - -Notifies Slack about deploy finish. - - - - -### slack:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L141) - -Notifies Slack about deploy failure. - - - - -### slack:notify:rollback -[Source](https://github.com/deployphp/deployer/blob/master/contrib/slack.php#L161) - -Notifies Slack about rollback. - - - - diff --git a/docs/contrib/supervisord-monitor.md b/docs/contrib/supervisord-monitor.md deleted file mode 100644 index 42d7287da..000000000 --- a/docs/contrib/supervisord-monitor.md +++ /dev/null @@ -1,106 +0,0 @@ - - - - -# Supervisord-monitor Recipe - -```php -require 'contrib/supervisord-monitor.php'; -``` - -[Source](/contrib/supervisord-monitor.php) - - - -### Description -This is a recipe that uses the [Supervisord server monitoring project](https://github.com/mlazarov/supervisord-monitor). -With this recipe the possibility is created to restart a supervisord process through the Supervisor Monitor webtool, by using cURL. This workaround is particular usefull when the deployment user has unsuficient rights to restart a daemon process from the cli. -### Configuration -``` -set('supervisord', [ - 'uri' => 'https://youruri.xyz/supervisor', - 'basic_auth_user' => 'username', - 'basic_auth_password' => 'password', - 'process_name' => 'process01', -]); -``` -or -``` -set('supervisord_uri', 'https://youruri.xyz/supervisor'); -set('supervisord_basic_auth_user', 'username'); -set('supervisord_basic_auth_password', 'password'); -set('supervisord_process_name', 'process01'); -``` -- `supervisord` – array with configuration for Supervisord - - `uri` – URI to the Supervisord monitor page - - `basic_auth_user` – Basic auth username to access the URI - - `basic_auth_password` – Basic auth password to access the URI - - `process_name` – the process name, as visible in the Supervisord monitor page. Multiple processes can be listed here, comma separated -### Task -- `supervisord-monitor:restart` Restarts given processes -- `supervisord-monitor:stop` Stops given processes -- `supervisord-monitor:start` Starts given processes -### Usage -A complete example with configs, staging and deployment -``` - 'https://youruri.xyz/supervisor', - 'basic_auth_user' => 'username', - 'basic_auth_password' => 'password', - 'process_name' => 'process01', -]); -host('staging.myproject.com') - ->set('branch', 'develop') - ->set('labels', ['stage' => 'staging']); -host('myproject.com') - ->set('branch', 'main') - ->set('labels', ['stage' => 'production']); -Tasks -task('build', function () { - run('cd {{release_path}} && build'); -}); -task('deploy', [ - 'build', - 'supervisord', -]); -task('supervisord', ['supervisord-monitor:restart']) - ->select('stage=production'); -``` - - - -## Tasks - -### supervisord-monitor:restart -[Source](https://github.com/deployphp/deployer/blob/master/contrib/supervisord-monitor.php#L134) - - - - - - -### supervisord-monitor:stop -[Source](https://github.com/deployphp/deployer/blob/master/contrib/supervisord-monitor.php#L151) - - - - - - -### supervisord-monitor:start -[Source](https://github.com/deployphp/deployer/blob/master/contrib/supervisord-monitor.php#L165) - - - - - - diff --git a/docs/contrib/telegram.md b/docs/contrib/telegram.md deleted file mode 100644 index 855da16d2..000000000 --- a/docs/contrib/telegram.md +++ /dev/null @@ -1,157 +0,0 @@ - - - - -# Telegram Recipe - -```php -require 'contrib/telegram.php'; -``` - -[Source](/contrib/telegram.php) - - - -## Installing - 1. Create telegram bot with [BotFather](https://t.me/BotFather) and grab the token provided - 2. Send `/start` to your bot and open https://api.telegram.org/bot{$TELEGRAM_TOKEN_HERE}/getUpdates - 3. Take chat_id from response -Add hook on deploy: -```php -before('deploy', 'telegram:notify'); -``` -## Configuration -- `telegram_token` – telegram bot token, **required** -- `telegram_chat_id` — chat ID to push messages to -- `telegram_proxy` - proxy connection string in [CURLOPT_PROXY](https://curl.haxx.se/libcurl/c/CURLOPT_PROXY.html) form like: - ``` - http://proxy:80 - socks5://user:password@host:3128 - ``` -- `telegram_title` – the title of application, default `{{application}}` -- `telegram_text` – notification message template - ``` - _{{user}}_ deploying `{{what}}` to *{{where}}* - ``` -- `telegram_success_text` – success template, default: - ``` - Deploy to *{{where}}* successful - ``` -- `telegram_failure_text` – failure template, default: - ``` - Deploy to *{{where}}* failed - ``` -## Usage -If you want to notify only about beginning of deployment add this line only: -```php -before('deploy', 'telegram:notify'); -``` -If you want to notify about successful end of deployment add this too: -```php -after('deploy:success', 'telegram:notify:success'); -``` -If you want to notify about failed deployment add this too: -```php -after('deploy:failed', 'telegram:notify:failure'); - - -## Configuration -### telegram_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L65) - -Title of project - -```php title="Default value" -return get('application', 'Project'); -``` - - -### telegram_token -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L70) - -Telegram settings -:::info Required -Throws exception if not set. -::: - - - - -### telegram_chat_id -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L73) - - -:::info Required -Throws exception if not set. -::: - - - - -### telegram_url -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L76) - - - -```php title="Default value" -return 'https://api.telegram.org/bot' . get('telegram_token') . '/sendmessage'; -``` - - -### telegram_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L81) - -Deploy message - -```php title="Default value" -'_{{user}}_ deploying `{{what}}` to *{{where}}*' -``` - - -### telegram_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L82) - - - -```php title="Default value" -'Deploy to *{{where}}* successful' -``` - - -### telegram_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L83) - - - -```php title="Default value" -'Deploy to *{{where}}* failed' -``` - - - -## Tasks - -### telegram:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L87) - -Notifies Telegram. - - - - -### telegram:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L118) - -Notifies Telegram about deploy finish. - - - - -### telegram:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/telegram.php#L149) - -Notifies Telegram about deploy failure. - - - - diff --git a/docs/contrib/webpack_encore.md b/docs/contrib/webpack_encore.md deleted file mode 100644 index bb80e69cb..000000000 --- a/docs/contrib/webpack_encore.md +++ /dev/null @@ -1,71 +0,0 @@ - - - - -# Webpack Encore Recipe - -```php -require 'contrib/webpack_encore.php'; -``` - -[Source](/contrib/webpack_encore.php) - -* Requires - * [npm](/docs/contrib/npm.md) - * [yarn](/docs/contrib/yarn.md) - - -## Configuration -- **webpack_encore/package_manager** *(optional)*: set yarn or npm. We try to find if yarn or npm is available and used. -## Usage -```php -For Yarn -after('deploy:update_code', 'yarn:install'); -For npm -after('deploy:update_code', 'npm:install'); -after('deploy:update_code', 'webpack_encore:build'); -``` - - -## Configuration -### webpack_encore/package_manager -[Source](https://github.com/deployphp/deployer/blob/master/contrib/webpack_encore.php#L25) - -## Configuration -- **webpack_encore/package_manager** *(optional)*: set yarn or npm. We try to find if yarn or npm is available and used. -## Usage -```php -For Yarn -after('deploy:update_code', 'yarn:install'); -For npm -after('deploy:update_code', 'npm:install'); -after('deploy:update_code', 'webpack_encore:build'); -``` -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### webpack_encore/env -[Source](https://github.com/deployphp/deployer/blob/master/contrib/webpack_encore.php#L33) - - - -```php title="Default value" -'production' -``` - - - -## Tasks - -### webpack_encore:build -[Source](https://github.com/deployphp/deployer/blob/master/contrib/webpack_encore.php#L36) - -Runs webpack encore build. - - - - diff --git a/docs/contrib/workplace.md b/docs/contrib/workplace.md deleted file mode 100644 index 595e3e806..000000000 --- a/docs/contrib/workplace.md +++ /dev/null @@ -1,128 +0,0 @@ - - - - -# Workplace Recipe - -```php -require 'contrib/workplace.php'; -``` - -[Source](/contrib/workplace.php) - - - -This recipes works with Custom Integrations and Publishing Bots. -Add hook on deploy: -``` -before('deploy', 'workplace:notify'); -``` -## Configuration - - `workplace_webhook` - incoming workplace webhook **required** - ``` - // With custom integration - set('workplace_webhook', 'https://graph.facebook.com//feed?access_token='); - // With publishing bot - set('workplace_webhook', 'https://graph.facebook.com/v3.0/group/feed?access_token='); - // Use markdown on message - set('workplace_webhook', 'https://graph.facebook.com//feed?access_token=&formatting=MARKDOWN'); - ``` - - `workplace_text` - notification message - ``` - set('workplace_text', '_{{user}}_ deploying `{{what}}` to *{{where}}*'); - ``` - - `workplace_success_text` – success template, default: - ``` - set('workplace_success_text', 'Deploy to *{{where}}* successful'); - ``` - - `workplace_failure_text` – failure template, default: - ``` - set('workplace_failure_text', 'Deploy to *{{where}}* failed'); - ``` - - `workplace_edit_post` – whether to create a new post for deploy result, or edit the first one created, default creates a new post: - ``` - set('workplace_edit_post', false); - ``` -## Usage -If you want to notify only about beginning of deployment add this line only: -```php -before('deploy', 'workplace:notify'); -``` -If you want to notify about successful end of deployment add this too: -```php -after('deploy:success', 'workplace:notify:success'); -``` -If you want to notify about failed deployment add this too: -```php -after('deploy:failed', 'workplace:notify:failure'); -``` - - -## Configuration -### workplace_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L71) - -Deploy message - -```php title="Default value" -'_{{user}}_ deploying `{{what}}` to *{{where}}*' -``` - - -### workplace_success_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L72) - - - -```php title="Default value" -'Deploy to *{{where}}* successful' -``` - - -### workplace_failure_text -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L73) - - - -```php title="Default value" -'Deploy to *{{where}}* failed' -``` - - -### workplace_edit_post -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L76) - -By default, create a new post for every message - -```php title="Default value" -false -``` - - - -## Tasks - -### workplace:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L79) - -Notifies Workplace. - - - - -### workplace:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L103) - -Notifies Workplace about deploy finish. - - - - -### workplace:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/workplace.php#L114) - -Notifies Workplace about deploy failure. - - - - diff --git a/docs/contrib/yammer.md b/docs/contrib/yammer.md deleted file mode 100644 index 74456a030..000000000 --- a/docs/contrib/yammer.md +++ /dev/null @@ -1,128 +0,0 @@ - - - - -# Yammer Recipe - -```php -require 'contrib/yammer.php'; -``` - -[Source](/contrib/yammer.php) - - - -Add hook on deploy: -```php -before('deploy', 'yammer:notify'); -``` -## Configuration -- `yammer_url` – The URL to the message endpoint, default is https://www.yammer.com/api/v1/messages.json -- `yammer_token` *(required)* – Yammer auth token -- `yammer_group_id` *(required)* - Group ID -- `yammer_title` – the title of application, default `{{application}}` -- `yammer_body` – notification message template, default: - ``` - {{user}} deploying {{what}} to {{where}} - ``` -- `yammer_success_body` – success template, default: - ``` - Deploy to {{where}} successful - ``` -- `yammer_failure_body` – failure template, default: - ``` - Deploy to {{where}} failed - ``` -## Usage -If you want to notify only about beginning of deployment add this line only: -```php -before('deploy', 'yammer:notify'); -``` -If you want to notify about successful end of deployment add this too: -```php -after('deploy:success', 'yammer:notify:success'); -``` -If you want to notify about failed deployment add this too: -```php -after('deploy:failed', 'yammer:notify:failure'); -``` - - -## Configuration -### yammer_url -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L55) - - - -```php title="Default value" -'https://www.yammer.com/api/v1/messages.json' -``` - - -### yammer_title -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L58) - -Title of project - -```php title="Default value" -return get('application', 'Project'); -``` - - -### yammer_body -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L63) - -Deploy message - -```php title="Default value" -'{{user}} deploying {{what}} to {{where}}' -``` - - -### yammer_success_body -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L64) - - - -```php title="Default value" -'Deploy to {{where}} successful' -``` - - -### yammer_failure_body -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L65) - - - -```php title="Default value" -'Deploy to {{where}} failed' -``` - - - -## Tasks - -### yammer:notify -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L68) - -Notifies Yammer. - - - - -### yammer:notify:success -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L87) - -Notifies Yammer about deploy finish. - - - - -### yammer:notify:failure -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yammer.php#L106) - -Notifies Yammer about deploy failure. - - - - diff --git a/docs/contrib/yarn.md b/docs/contrib/yarn.md deleted file mode 100644 index 5a188b3b5..000000000 --- a/docs/contrib/yarn.md +++ /dev/null @@ -1,49 +0,0 @@ - - - - -# Yarn Recipe - -```php -require 'contrib/yarn.php'; -``` - -[Source](/contrib/yarn.php) - - - -## Configuration -- **bin/yarn** *(optional)*: set Yarn binary, automatically detected otherwise. -## Usage -```php -after('deploy:update_code', 'yarn:install'); -``` - - -## Configuration -### bin/yarn -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yarn.php#L16) - -## Configuration -- **bin/yarn** *(optional)*: set Yarn binary, automatically detected otherwise. -## Usage -```php -after('deploy:update_code', 'yarn:install'); -``` - -```php title="Default value" -return which('yarn'); -``` - - - -## Tasks - -### yarn:install -[Source](https://github.com/deployphp/deployer/blob/master/contrib/yarn.php#L22) - -Installs Yarn packages. - -In there is a {{previous_release}}, node_modules will be copied from it before installing deps with yarn. - - diff --git a/docs/getting-started.md b/docs/getting-started.md deleted file mode 100755 index 3eada0db6..000000000 --- a/docs/getting-started.md +++ /dev/null @@ -1,175 +0,0 @@ -# Getting Started - -In this tutorial we will cover: - -- Setting up a new host with the [provision](recipe/provision.md) recipe. -- Configuring a deployment and perfoming our first deploy. - -First, [install Deployer](installation.md): - -Now lets cd into the project and run the following command: - -```sh -dep init -``` - -Deployer will ask you a few questions, and after finishing you will have a -**deploy.php** or **deploy.yaml** file. This is our deployment recipe. -It contains hosts, tasks and requires other recipes. All framework recipes -that come with Deployer are based on the [common](recipe/common.md) recipe. - -## Provision - -:::note -If you already have a configured webserver you may skip to -[deployment](#deploy). -::: - -Let's create a new VPS on Linode, DigitalOcean, Vultr, AWS, GCP, etc. - -Make sure the image is **Ubuntu 20.04 LTS** as this version is supported by -Deployer's [provision](recipe/provision.md) recipe. - -:::tip -Configure a DNS record for your domain that points to the IP address of your server. -This will allow you to ssh into the server using your domain name instead of the IP address. -::: - -Our **deploy.php** recipe contains a host definition with a few important params: - -- `remote_user` the user name for the ssh connection, -- `deploy_path` the file path on the host where we are going to deploy. - -Let's set `remote_user` to be `deployer`. Right now our new server probably only has the `root` user. The provision recipe will -create and configure a `deployer` user for us. - -```php -host('example.org') - ->set('remote_user', 'deployer') - ->set('deploy_path', '~/example'); -``` - -To connect to the remote host we need to specify an identity key or private key. -We can add our identity key directly into the host definition, but it's better to put it -in the **~/.ssh/config** file: - -``` -Host * - IdentityFile ~/.ssh/id_rsa -``` - -Now let's provision our server. - -```sh -dep provision -``` - -:::tip - -Deployer uses `root` user by default, but you can change it via `-o provision_user=your-user`. - -If your server doesn't have a `root` user but your remote user can use `sudo` to -become root, then use: - -```sh -dep provision -o become=root -``` - -::: - -Deployer will ask you a few questions during provisioning: php version, -database type, etc. Next, Deployer will configure our server and create -the `deployer` user. Provisioning takes around **5 minutes** and will install -everything we need to run a website. A new website will be configured -at [deploy_path](recipe/common.md#deploy_path). - -After we have configured the webserver, let's deploy the project. - -## Deploy - -To deploy the project: - -```sh -dep deploy -``` - -If deploy failed, Deployer will print an error message and which command was unsuccessful. -Most likely we need to configure the correct database credentials in the _.env_ file or similar. - -Ssh to the host, for example, for editing the _.env_ file: - -```sh -dep ssh -``` - -:::tip -If your webserver is using an OpenSSH version older than v7.6, updating the code may fail with the error -message `unsupported option "accept-new".` In this case, override the Git SSH command with: -```php -set('git_ssh_command', 'ssh'); -``` -::: - -After everything is configured properly we can resume our deployment from the -place it stopped. However, this is not required; we can just start a new deploy: - -``` -dep deploy --start-from deploy:migrate -``` - -After our first successful deployment, we can find the following directory structure on our server: - -``` -~/example // The deploy_path. - |- current -> releases/1 // Symlink to the current release. - |- releases // Dir for all releases. - |- 1 // Actual files location. - |- ... - |- .env -> shared/.env // Symlink to shared .env file. - |- shared // Dirs for shared files between releases. - |- ... - |- .env // Example: shared .env file. - |- .dep // Deployer configuration files. -``` - -Configure you webserver to serve the `current` directory. For example, for nginx: - -``` -root /home/deployer/example/current/public; -index index.php; -location / { - try_files $uri $uri/ /index.php?$query_string; -} -``` - -If you're using the [provision recipe](recipe/provision.md), Deployer will automatically configure the Caddy -webserver to serve from the [public_path](/docs/recipe/provision/website.md#public_path). - -Now let's add a build step on our host: - -```php -task('build', function () { - cd('{{release_path}}'); - run('npm install'); - run('npm run prod'); -}); - -after('deploy:update_code', 'build'); -``` - -Deployer has a useful task for examining what is currently deployed. - -``` -$ dep releases -task releases -+---------------------+--------- deployer.org -------+--------+-----------+ -| Date (UTC) | Release | Author | Target | Commit | -+---------------------+-------------+----------------+--------+-----------+ -| 2021-11-05 14:00:22 | 1 (current) | Anton Medvedev | HEAD | 943ded2be | -+---------------------+-------------+----------------+--------+-----------+ -``` - -:::tip -During development, the [dep push](recipe/deploy/push.md) task maybe useful -to create a patch of local changes and push them to the host. -::: diff --git a/docs/hosts.md b/docs/hosts.md deleted file mode 100644 index 921a64906..000000000 --- a/docs/hosts.md +++ /dev/null @@ -1,247 +0,0 @@ -# Hosts - -To define a new host use the [host()](api.md#host) function. Deployer keeps a list of -all defined hosts in the `Deployer::get()->hosts` collection. - -```php -host('example.org'); -``` - -Each host contains it's own configuration key-value pairs. The [host()](api.md#host) -call defines two important configs: **alias** and **hostname**. - -- **hostname** - used when connecting to remote host. -- **alias** - used as a key in `Deployer::get()->hosts` collection. - -```php -task('test', function () { - writeln('The {{alias}} is {{hostname}}'); -}); -``` - -``` -$ dep test -[example.org] The example.org is example.org -``` - -We can override hostname via `set()` method: - -```php -host('example.org') - ->set('hostname', 'example.cloud.google.com'); -``` - -The hostname will be used for the ssh connection, but the host will be referred -by its alias when running Deployer. - -``` -$ dep test -[example.org] The example.org is example.cloud.google.com -``` - -Another important ssh connection parameter is `remote_user`. - -```php -host('example.org') - ->set('hostname', 'example.cloud.google.com') - ->set('remote_user', 'deployer'); -``` - -Now Deployer will connect using something like -`ssh deployer@example.cloud.google.com` to establishing connection. - -Also, Deployer's `Host` class has special setter methods (for better IDE -autocompletion). - -```php -host('example.org') - ->setHostname('example.cloud.google.com') - ->setRemoteUser('deployer'); -``` - -## Host labels - -Hosts can receive labels to identify a subselection of all available hosts. This is a flexible approach to manage and deploy multiple hosts. -The label names and values can be chosen freely. For example, a stage name can be applied: - -```php -host('example.org') - ->setLabels(['stage' => 'prod']) -; - -host('staging.example.org') - ->setLabels(['stage' => 'staging']) -; - -``` -The example above can be simplified without labels, by giving the host prod and staging as name, and using setHostname(...). - -But for for multi server setups, labels become much more powerful: - -```php -host('admin.example.org') - ->setLabels(['stage' => 'prod', 'role' => 'web']) -; - -host('web[1:5].example.org') - ->setLabels(['stage' => 'prod', 'role' => 'web']) -; - -host('db[1:2].example.org') - ->setLabels(['stage' => 'prod', 'role' => 'db']) -; - -host('test.example.org') - ->setLabels(['stage' => 'test', 'role' => 'web']) -; - -host('special.example.org') - ->setLabels(['role' => 'special']) -; -``` - -When calling `dep deploy`, you can filter the hosts to deploy by passing a select string: - -``` -$ dep deploy stage=prod&role=web,role=special -``` - -To check for multiple labels that have to be set on the same host, you can use the `&` operator. -To add another selection, you can use `,` as a separator. - -Also you can configure a default selection string, that is used when running 'dep deploy' without arguments. - -```php -set('default_selector', "stage=prod&role=web,role=special"); -``` - - -## Host config - -### `alias` - -The identifier used to identify a host. -You can use actual hostname or something like `prod` or `staging`. - -### `hostname` - -Deployer uses this config for actual ssh connection. - -### `remote_user` - -Deployer uses this config for actual ssh connection. If not specified, -Deployer will be using `RemoteUser` from **~/.ssh/config** file, or current -OS username. - -### `port` - -Port of remote ssh server to connect to. Default is `22`. - -### `config_file` - -Default is `~/.ssh/config`. - -:::info Config file -For best practices, avoid storing connection parameters in the `deploy.php` file, as -these can vary based on the deployment execution location. Instead, only include the -hostname and remote_user in `deploy.php`, while maintaining other parameters in the -`~/.ssh/config` file. - -``` -Host * - IdentityFile ~/.ssh/id_rsa -``` - -::: - -### `identity_file` - -For example, `~/.ssh/id_rsa`. - -### `forward_agent` - -SSH forwarding is a way to securely tunnel network connections from your local computer to a remote server, and from the remote server to another destination. There are several types of SSH forwarding, including local, remote, and dynamic forwarding. SSH agent forwarding is a specific type of local forwarding that allows you to use your local SSH keys to authenticate on remote servers. This can be useful if you want to use your local SSH keys to connect to a remote server, but don't want to copy your keys to the remote server. - -Default is `true`. - -### `ssh_multiplexing` - -SSH multiplexing is a technique that allows a single Secure Shell (SSH) connection to be used for multiple interactive sessions or for multiple tunneled connections. This can be useful in a number of situations, such as when you want to open multiple terminal sessions to a remote server over a single SSH connection, or when you want to establish multiple secure connections to a remote server but don't want to open multiple SSH connections. - -Default is `true`. - -### `shell` - -Default is `bash -ls`. - -### `deploy_path` - -For example, `~/myapp`. - -### `labels` - -Key-value pairs for host selector. - -### `ssh_arguments` - -For example, `['-o UserKnownHostsFile=/dev/null']` - -### `ssh_control_path` - -Default is `~/.ssh/%C`. - -If **CI** env is present, default value is `/dev/shm/%C`. - -## Multiple hosts - -You can pass multiple hosts to the host function: - -```php -host('example.org', 'deployer.org', ...) - ->setRemoteUser('anton'); -``` - -## Host ranges - -If you have a lot of hosts following similar patterns, you can describe them -like this rather than listing each hostname: - -```php -host('www[01:50].example.org'); -``` - -For numeric patterns, leading zeros can be included or removed, as desired. -Ranges are inclusive. - -You can also define alphabetic ranges: - -```php -host('db[a:f].example.org'); -``` - -## Localhost - -The [localhost()](api.md#localhost) function defines a special local host. -Deployer will not connect to this host, but will execute commands locally instead. - -```php -localhost(); // Alias and hostname will be "localhost". -localhost('ci'); // Alias is "ci", hostname is "localhost". -``` - -## YAML Inventory - -You can use the [import()](api.md#import) function to keep host definitions in a -separate file. For example, _inventory.yaml_. - -```php title="deploy.php" -import('inventory.yaml'); -``` - -```yaml title="inventory.yaml" -hosts: - example.org: - remote_user: deployer - deployer.org: - remote_user: deployer -``` diff --git a/docs/installation.md b/docs/installation.md deleted file mode 100755 index 93e0f7e12..000000000 --- a/docs/installation.md +++ /dev/null @@ -1,57 +0,0 @@ -# Installation - -## Global installation - -To install Deployer, run next command in your project dir: - -``` -composer global require deployer/deployer -``` - -``` -phive install deployer -``` - -Run in your project to create `deploy.php` file: - -``` -dep init -``` - -:::tip Autocomplete - -Deployer comes with autocomplete support for task names, options, and hosts. - -Run the next command to add bash completion support: - -``` -dep completion bash > /etc/bash_completion.d/deployer -``` - -Make sure what your _.bashrc_ file includes generated file in some way. - -::: - -## Project installation - -To install Deployer in your project, run next command in your project dir: - -``` -composer require --dev deployer/deployer -``` - -To initialize deployer in your project run: - -``` -vendor/bin/dep init -``` - -## Phar download - -You can download deployer phar file from [releases](https://github.com/deployphp/deployer/releases) page. - -After downloading, you can run it in your project dir: - -``` -php deployer.phar init -``` diff --git a/docs/recipe/README.md b/docs/recipe/README.md deleted file mode 100644 index e6674e870..000000000 --- a/docs/recipe/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# All Recipes - -* [Cakephp Recipe](/docs/recipe/cakephp.md) -* [Codeigniter 4 Recipe](/docs/recipe/codeigniter4.md) -* [Codeigniter Recipe](/docs/recipe/codeigniter.md) -* [Common Recipe](/docs/recipe/common.md) -* [Composer Recipe](/docs/recipe/composer.md) -* [Contao Recipe](/docs/recipe/contao.md) -* [Craftcms Recipe](/docs/recipe/craftcms.md) -* [Drupal 7 Recipe](/docs/recipe/drupal7.md) -* [Drupal 8 Recipe](/docs/recipe/drupal8.md) -* [Flow Framework Recipe](/docs/recipe/flow_framework.md) -* [Fuelphp Recipe](/docs/recipe/fuelphp.md) -* [Joomla Recipe](/docs/recipe/joomla.md) -* [Laravel Recipe](/docs/recipe/laravel.md) -* [Magento 2 Recipe](/docs/recipe/magento2.md) -* [Magento Recipe](/docs/recipe/magento.md) -* [Pimcore Recipe](/docs/recipe/pimcore.md) -* [Prestashop Recipe](/docs/recipe/prestashop.md) -* [Provision Recipe](/docs/recipe/provision.md) -* [Shopware Recipe](/docs/recipe/shopware.md) -* [Silverstripe Recipe](/docs/recipe/silverstripe.md) -* [Spiral Recipe](/docs/recipe/spiral.md) -* [Statamic Recipe](/docs/recipe/statamic.md) -* [Sulu Recipe](/docs/recipe/sulu.md) -* [Symfony Recipe](/docs/recipe/symfony.md) -* [TYPO3 Recipe](/docs/recipe/typo3.md) -* [WordPress Recipe](/docs/recipe/wordpress.md) -* [Yii2 Recipe](/docs/recipe/yii.md) -* [Zend Framework Recipe](/docs/recipe/zend_framework.md) \ No newline at end of file diff --git a/docs/recipe/cakephp.md b/docs/recipe/cakephp.md deleted file mode 100644 index 9449cdd44..000000000 --- a/docs/recipe/cakephp.md +++ /dev/null @@ -1,118 +0,0 @@ - - - - -# How to Deploy a Cakephp Project - -```php -require 'recipe/cakephp.php'; -``` - -[Source](/recipe/cakephp.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Cakephp application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Cakephp** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [deploy:init](/docs/recipe/cakephp.md#deployinit) – -* [deploy:run_migrations](/docs/recipe/cakephp.md#deployrun_migrations) – -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The cakephp recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/cakephp.php#L14) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -CakePHP 4 Project Template configuration -CakePHP 4 Project Template shared dirs - -```php title="Default value" -[ - 'logs', - 'tmp', -] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/cakephp.php#L20) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - -CakePHP 4 Project Template shared files - -```php title="Default value" -[ - 'config/.env', - 'config/app.php', -] -``` - - - -## Tasks - -### deploy:init -[Source](https://github.com/deployphp/deployer/blob/master/recipe/cakephp.php#L28) - - - -Create plugins' symlinks - - -### deploy:run_migrations -[Source](https://github.com/deployphp/deployer/blob/master/recipe/cakephp.php#L35) - - - -Run migrations - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/cakephp.php#L43) - - - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:init](/docs/recipe/cakephp.md#deployinit) -* [deploy:run_migrations](/docs/recipe/cakephp.md#deployrun_migrations) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/codeigniter.md b/docs/recipe/codeigniter.md deleted file mode 100644 index 4dabb4511..000000000 --- a/docs/recipe/codeigniter.md +++ /dev/null @@ -1,91 +0,0 @@ - - - - -# How to Deploy a Codeigniter Project - -```php -require 'recipe/codeigniter.php'; -``` - -[Source](/recipe/codeigniter.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Codeigniter application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Codeigniter** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The codeigniter recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter.php#L10) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -CodeIgniter shared dirs - -```php title="Default value" -['application/cache', 'application/logs'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter.php#L13) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -CodeIgniter writable dirs - -```php title="Default value" -['application/cache', 'application/logs'] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter.php#L19) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/codeigniter4.md b/docs/recipe/codeigniter4.md deleted file mode 100644 index d9c9febba..000000000 --- a/docs/recipe/codeigniter4.md +++ /dev/null @@ -1,323 +0,0 @@ - - - - -# How to Deploy a Codeigniter 4 Project - -```php -require 'recipe/codeigniter4.php'; -``` - -[Source](/recipe/codeigniter4.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Codeigniter 4 application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Codeigniter 4** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [spark:optimize](/docs/recipe/codeigniter4.md#sparkoptimize) – Optimize for production. -* [spark:migrate](/docs/recipe/codeigniter4.md#sparkmigrate) – Locates and runs all new migrations against the database. -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The codeigniter4 recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### public_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L10) - -Overrides [public_path](/docs/recipe/provision/website.md#public_path) from `recipe/provision/website.php`. - -Default Configurations - -```php title="Default value" -'public' -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L12) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['writable'] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L14) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['.env'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L16) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -[ - 'writable/cache', - 'writable/debugbar', - 'writable/logs', - 'writable/session', - 'writable/uploads', -] -``` - - -### log_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L24) - - - -```php title="Default value" -'writable/logs/*.log' -``` - - -### codeigniter4_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L26) - - - -```php title="Default value" -$result = run('{{bin/php}} {{release_or_current_path}}/spark'); -preg_match_all('/(\d+\.?)+/', $result, $matches); -return $matches[0][0] ?? 5.5; -``` - - - -## Tasks - -### spark:cache:info -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L94) - -Shows file cache information in the current system. - -Discover & Checks - - -### spark:config:check -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L97) - -Check your Config values. - - - - -### spark:env -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L100) - -Retrieves the current environment, or set a new one. - - - - -### spark:filter:check -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L103) - -Check filters for a route. - - - - -### spark:lang:find -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L106) - -Find and save available phrases to translate. - - - - -### spark:namespaces -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L109) - -Verifies your namespaces are setup correctly. - - - - -### spark:phpini:check -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L112) - -Check your php.ini values. - - - - -### spark:routes -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L115) - -Displays all routes. - - - - -### spark:​key:generate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L123) - -Generates a new encryption key and writes it in an `.env` file. - -Actions - - -### spark:optimize -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L126) - -Optimize for production. - - - - -### spark:publish -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L129) - -Discovers and executes all predefined Publisher classes. - - - - -### spark:db:create -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L137) - -Create a new database schema. - -Database and migrations. - - -### spark:db:seed -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L140) - -Runs the specified seeder to populate known data into the database. - - - - -### spark:db:table -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L143) - -Retrieves information on the selected table. - - - - -### spark:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L146) - -Locates and runs all new migrations against the database. - - - - -### spark:migrate:refresh -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L149) - -Does a rollback followed by a latest to refresh the current state of the database. - - - - -### spark:migrate:rollback -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L152) - -Runs the "down" method for all migrations in the last batch. - - - - -### spark:migrate:status -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L155) - -Displays a list of all migrations and whether they\'ve been run or not. - - - - -### spark:cache:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L163) - -Clears the current system caches. - -Housekeeping - - -### spark:debugbar:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L166) - -Clears all debugbar JSON files. - - - - -### spark:logs:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L169) - -Clears all log files. - - - - -### spark:custom -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L176) - -Run a custom spark command. - -Custom Spark Command for shield or setting packages - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/codeigniter4.php#L184) - -Deploys your project. - -Main deploy task. - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [spark:optimize](/docs/recipe/codeigniter4.md#sparkoptimize) -* [spark:migrate](/docs/recipe/codeigniter4.md#sparkmigrate) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/common.md b/docs/recipe/common.md deleted file mode 100644 index 4855723d2..000000000 --- a/docs/recipe/common.md +++ /dev/null @@ -1,266 +0,0 @@ - - - - -# Common Recipe - -```php -require 'recipe/common.php'; -``` - -[Source](/recipe/common.php) - -* Requires - * [provision](/docs/recipe/provision.md) - * [check_remote](/docs/recipe/deploy/check_remote.md) - * [cleanup](/docs/recipe/deploy/cleanup.md) - * [clear_paths](/docs/recipe/deploy/clear_paths.md) - * [copy_dirs](/docs/recipe/deploy/copy_dirs.md) - * [env](/docs/recipe/deploy/env.md) - * [info](/docs/recipe/deploy/info.md) - * [lock](/docs/recipe/deploy/lock.md) - * [push](/docs/recipe/deploy/push.md) - * [release](/docs/recipe/deploy/release.md) - * [rollback](/docs/recipe/deploy/rollback.md) - * [setup](/docs/recipe/deploy/setup.md) - * [shared](/docs/recipe/deploy/shared.md) - * [symlink](/docs/recipe/deploy/symlink.md) - * [update_code](/docs/recipe/deploy/update_code.md) - * [vendors](/docs/recipe/deploy/vendors.md) - * [writable](/docs/recipe/deploy/writable.md) - -## Configuration -### user -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L31) - -Name of current user who is running deploy. -If not set will try automatically get git user name, -otherwise output of `whoami` command. -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### keep_releases -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L48) - -Number of releases to preserve in releases folder. - -```php title="Default value" -10 -``` - - -### repository -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L51) - -Repository to deploy. - - - -### default_timeout -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L56) - -Default timeout for `run()` and `runLocally()` functions. - -Set to `null` to disable timeout. - -```php title="Default value" -300 -``` - - -### env -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L72) - -Remote environment variables. -```php -set('env', [ - 'KEY' => 'something', -]); -``` - -It is possible to override it per `run()` call. - -```php -run('echo $KEY', env: ['KEY' => 'over']); -``` - - - -### dotenv -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L81) - -Path to `.env` file which will be used as environment variables for each command per `run()`. - -```php -set('dotenv', '{{current_path}}/.env'); -``` - -```php title="Default value" -false -``` - - -### deploy_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L91) - -The deploy path. - -For example can be set for a bunch of host once as: -```php -set('deploy_path', '~/{{alias}}'); -``` -:::info Required -Throws exception if not set. -::: - - - - -### current_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L101) - -Return current release path. Default to [deploy_path](/docs/recipe/common.md#deploy_path)/`current`. -```php -set('current_path', '/var/public_html'); -``` - -```php title="Default value" -'{{deploy_path}}/current' -``` - - -### bin/php -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L104) - -Path to the `php` bin. - -```php title="Default value" -if (currentHost()->hasOwn('php_version')) { -return '/usr/bin/php{{php_version}}'; -} -return which('php'); -``` - - -### bin/git -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L112) - -Path to the `git` bin. - -```php title="Default value" -return which('git'); -``` - - -### use_relative_symlink -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L118) - -Should [bin/symlink](/docs/recipe/common.md#bin/symlink) use `--relative` option or not. Will detect -automatically. - -```php title="Default value" -return commandSupportsOption('ln', '--relative'); -``` - - -### bin/symlink -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L123) - -Path to the `ln` bin. With predefined options `-nfs`. - -```php title="Default value" -return get('use_relative_symlink') ? 'ln -nfs --relative' : 'ln -nfs'; -``` - - -### sudo_askpass -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L130) - -Path to a file which will store temp script with sudo password. -Defaults to `.dep/sudo_pass`. This script is only temporary and will be deleted after -sudo command executed. -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - - -## Tasks - -### deploy:prepare -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L139) - -Prepares a new release. - - - - -This task is group task which contains next tasks: -* [deploy:info](/docs/recipe/deploy/info.md#deployinfo) -* [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) -* [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) -* [deploy:release](/docs/recipe/deploy/release.md#deployrelease) -* [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) -* [deploy:env](/docs/recipe/deploy/env.md#deployenv) -* [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) -* [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) - - -### deploy:publish -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L151) - -Publishes the release. - - - - -This task is group task which contains next tasks: -* [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) -* [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) -* [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) -* [deploy:success](/docs/recipe/common.md#deploysuccess) - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L159) - -Deploys your project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - -### deploy:success -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L168) - -Deploys your project. - -Prints success message - - -### deploy:failed -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L177) - - - -Hook on deploy failure. - - -### logs:app -[Source](https://github.com/deployphp/deployer/blob/master/recipe/common.php#L186) - -Shows application logs. - -Follows latest application logs. - - diff --git a/docs/recipe/composer.md b/docs/recipe/composer.md deleted file mode 100644 index ce20773f8..000000000 --- a/docs/recipe/composer.md +++ /dev/null @@ -1,32 +0,0 @@ - - - - -# Composer Recipe - -```php -require 'recipe/composer.php'; -``` - -[Source](/recipe/composer.php) - -* Requires - * [common](/docs/recipe/common.md) - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/composer.php#L10) - -Deploys your project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/contao.md b/docs/recipe/contao.md deleted file mode 100644 index 964553c04..000000000 --- a/docs/recipe/contao.md +++ /dev/null @@ -1,183 +0,0 @@ - - - - -# How to Deploy a Contao Project - -```php -require 'recipe/contao.php'; -``` - -[Source](/recipe/contao.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Contao application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Contao** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [contao:maintenance:enable](/docs/recipe/contao.md#contaomaintenanceenable) – Enable maintenance mode -* [contao:migrate](/docs/recipe/contao.md#contaomigrate) – Run Contao migrations -* [contao:maintenance:disable](/docs/recipe/contao.md#contaomaintenancedisable) – Disable maintenance mode -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The contao recipe is based on the [symfony](/docs/recipe/symfony.md) recipe. - -## Configuration -### public_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L12) - -Overrides [public_path](/docs/recipe/provision/website.md#public_path) from `recipe/provision/website.php`. - -The public path is the path to be set as DocumentRoot and is defined in the `composer.json` of the project -but defaults to `public` from Contao 5.0 on. -This path is relative from the [current_path](/docs/recipe/common.md#current_path), see [`recipe/provision/website.php`](/docs/recipe/provision/website.php#public_path). - -```php title="Default value" -$composerConfig = json_decode(file_get_contents('./composer.json'), true, 512, JSON_THROW_ON_ERROR); - -return $composerConfig['extra']['public-dir'] ?? 'public'; -``` - - -### bin/console -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L30) - -Overrides [bin/console](/docs/recipe/symfony.md#bin/console) from `recipe/symfony.php`. - - - -```php title="Default value" -return '{{bin/php}} {{release_or_current_path}}/vendor/bin/contao-console'; -``` - - -### contao_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L34) - - - -```php title="Default value" -$result = run('{{bin/console}} --version'); -preg_match_all('/(\d+\.?)+/', $result, $matches); -return $matches[0][0] ?? 'n/a'; -``` - - -### symfony_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L40) - -Overrides [symfony_version](/docs/recipe/symfony.md#symfony_version) from `recipe/symfony.php`. - - - -```php title="Default value" -$result = run('{{bin/console}} about'); -preg_match_all('/(\d+\.?)+/', $result, $matches); -return $matches[0][0] ?? 5.0; -``` - - - -## Tasks - -### contao:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L56) - -Run Contao migrations. - -This task updates the database. A database backup is saved automatically as a default. - -To automatically drop the obsolete database structures, you can override the task as follows: - -```php -task('contao:migrate', function () { - run('{{bin/php}} {{bin/console}} contao:migrate --with-deletes {{console_options}}'); -}); -``` - - -### contao:manager:download -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L62) - -Download the Contao Manager. - -Downloads the `contao-manager.phar.php` into the public path. - - -### contao:install:lock -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L68) - -Lock the Contao Install Tool. - -Locks the Contao install tool which is useful if you don't use it. - - -### contao:manager:lock -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L74) - -Lock the Contao Manager. - -Locks the Contao Manager which is useful if you only need the API of the Manager rather than the UI. - - -### contao:maintenance:enable -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L80) - -Enable maintenance mode. - - - - -### contao:maintenance:disable -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L95) - -Disable maintenance mode. - - - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/contao.php#L107) - -Deploy the project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [contao:maintenance:enable](/docs/recipe/contao.md#contaomaintenanceenable) -* [contao:migrate](/docs/recipe/contao.md#contaomigrate) -* [contao:maintenance:disable](/docs/recipe/contao.md#contaomaintenancedisable) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/craftcms.md b/docs/recipe/craftcms.md deleted file mode 100644 index 6a819d802..000000000 --- a/docs/recipe/craftcms.md +++ /dev/null @@ -1,123 +0,0 @@ - - - - -# How to Deploy a Craftcms Project - -```php -require 'recipe/craftcms.php'; -``` - -[Source](/recipe/craftcms.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Craftcms application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Craftcms** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors - - -The craftcms recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### log_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/craftcms.php#L9) - - - -```php title="Default value" -'storage/logs/*.log' -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/craftcms.php#L11) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -[ - 'storage', - 'web/assets', -] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/craftcms.php#L16) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['.env'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/craftcms.php#L18) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -[ - 'config/project', - 'storage', - 'web/assets', - 'web/cpresources', -] -``` - - - -## Tasks - -### craft:gc -[Source](https://github.com/deployphp/deployer/blob/master/recipe/craftcms.php#L120) - -Runs garbage collection. - -Garbage collection - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/craftcms.php#L127) - -Deploys Craft CMS. - -Main deploy - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) - - diff --git a/docs/recipe/deploy/check_remote.md b/docs/recipe/deploy/check_remote.md deleted file mode 100644 index b8e9e67a9..000000000 --- a/docs/recipe/deploy/check_remote.md +++ /dev/null @@ -1,25 +0,0 @@ - - - - -# Check Remote Recipe - -```php -require 'recipe/deploy/check_remote.php'; -``` - -[Source](/recipe/deploy/check_remote.php) - - - -## Tasks - -### deploy:check_remote -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/check_remote.php#L11) - -Checks remote head. - -Cancel deployment if there would be no change to the codebase. -This avoids unnecessary releases if the latest commit has already been deployed. - - diff --git a/docs/recipe/deploy/cleanup.md b/docs/recipe/deploy/cleanup.md deleted file mode 100644 index 7de0ab598..000000000 --- a/docs/recipe/deploy/cleanup.md +++ /dev/null @@ -1,35 +0,0 @@ - - - - -# Cleanup Recipe - -```php -require 'recipe/deploy/cleanup.php'; -``` - -[Source](/recipe/deploy/cleanup.php) - - -## Configuration -### cleanup_use_sudo -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/cleanup.php#L6) - -Use sudo in deploy:cleanup task for rm command. - -```php title="Default value" -false -``` - - - -## Tasks - -### deploy:cleanup -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/cleanup.php#L9) - -Cleanup old releases. - - - - diff --git a/docs/recipe/deploy/clear_paths.md b/docs/recipe/deploy/clear_paths.md deleted file mode 100644 index 111e2dd64..000000000 --- a/docs/recipe/deploy/clear_paths.md +++ /dev/null @@ -1,42 +0,0 @@ - - - - -# Clear Paths Recipe - -```php -require 'recipe/deploy/clear_paths.php'; -``` - -[Source](/recipe/deploy/clear_paths.php) - - -## Configuration -### clear_paths -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/clear_paths.php#L6) - -List of paths to remove from [release_path](/docs/recipe/deploy/release.md#release_path). - - - -### clear_use_sudo -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/clear_paths.php#L9) - -Use sudo for deploy:clear_path task? - -```php title="Default value" -false -``` - - - -## Tasks - -### deploy:clear_paths -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/clear_paths.php#L12) - -Cleanup files and/or directories. - - - - diff --git a/docs/recipe/deploy/copy_dirs.md b/docs/recipe/deploy/copy_dirs.md deleted file mode 100644 index 12b27b8bb..000000000 --- a/docs/recipe/deploy/copy_dirs.md +++ /dev/null @@ -1,33 +0,0 @@ - - - - -# Copy Dirs Recipe - -```php -require 'recipe/deploy/copy_dirs.php'; -``` - -[Source](/recipe/deploy/copy_dirs.php) - - -## Configuration -### copy_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/copy_dirs.php#L7) - -List of dirs to copy between releases. -For example you can copy `node_modules` to speedup npm install. - - - - -## Tasks - -### deploy:copy_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/copy_dirs.php#L10) - -Copies directories. - - - - diff --git a/docs/recipe/deploy/env.md b/docs/recipe/deploy/env.md deleted file mode 100644 index 17e13ed93..000000000 --- a/docs/recipe/deploy/env.md +++ /dev/null @@ -1,24 +0,0 @@ - - - - -# Env Recipe - -```php -require 'recipe/deploy/env.php'; -``` - -[Source](/recipe/deploy/env.php) - - - -## Tasks - -### deploy:env -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/env.php#L6) - -Configure .env file. - - - - diff --git a/docs/recipe/deploy/info.md b/docs/recipe/deploy/info.md deleted file mode 100644 index 432a1d428..000000000 --- a/docs/recipe/deploy/info.md +++ /dev/null @@ -1,52 +0,0 @@ - - - - -# Info Recipe - -```php -require 'recipe/deploy/info.php'; -``` - -[Source](/recipe/deploy/info.php) - - -## Configuration -### what -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/info.php#L8) - -Defines "what" text for the 'deploy:info' task. -Uses one of the following sources: -1. Repository name -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### where -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/info.php#L20) - -Defines "where" text for the 'deploy:info' task. -Uses one of the following sources: -1. Host's stage label -2. Host's alias -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - - -## Tasks - -### deploy:info -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/info.php#L29) - -Displays info about deployment. - - - - diff --git a/docs/recipe/deploy/lock.md b/docs/recipe/deploy/lock.md deleted file mode 100644 index 0b5ee9b40..000000000 --- a/docs/recipe/deploy/lock.md +++ /dev/null @@ -1,40 +0,0 @@ - - - - -# Lock Recipe - -```php -require 'recipe/deploy/lock.php'; -``` - -[Source](/recipe/deploy/lock.php) - - - -## Tasks - -### deploy:lock -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/lock.php#L8) - -Locks deploy. - - - - -### deploy:unlock -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/lock.php#L21) - -Unlocks deploy. - - - - -### deploy:is_locked -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/lock.php#L26) - -Checks if deploy is locked. - - - - diff --git a/docs/recipe/deploy/push.md b/docs/recipe/deploy/push.md deleted file mode 100644 index 20e2f2d34..000000000 --- a/docs/recipe/deploy/push.md +++ /dev/null @@ -1,26 +0,0 @@ - - - - -# Push Recipe - -```php -require 'recipe/deploy/push.php'; -``` - -[Source](/recipe/deploy/push.php) - - - -## Tasks - -### push -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/push.php#L9) - -Pushes local changes to remote host. - -Creates patch of local changes and pushes them on host. -And applies to current_path. Push can be done many times. -The task purpose to be used only for development. - - diff --git a/docs/recipe/deploy/release.md b/docs/recipe/deploy/release.md deleted file mode 100644 index 792d3d2d2..000000000 --- a/docs/recipe/deploy/release.md +++ /dev/null @@ -1,111 +0,0 @@ - - - - -# Release Recipe - -```php -require 'recipe/deploy/release.php'; -``` - -[Source](/recipe/deploy/release.php) - - -## Configuration -### release_name -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L11) - -The name of the release. - -```php title="Default value" -return within('{{deploy_path}}', function () { -$latest = run('cat .dep/latest_release || echo 0'); -return strval(intval($latest) + 1); -}); -``` - - -### releases_log -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L19) - -Holds releases log from `.dep/releases_log` file. -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### releases_list -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L34) - -Return list of release names on host. -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### release_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L61) - -Return release path. -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### release_revision -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L72) - -Current release revision. Usually a git hash. - -```php title="Default value" -return run('cat {{release_path}}/REVISION'); -``` - - -### release_or_current_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L78) - -Return the release path during a deployment -but fallback to the current path otherwise. - -```php title="Default value" -$releaseExists = test('[ -h {{deploy_path}}/release ]'); -return $releaseExists ? get('release_path') : get('current_path'); -``` - - - -## Tasks - -### deploy:release -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L85) - -Prepares release. - -Clean up unfinished releases and prepare next release - - -### releases -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/release.php#L160) - -Shows releases list. - -Example output: -``` -+---------------------+------example.org ------------+--------+-----------+ -| Date (UTC) | Release | Author | Target | Commit | -+---------------------+-------------+----------------+--------+-----------+ -| 2021-11-06 20:51:45 | 1 | Anton Medvedev | HEAD | 34d24192e | -| 2021-11-06 21:00:50 | 2 (bad) | Anton Medvedev | HEAD | 392948a40 | -| 2021-11-06 23:19:20 | 3 | Anton Medvedev | HEAD | a4057a36c | -| 2021-11-06 23:24:30 | 4 (current) | Anton Medvedev | HEAD | s3wa45ca6 | -+---------------------+-------------+----------------+--------+-----------+ -``` - - diff --git a/docs/recipe/deploy/rollback.md b/docs/recipe/deploy/rollback.md deleted file mode 100644 index 1348b7247..000000000 --- a/docs/recipe/deploy/rollback.md +++ /dev/null @@ -1,54 +0,0 @@ - - - - -# Rollback Recipe - -```php -require 'recipe/deploy/rollback.php'; -``` - -[Source](/recipe/deploy/rollback.php) - - -## Configuration -### rollback_candidate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/rollback.php#L20) - -Rollback candidate will be automatically chosen by looking -at output of `ls` command and content of `.dep/releases_log`. - -If rollback candidate is marked as **BAD_RELEASE**, it will be skipped. - -:::tip -You can override rollback candidate via: -``` -dep rollback -o rollback_candidate=123 -``` -::: -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - - -## Tasks - -### rollback -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/rollback.php#L63) - -Rollbacks to the previous release. - -Uses [rollback_candidate](/docs/recipe/deploy/rollback.md#rollback_candidate) for symlinking. Current release will be marked as -bad by creating file **BAD_RELEASE** with timestamp and [user](/docs/recipe/common.md#user). - -:::warning -You can always manually symlink [current_path](/docs/recipe/common.md#current_path) to proper release. -``` -dep run '{{bin/symlink}} releases/123 {{current_path}}' -``` -::: - - diff --git a/docs/recipe/deploy/setup.md b/docs/recipe/deploy/setup.md deleted file mode 100644 index b5778d4cf..000000000 --- a/docs/recipe/deploy/setup.md +++ /dev/null @@ -1,24 +0,0 @@ - - - - -# Setup Recipe - -```php -require 'recipe/deploy/setup.php'; -``` - -[Source](/recipe/deploy/setup.php) - - - -## Tasks - -### deploy:setup -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/setup.php#L6) - -Prepares host for deploy. - - - - diff --git a/docs/recipe/deploy/shared.md b/docs/recipe/deploy/shared.md deleted file mode 100644 index 1bd38f0be..000000000 --- a/docs/recipe/deploy/shared.md +++ /dev/null @@ -1,47 +0,0 @@ - - - - -# Shared Recipe - -```php -require 'recipe/deploy/shared.php'; -``` - -[Source](/recipe/deploy/shared.php) - - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/shared.php#L13) - -List of dirs what will be shared between releases. -Each release will have symlink to those dirs stored in [deploy_path](/docs/recipe/common.md#deploy_path)/shared dir. -```php -set('shared_dirs', ['storage']); -``` - - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/shared.php#L20) - -List of files what will be shared between releases. -Each release will have symlink to those files stored in [deploy_path](/docs/recipe/common.md#deploy_path)/shared dir. -```php -set('shared_files', ['.env']); -``` - - - - -## Tasks - -### deploy:shared -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/shared.php#L23) - -Creates symlinks for shared files and dirs. - - - - diff --git a/docs/recipe/deploy/symlink.md b/docs/recipe/deploy/symlink.md deleted file mode 100644 index 3366e6bc6..000000000 --- a/docs/recipe/deploy/symlink.md +++ /dev/null @@ -1,35 +0,0 @@ - - - - -# Symlink Recipe - -```php -require 'recipe/deploy/symlink.php'; -``` - -[Source](/recipe/deploy/symlink.php) - - -## Configuration -### use_atomic_symlink -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/symlink.php#L6) - -Use mv -T if available. Will check automatically. - -```php title="Default value" -return commandSupportsOption('mv', '--no-target-directory'); -``` - - - -## Tasks - -### deploy:symlink -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/symlink.php#L11) - -Creates symlink to release. - - - - diff --git a/docs/recipe/deploy/update_code.md b/docs/recipe/deploy/update_code.md deleted file mode 100644 index 90dcd0e65..000000000 --- a/docs/recipe/deploy/update_code.md +++ /dev/null @@ -1,90 +0,0 @@ - - - - -# Update Code Recipe - -```php -require 'recipe/deploy/update_code.php'; -``` - -[Source](/recipe/deploy/update_code.php) - - -## Configuration -### branch -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/update_code.php#L12) - -Determines which branch to deploy. Can be overridden with CLI option `--branch`. -If not specified, will get current git HEAD branch as default branch to deploy. - -```php title="Default value" -'HEAD' -``` - - -### target -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/update_code.php#L19) - -The deploy target: a branch, a tag or a revision. -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### update_code_strategy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/update_code.php#L48) - -Sets deploy:update_code strategy. -Can be one of: -- archive -- clone (if you need the origin repository `.git` dir in your [release_path](/docs/recipe/deploy/release.md#release_path)) - -```php title="Default value" -'archive' -``` - - -### git_ssh_command -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/update_code.php#L54) - -Sets environment variable _GIT_SSH_COMMAND_ for `git clone` command. -If `StrictHostKeyChecking` flag is set to `accept-new` then ssh will -automatically add new host keys to the user known hosts files, but -will not permit connections to hosts with changed host keys. - -```php title="Default value" -'ssh -o StrictHostKeyChecking=accept-new' -``` - - -### sub_directory -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/update_code.php#L66) - -Specifies a sub directory within the repository to deploy. -Works only when [`update_code_strategy`](#update_code_strategy) is set to `archive` (default). - -Example: - - set value to `src` if you want to deploy the folder that lives at `/src`. - - set value to `src/api` if you want to deploy the folder that lives at `/src/api`. - -Note: do not use a leading `/`! - -```php title="Default value" -false -``` - - - -## Tasks - -### deploy:update_code -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/update_code.php#L72) - -Updates code. - -Update code at [release_path](/docs/recipe/deploy/release.md#release_path) on host. - - diff --git a/docs/recipe/deploy/vendors.md b/docs/recipe/deploy/vendors.md deleted file mode 100644 index 98a0d4966..000000000 --- a/docs/recipe/deploy/vendors.md +++ /dev/null @@ -1,58 +0,0 @@ - - - - -# Vendors Recipe - -```php -require 'recipe/deploy/vendors.php'; -``` - -[Source](/recipe/deploy/vendors.php) - - -## Configuration -### composer_action -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/vendors.php#L5) - - - -```php title="Default value" -'install' -``` - - -### composer_options -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/vendors.php#L7) - - - -```php title="Default value" -'--verbose --prefer-dist --no-progress --no-interaction --no-dev --optimize-autoloader' -``` - - -### bin/composer -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/vendors.php#L12) - -Returns Composer binary path in found. Otherwise try to install latest -composer version to `.dep/composer.phar`. To use specific composer version -download desired phar and place it at `.dep/composer.phar`. -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - - -## Tasks - -### deploy:vendors -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/vendors.php#L28) - -Installs vendors. - - - - diff --git a/docs/recipe/deploy/writable.md b/docs/recipe/deploy/writable.md deleted file mode 100644 index adc841206..000000000 --- a/docs/recipe/deploy/writable.md +++ /dev/null @@ -1,104 +0,0 @@ - - - - -# Writable Recipe - -```php -require 'recipe/deploy/writable.php'; -``` - -[Source](/recipe/deploy/writable.php) - - -## Configuration -### http_user -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L9) - -Used to make a writable directory by a server. -Used in `chown` and `acl` modes of [writable_mode](/docs/recipe/deploy/writable.md#writable_mode). -Attempts automatically to detect http user in process list. -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### http_group -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L26) - -Used to make a writable directory by a server. -Used in `chgrp` mode of [writable_mode](/docs/recipe/deploy/writable.md#writable_mode) only. -Attempts automatically to detect http user in process list. -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L41) - -List of writable dirs. - - - -### writable_mode -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L50) - -One of: -- chown -- chgrp -- chmod -- acl -- sticky -- skip - -```php title="Default value" -'acl' -``` - - -### writable_use_sudo -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L53) - -Using sudo in writable commands? - -```php title="Default value" -false -``` - - -### writable_recursive -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L56) - -Use recursive mode (-R)? - -```php title="Default value" -false -``` - - -### writable_chmod_mode -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L59) - -The chmod mode. - -```php title="Default value" -'0755' -``` - - - -## Tasks - -### deploy:writable -[Source](https://github.com/deployphp/deployer/blob/master/recipe/deploy/writable.php#L62) - -Makes writable dirs. - - - - diff --git a/docs/recipe/drupal7.md b/docs/recipe/drupal7.md deleted file mode 100644 index 375069e3b..000000000 --- a/docs/recipe/drupal7.md +++ /dev/null @@ -1,133 +0,0 @@ - - - - -# How to Deploy a Drupal 7 Project - -```php -require 'recipe/drupal7.php'; -``` - -[Source](/recipe/drupal7.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Drupal 7 application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Drupal 7** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The drupal7 recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### drupal_site -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L15) - -Set Drupal 7 site. Change if you use different site - -```php title="Default value" -'default' -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L18) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Drupal 7 shared dirs - -```php title="Default value" -[ - 'sites/{{drupal_site}}/files', -] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L23) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - -Drupal 7 shared files - -```php title="Default value" -[ - 'sites/{{drupal_site}}/settings.php', -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L28) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -Drupal 7 writable dirs - -```php title="Default value" -[ - 'sites/{{drupal_site}}/files', -] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L9) - - - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - -### drupal:settings -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L34) - - - -Create and upload Drupal 7 settings.php using values from secrets - - -### drupal:upload_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal7.php#L76) - - - -Upload Drupal 7 files folder - - diff --git a/docs/recipe/drupal8.md b/docs/recipe/drupal8.md deleted file mode 100644 index e49c4aa31..000000000 --- a/docs/recipe/drupal8.md +++ /dev/null @@ -1,118 +0,0 @@ - - - - -# How to Deploy a Drupal 8 Project - -```php -require 'recipe/drupal8.php'; -``` - -[Source](/recipe/drupal8.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Drupal 8 application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Drupal 8** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The drupal8 recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### drupal_site -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal8.php#L15) - -Set drupal site. Change if you use different site - -```php title="Default value" -'default' -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal8.php#L19) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Drupal 8 shared dirs - -```php title="Default value" -[ - 'sites/{{drupal_site}}/files', -] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal8.php#L24) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - -Drupal 8 shared files - -```php title="Default value" -[ - 'sites/{{drupal_site}}/settings.php', - 'sites/{{drupal_site}}/services.yml', -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal8.php#L30) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -Drupal 8 Writable dirs - -```php title="Default value" -[ - 'sites/{{drupal_site}}/files', -] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/drupal8.php#L9) - - - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/flow_framework.md b/docs/recipe/flow_framework.md deleted file mode 100644 index 491e15d25..000000000 --- a/docs/recipe/flow_framework.md +++ /dev/null @@ -1,123 +0,0 @@ - - - - -# How to Deploy a Flow Framework Project - -```php -require 'recipe/flow_framework.php'; -``` - -[Source](/recipe/flow_framework.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Flow Framework application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Flow Framework** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [deploy:run_migrations](/docs/recipe/flow_framework.md#deployrun_migrations) – Applies database migrations -* [deploy:publish_resources](/docs/recipe/flow_framework.md#deploypublish_resources) – Publishes resources -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The flow_framework recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### flow_context -[Source](https://github.com/deployphp/deployer/blob/master/recipe/flow_framework.php#L10) - -Flow-Framework application-context - -```php title="Default value" -'Production' -``` - - -### flow_command -[Source](https://github.com/deployphp/deployer/blob/master/recipe/flow_framework.php#L13) - -Flow-Framework cli-command - -```php title="Default value" -'flow' -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/flow_framework.php#L16) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Flow-Framework shared directories - -```php title="Default value" -[ - 'Data/Persistent', - 'Data/Logs', - 'Configuration/{{flow_context}}', -] -``` - - - -## Tasks - -### deploy:run_migrations -[Source](https://github.com/deployphp/deployer/blob/master/recipe/flow_framework.php#L26) - -Applies database migrations. - -Apply database migrations - - -### deploy:publish_resources -[Source](https://github.com/deployphp/deployer/blob/master/recipe/flow_framework.php#L34) - -Publishes resources. - -Publish resources - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/flow_framework.php#L42) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:run_migrations](/docs/recipe/flow_framework.md#deployrun_migrations) -* [deploy:publish_resources](/docs/recipe/flow_framework.md#deploypublish_resources) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/fuelphp.md b/docs/recipe/fuelphp.md deleted file mode 100644 index c69e3ded3..000000000 --- a/docs/recipe/fuelphp.md +++ /dev/null @@ -1,81 +0,0 @@ - - - - -# How to Deploy a Fuelphp Project - -```php -require 'recipe/fuelphp.php'; -``` - -[Source](/recipe/fuelphp.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Fuelphp application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Fuelphp** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The fuelphp recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/fuelphp.php#L10) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -FuelPHP 1.x shared dirs - -```php title="Default value" -[ - 'fuel/app/cache', 'fuel/app/logs', -] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/fuelphp.php#L18) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/joomla.md b/docs/recipe/joomla.md deleted file mode 100644 index c88529cbb..000000000 --- a/docs/recipe/joomla.md +++ /dev/null @@ -1,101 +0,0 @@ - - - - -# How to Deploy a Joomla Project - -```php -require 'recipe/joomla.php'; -``` - -[Source](/recipe/joomla.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Joomla application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Joomla** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The joomla recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/joomla.php#L9) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['configuration.php'] -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/joomla.php#L10) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['images'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/joomla.php#L11) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -['images'] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/joomla.php#L14) - -Deploys your project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/laravel.md b/docs/recipe/laravel.md deleted file mode 100644 index 949e6b5d1..000000000 --- a/docs/recipe/laravel.md +++ /dev/null @@ -1,554 +0,0 @@ - - - - -# How to Deploy a Laravel Project - -```php -require 'recipe/laravel.php'; -``` - -[Source](/recipe/laravel.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Laravel application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Laravel** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [artisan:create_key](/docs/recipe/laravel.md#artisancreate_key) – Generates the application key for new deployments -* [artisan:storage:link](/docs/recipe/laravel.md#artisanstoragelink) – Creates the symbolic links configured for the application -* [artisan:config:cache](/docs/recipe/laravel.md#artisanconfigcache) – Creates a cache file for faster configuration loading -* [artisan:route:cache](/docs/recipe/laravel.md#artisanroutecache) – Creates a route cache file for faster route registration -* [artisan:view:cache](/docs/recipe/laravel.md#artisanviewcache) – Compiles all of the application\'s Blade templates -* [artisan:event:cache](/docs/recipe/laravel.md#artisaneventcache) – Discovers and cache the application\'s events and listeners -* [artisan:migrate](/docs/recipe/laravel.md#artisanmigrate) – Runs the database migrations -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The laravel recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L9) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['storage'] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L10) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['.env'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L11) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -[ - 'bootstrap/cache', - 'storage', - 'storage/app', - 'storage/app/public', - 'storage/framework', - 'storage/framework/cache', - 'storage/framework/cache/data', - 'storage/framework/sessions', - 'storage/framework/views', - 'storage/logs', -] -``` - - -### log_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L23) - - - -```php title="Default value" -'storage/logs/*.log' -``` - - -### laravel_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L24) - - - -```php title="Default value" -$result = run('{{bin/php}} {{release_or_current_path}}/artisan --version'); -preg_match_all('/(\d+\.?)+/', $result, $matches); -return $matches[0][0] ?? 5.5; -``` - - -### public_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L29) - -Overrides [public_path](/docs/recipe/provision/website.md#public_path) from `recipe/provision/website.php`. - - - -```php title="Default value" -'public' -``` - - - -## Tasks - -### artisan:down -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L92) - -Puts the application into maintenance / demo mode. - -Maintenance mode. - - -### artisan:up -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L95) - -Brings the application out of maintenance mode. - - - - -### artisan:​key:generate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L102) - -Sets the application key. - -Generate keys. - - -### artisan:create_key -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L105) - -Generates the application key for new deployments. - - - - -### artisan:passport:keys -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L112) - -Creates the encryption keys for API authentication. - - - - -### artisan:db:seed -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L119) - -Seeds the database with records. - -Database and migrations. - - -### artisan:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L122) - -Runs the database migrations. - - - - -### artisan:migrate:fresh -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L125) - -Drops all tables and re-run all migrations. - - - - -### artisan:migrate:rollback -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L128) - -Rollbacks the last database migration. - - - - -### artisan:migrate:status -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L131) - -Shows the status of each migration. - - - - -### artisan:cache:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L138) - -Flushes the application cache. - -Cache and optimizations. - - -### artisan:config:cache -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L141) - -Creates a cache file for faster configuration loading. - - - - -### artisan:config:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L144) - -Removes the configuration cache file. - - - - -### artisan:event:cache -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L147) - -Discovers and cache the application\'s events and listeners. - - - - -### artisan:event:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L150) - -Clears all cached events and listeners. - - - - -### artisan:event:list -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L153) - -Lists the application\'s events and listeners. - - - - -### artisan:optimize -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L156) - -Cache the framework bootstrap files. - - - - -### artisan:optimize:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L159) - -Removes the cached bootstrap files. - - - - -### artisan:route:cache -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L162) - -Creates a route cache file for faster route registration. - - - - -### artisan:route:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L165) - -Removes the route cache file. - - - - -### artisan:route:list -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L168) - -Lists all registered routes. - - - - -### artisan:storage:link -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L171) - -Creates the symbolic links configured for the application. - - - - -### artisan:view:cache -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L174) - -Compiles all of the application\'s Blade templates. - - - - -### artisan:view:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L177) - -Clears all compiled view files. - - - - -### artisan:queue:failed -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L184) - -Lists all of the failed queue jobs. - -Queue and Horizon. - - -### artisan:queue:flush -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L187) - -Flushes all of the failed queue jobs. - - - - -### artisan:queue:restart -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L190) - -Restarts queue worker daemons after their current job. - - - - -### artisan:horizon -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L193) - -Starts a master supervisor in the foreground. - - - - -### artisan:horizon:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L196) - -Deletes all of the jobs from the specified queue. - - - - -### artisan:horizon:continue -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L199) - -Instructs the master supervisor to continue processing jobs. - - - - -### artisan:horizon:list -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L202) - -Lists all of the deployed machines. - - - - -### artisan:horizon:pause -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L205) - -Pauses the master supervisor. - - - - -### artisan:horizon:purge -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L208) - -Terminates any rogue Horizon processes. - - - - -### artisan:horizon:status -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L211) - -Gets the current status of Horizon. - - - - -### artisan:horizon:terminate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L214) - -Terminates the master supervisor so it can be restarted. - - - - -### artisan:horizon:publish -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L217) - -Publish all of the Horizon resources. - - - - -### artisan:​telescope:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L224) - -Clears all entries from Telescope. - -Telescope. - - -### artisan:​telescope:prune -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L227) - -Prunes stale entries from the Telescope database. - - - - -### artisan:octane -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L234) - -Starts the octane server. - -Octane. - - -### artisan:octane:reload -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L237) - -Reloads the octane server. - - - - -### artisan:octane:stop -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L240) - -Stops the octane server. - - - - -### artisan:octane:status -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L243) - -Check the status of the octane server. - - - - -### artisan:nova:publish -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L250) - -Publish all of the Laravel Nova resources. - -Nova. - - -### artisan:reverb:start -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L257) - -Starts the Reverb server. - -Reverb. - - -### artisan:reverb:restart -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L260) - -Restarts the Reverb server. - - - - -### artisan:pulse:check -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L267) - -Starts the Pulse server. - -Pulse. - - -### artisan:pulse:restart -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L270) - -Restarts the Pulse server. - - - - -### artisan:pulse:purge -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L273) - -Purges all Pulse data from storage. - - - - -### artisan:pulse:work -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L276) - -Process incoming Pulse data from the ingest stream. - - - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/laravel.php#L282) - -Deploys your project. - -Main deploy task. - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [artisan:create_key](/docs/recipe/laravel.md#artisancreate_key) -* [artisan:storage:link](/docs/recipe/laravel.md#artisanstoragelink) -* [artisan:config:cache](/docs/recipe/laravel.md#artisanconfigcache) -* [artisan:route:cache](/docs/recipe/laravel.md#artisanroutecache) -* [artisan:view:cache](/docs/recipe/laravel.md#artisanviewcache) -* [artisan:event:cache](/docs/recipe/laravel.md#artisaneventcache) -* [artisan:migrate](/docs/recipe/laravel.md#artisanmigrate) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/magento.md b/docs/recipe/magento.md deleted file mode 100644 index 23ab37874..000000000 --- a/docs/recipe/magento.md +++ /dev/null @@ -1,120 +0,0 @@ - - - - -# How to Deploy a Magento Project - -```php -require 'recipe/magento.php'; -``` - -[Source](/recipe/magento.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Magento application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Magento** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:cache:clear](/docs/recipe/magento.md#deploycacheclear) – Clears cache -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The magento recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento.php#L14) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Magento Configuration -Magento shared dirs - -```php title="Default value" -['var', 'media'] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento.php#L17) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - -Magento shared files - -```php title="Default value" -['app/etc/local.xml'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento.php#L20) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -Magento writable dirs - -```php title="Default value" -['var', 'media'] -``` - - - -## Tasks - -### deploy:cache:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento.php#L26) - -Clears cache. - -Clear cache - - -### deploy:clear_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento.php#L33) - - - -Remove files that can be used to compromise Magento - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento.php#L47) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:cache:clear](/docs/recipe/magento.md#deploycacheclear) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/magento2.md b/docs/recipe/magento2.md deleted file mode 100644 index c7313f6a5..000000000 --- a/docs/recipe/magento2.md +++ /dev/null @@ -1,775 +0,0 @@ - - - - -# How to Deploy a Magento 2 Project - -```php -require 'recipe/magento2.php'; -``` - -[Source](/recipe/magento2.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Magento 2 application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Magento 2** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [deploy:clear_paths](/docs/recipe/deploy/clear_paths.md#deployclear_paths) – Cleanup files and/or directories -* [deploy:magento](/docs/recipe/magento2.md#deploymagento) – Magento2 deployment operations - * [magento:build](/docs/recipe/magento2.md#magentobuild) – Magento2 build operations - * [magento:compile](/docs/recipe/magento2.md#magentocompile) – Compiles magento di - * [magento:deploy:assets](/docs/recipe/magento2.md#magentodeployassets) – Deploys assets - * [magento:maintenance:enable-if-needed](/docs/recipe/magento2.md#magentomaintenanceenable-if-needed) – Set maintenance mode if needed - * [magento:config:import](/docs/recipe/magento2.md#magentoconfigimport) – Config Import - * [magento:upgrade:db](/docs/recipe/magento2.md#magentoupgradedb) – Upgrades magento database - * [magento:maintenance:disable](/docs/recipe/magento2.md#magentomaintenancedisable) – Disables maintenance mode -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -In addition the **Magento 2** recipe contains an artifact deployment. -This is a two step process where you first execute - -```php -bin/dep artifact:build [options] [localhost] -``` - -to build an artifact, which then is deployed on a server with - -```php -bin/dep artifact:deploy [host] -``` - -The `localhost` to build the artifact on has to be declared local, so either add -```php -localhost() - ->set('local', true); -``` -to your deploy.php or -```yaml -hosts: - localhost: - local: true -``` -to your deploy yaml. - -The [artifact:build](#artifact:build) command of **Magento 2** consists of: * [build:prepare](/docs/recipe/magento2.md#buildprepare) – Prepare local artifact build -* [build:remove-generated](/docs/recipe/magento2.md#buildremove-generated) – Clears generated files prior to building. -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [magento:compile](/docs/recipe/magento2.md#magentocompile) – Compiles magento di -* [magento:deploy:assets](/docs/recipe/magento2.md#magentodeployassets) – Deploys assets -* [artifact:package](/docs/recipe/magento2.md#artifactpackage) – Packages all relevant files in an artifact. - - - The [artifact:deploy](#artifact:deploy) command of **Magento 2** consists of: -* [artifact:prepare](/docs/recipe/magento2.md#artifactprepare) – Prepares an artifact on the target server - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [artifact:upload](/docs/recipe/magento2.md#artifactupload) – Uploads artifact in release folder for extraction. - * [artifact:extract](/docs/recipe/magento2.md#artifactextract) – Extracts artifact in release path. - * [deploy:additional-shared](/docs/recipe/magento2.md#deployadditional-shared) – Adds additional files and dirs to the list of shared files and dirs - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [magento:maintenance:enable-if-needed](/docs/recipe/magento2.md#magentomaintenanceenable-if-needed) – Set maintenance mode if needed -* [magento:config:import](/docs/recipe/magento2.md#magentoconfigimport) – Config Import -* [magento:upgrade:db](/docs/recipe/magento2.md#magentoupgradedb) – Upgrades magento database -* [magento:maintenance:disable](/docs/recipe/magento2.md#magentomaintenancedisable) – Disables maintenance mode -* [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release -* [artifact:finish](/docs/recipe/magento2.md#artifactfinish) – Executes the tasks after artifact is released - * [magento:cache:flush](/docs/recipe/magento2.md#magentocacheflush) – Flushes Magento Cache - * [cachetool:clear:opcache](/docs/contrib/cachetool.md#cachetoolclearopcache) – Clears OPcode cache - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The magento2 recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### static_content_locales -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L26) - -Configuration -By default setup:static-content:deploy uses `en_US`. -To change that, simply put `set('static_content_locales', 'en_US de_DE');` -in you deployer script. - -```php title="Default value" -'en_US' -``` - - -### magento_themes -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L43) - -Configuration -You can also set the themes to run against. By default it'll deploy -all themes - `add('magento_themes', ['Magento/luma', 'Magento/backend']);` -If the themes are set as a simple list of strings, then all languages defined in [static_content_locales](/docs/recipe/magento2.md#static_content_locales) are -compiled for the given themes. -Alternatively The themes can be defined as an associative array, where the key represents the theme name and -the key contains the languages for the compilation (for this specific theme) -Example: -set('magento_themes', ['Magento/luma']); - Will compile this theme with every language from [static_content_locales](/docs/recipe/magento2.md#static_content_locales) -set('magento_themes', [ - 'Magento/luma' => null, - Will compile all languages from [static_content_locales](/docs/recipe/magento2.md#static_content_locales) for Magento/luma - 'Custom/theme' => 'en_US fr_FR' - Will compile only en_US and fr_FR for Custom/theme - 'Custom/another' => '[static_content_locales](/docs/recipe/magento2.md#static_content_locales) it_IT' - Will compile all languages from [static_content_locales](/docs/recipe/magento2.md#static_content_locales) + it_IT for Custom/another -]); - Will compile this theme with every language - -```php title="Default value" -[ - -] -``` - - -### static_deploy_options -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L48) - -Static content deployment options, e.g. '--no-parent' - - - -### split_static_deployment -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L51) - -Deploy frontend and adminhtml together as default - -```php title="Default value" -false -``` - - -### static_content_locales_backend -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L54) - -Use the default languages for the backend as default - -```php title="Default value" -'{{static_content_locales}}' -``` - - -### magento_themes_backend -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L58) - -backend themes to deploy. Only used if split_static_deployment=true -This setting supports the same options/structure as [magento_themes](/docs/recipe/magento2.md#magento_themes) - -```php title="Default value" -['Magento/backend' => null] -``` - - -### static_content_jobs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L64) - -Configuration -Also set the number of concurrent jobs to run. The default is 1 -Update using: `set('static_content_jobs', '1');` - -```php title="Default value" -'1' -``` - - -### content_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L66) - - - -```php title="Default value" -return time(); -``` - - -### magento_dir -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L71) - -Magento directory relative to repository root. Use "." (default) if it is not located in a subdirectory - -```php title="Default value" -'.' -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L74) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -[ - '{{magento_dir}}/app/etc/env.php', - '{{magento_dir}}/var/.maintenance.ip', -] -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L78) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -[ - '{{magento_dir}}/var/composer_home', - '{{magento_dir}}/var/log', - '{{magento_dir}}/var/export', - '{{magento_dir}}/var/report', - '{{magento_dir}}/var/import', - '{{magento_dir}}/var/import_history', - '{{magento_dir}}/var/session', - '{{magento_dir}}/var/importexport', - '{{magento_dir}}/var/backups', - '{{magento_dir}}/var/tmp', - '{{magento_dir}}/pub/sitemap', - '{{magento_dir}}/pub/media', - '{{magento_dir}}/pub/static/_cache', -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L93) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -[ - '{{magento_dir}}/var', - '{{magento_dir}}/pub/static', - '{{magento_dir}}/pub/media', - '{{magento_dir}}/generated', - '{{magento_dir}}/var/page_cache', -] -``` - - -### clear_paths -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L100) - -Overrides [clear_paths](/docs/recipe/deploy/clear_paths.md#clear_paths) from `recipe/deploy/clear_paths.php`. - - - -```php title="Default value" -[ - '{{magento_dir}}/generated/*', - '{{magento_dir}}/pub/static/_cache/*', - '{{magento_dir}}/var/generation/*', - '{{magento_dir}}/var/cache/*', - '{{magento_dir}}/var/page_cache/*', - '{{magento_dir}}/var/view_preprocessed/*', -] -``` - - -### bin/magento -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L109) - - - -```php title="Default value" -'{{release_or_current_path}}/{{magento_dir}}/bin/magento' -``` - - -### magento_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L111) - - - -```php title="Default value" -// detect version -$versionOutput = run('{{bin/php}} {{bin/magento}} --version'); -preg_match('/(\d+\.?)+(-p\d+)?$/', $versionOutput, $matches); -return $matches[0] ?? '2.0'; -``` - - -### config_import_needed -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L118) - - -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### database_upgrade_needed -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L132) - - -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### enable_zerodowntime -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L148) - -Deploy without setting maintenance mode if possible - -```php title="Default value" -true -``` - - -### artifact_file -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L337) - -Artifact deployment section -The file the artifact is saved to - -```php title="Default value" -'artifact.tar.gz' -``` - - -### artifact_dir -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L340) - -The directory the artifact is saved in - -```php title="Default value" -'artifacts' -``` - - -### artifact_excludes_file -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L344) - -Points to a file with a list of files to exclude from packaging. -The format is as with the `tar --exclude-from=[file]` option - -```php title="Default value" -'artifacts/excludes' -``` - - -### build_from_repo -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L347) - -If set to true, the artifact is built from a clean copy of the project repository instead of the current working directory - -```php title="Default value" -false -``` - - -### repository -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L350) - -Overrides [repository](/docs/recipe/common.md#repository) from `recipe/common.php`. - -Set this value if "build_from_repo" is set to true. The target to deploy must also be set with "--branch", "--tag" or "--revision" - -```php title="Default value" -null -``` - - -### artifact_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L353) - -The relative path to the artifact file. If the directory does not exist, it will be created - -```php title="Default value" -if (!testLocally('[ -d {{artifact_dir}} ]')) { -runLocally('mkdir -p {{artifact_dir}}'); -} -return get('artifact_dir') . '/' . get('artifact_file'); -``` - - -### bin/tar -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L361) - -The location of the tar command. On MacOS you should have installed gtar, as it supports the required settings -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### additional_shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L433) - -Array of shared files that will be added to the default shared_files without overriding - - - -### additional_shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L435) - -Array of shared directories that will be added to the default shared_dirs without overriding - - - - -## Tasks - -### magento:compile -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L158) - -Compiles magento di. - -Tasks -To work correctly with artifact deployment, it is necessary to set the MAGE_MODE correctly in `app/etc/config.php` -e.g. -```php -'MAGE_MODE' => 'production' -``` - - -### magento:deploy:assets -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L184) - -Deploys assets. - -To work correctly with artifact deployment it is necessary to set `system/dev/js` , `system/dev/css` and `system/dev/template` -in `app/etc/config.php`, e.g.: -```php -'system' => [ - 'default' => [ - 'dev' => [ - 'js' => [ - 'merge_files' => '1', - 'minify_files' => '1' - ], - 'css' => [ - 'merge_files' => '1', - 'minify_files' => '1' - ], - 'template' => [ - 'minify_html' => '1' - ] - ] - ] -``` - - -### magento:deploy:assets:adminhtml -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L201) - -Deploys assets for backend only. - - - - -### magento:deploy:assets:frontend -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L206) - -Deploys assets for frontend only. - - - - -### magento:sync:content_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L254) - -Syncs content version. - - - - -### magento:maintenance:enable -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L264) - -Enables maintenance mode. - - - - -### magento:maintenance:disable -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L270) - -Disables maintenance mode. - - - - -### magento:maintenance:enable-if-needed -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L276) - -Set maintenance mode if needed. - - - - -### magento:config:import -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L283) - -Config Import. - - - - -### magento:upgrade:db -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L292) - -Upgrades magento database. - - - - -### magento:cache:flush -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L302) - -Flushes Magento Cache. - - - - -### deploy:magento -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L307) - -Magento2 deployment operations. - - - - -This task is group task which contains next tasks: -* [magento:build](/docs/recipe/magento2.md#magentobuild) -* [magento:maintenance:enable-if-needed](/docs/recipe/magento2.md#magentomaintenanceenable-if-needed) -* [magento:config:import](/docs/recipe/magento2.md#magentoconfigimport) -* [magento:upgrade:db](/docs/recipe/magento2.md#magentoupgradedb) -* [magento:maintenance:disable](/docs/recipe/magento2.md#magentomaintenancedisable) - - -### magento:build -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L316) - -Magento2 build operations. - - - - -This task is group task which contains next tasks: -* [magento:compile](/docs/recipe/magento2.md#magentocompile) -* [magento:deploy:assets](/docs/recipe/magento2.md#magentodeployassets) - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L322) - -Deploys your project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:clear_paths](/docs/recipe/deploy/clear_paths.md#deployclear_paths) -* [deploy:magento](/docs/recipe/magento2.md#deploymagento) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - -### artifact:package -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L372) - -Packages all relevant files in an artifact. - -tasks section - - -### artifact:upload -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L382) - -Uploads artifact in release folder for extraction. - - - - -### artifact:extract -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L387) - -Extracts artifact in release path. - - - - -### build:remove-generated -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L393) - -Clears generated files prior to building. - - - - -### build:prepare -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L398) - -Prepare local artifact build. - - - - -### artifact:build -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L423) - -Builds an artifact. - - - - -This task is group task which contains next tasks: -* [build:prepare](/docs/recipe/magento2.md#buildprepare) -* [build:remove-generated](/docs/recipe/magento2.md#buildremove-generated) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [magento:compile](/docs/recipe/magento2.md#magentocompile) -* [magento:deploy:assets](/docs/recipe/magento2.md#magentodeployassets) -* [artifact:package](/docs/recipe/magento2.md#artifactpackage) - - -### deploy:additional-shared -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L439) - -Adds additional files and dirs to the list of shared files and dirs. - - - - -### magento:set_cache_prefix -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L454) - -Update cache id_prefix. - -Update cache id_prefix on deploy so that you are compiling against a fresh cache -Reference Issue: https://github.com/davidalger/capistrano-magento2/issues/151 -To use this feature, add the following to your deployer scripts: -```php -after('deploy:shared', 'magento:set_cache_prefix'); -after('deploy:magento', 'magento:cleanup_cache_prefix'); -``` - - -### magento:cleanup_cache_prefix -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L494) - -Cleanup cache id_prefix env files. - -After successful deployment, move the tmp_env.php file to env.php ready for next deployment - - -### magento:cron:stop -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L510) - -Remove cron from crontab and kill running cron jobs. - -Remove cron from crontab and kill running cron jobs -To use this feature, add the following to your deployer scripts: - ```php - after('magento:maintenance:enable-if-needed', 'magento:cron:stop'); - ``` - - -### magento:cron:install -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L526) - -Install cron in crontab. - -Install cron in crontab -To use this feature, add the following to your deployer scripts: - ```php - after('magento:upgrade:db', 'magento:cron:install'); - ``` - - -### artifact:prepare -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L532) - -Prepares an artifact on the target server. - - - - -This task is group task which contains next tasks: -* [deploy:info](/docs/recipe/deploy/info.md#deployinfo) -* [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) -* [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) -* [deploy:release](/docs/recipe/deploy/release.md#deployrelease) -* [artifact:upload](/docs/recipe/magento2.md#artifactupload) -* [artifact:extract](/docs/recipe/magento2.md#artifactextract) -* [deploy:additional-shared](/docs/recipe/magento2.md#deployadditional-shared) -* [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) -* [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) - - -### artifact:finish -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L545) - -Executes the tasks after artifact is released. - - - - -This task is group task which contains next tasks: -* [magento:cache:flush](/docs/recipe/magento2.md#magentocacheflush) -* [cachetool:clear:opcache](/docs/contrib/cachetool.md#cachetoolclearopcache) -* [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) -* [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) -* [deploy:success](/docs/recipe/common.md#deploysuccess) - - -### artifact:deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/magento2.php#L554) - -Actually releases the artifact deployment. - - - - -This task is group task which contains next tasks: -* [artifact:prepare](/docs/recipe/magento2.md#artifactprepare) -* [magento:maintenance:enable-if-needed](/docs/recipe/magento2.md#magentomaintenanceenable-if-needed) -* [magento:config:import](/docs/recipe/magento2.md#magentoconfigimport) -* [magento:upgrade:db](/docs/recipe/magento2.md#magentoupgradedb) -* [magento:maintenance:disable](/docs/recipe/magento2.md#magentomaintenancedisable) -* [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) -* [artifact:finish](/docs/recipe/magento2.md#artifactfinish) - - diff --git a/docs/recipe/pimcore.md b/docs/recipe/pimcore.md deleted file mode 100644 index 86f541a0d..000000000 --- a/docs/recipe/pimcore.md +++ /dev/null @@ -1,82 +0,0 @@ - - - - -# How to Deploy a Pimcore Project - -```php -require 'recipe/pimcore.php'; -``` - -[Source](/recipe/pimcore.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Pimcore application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Pimcore** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [deploy:cache:clear](/docs/recipe/symfony.md#deploycacheclear) – Clears cache -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The pimcore recipe is based on the [symfony](/docs/recipe/symfony.md) recipe. - - -## Tasks - -### pimcore:rebuild-classes -[Source](https://github.com/deployphp/deployer/blob/master/recipe/pimcore.php#L16) - -Rebuilds Pimcore Classes. - - - - -### pimcore:cache_clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/pimcore.php#L21) - -Removes cache. - - - - -### pimcore:deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/pimcore.php#L25) - - - - - - -This task is group task which contains next tasks: -* [pimcore:rebuild-classes](/docs/recipe/pimcore.md#pimcorerebuild-classes) -* [pimcore:cache_clear](/docs/recipe/pimcore.md#pimcorecache_clear) - - diff --git a/docs/recipe/prestashop.md b/docs/recipe/prestashop.md deleted file mode 100644 index 3d4daaf7d..000000000 --- a/docs/recipe/prestashop.md +++ /dev/null @@ -1,111 +0,0 @@ - - - - -# How to Deploy a Prestashop Project - -```php -require 'recipe/prestashop.php'; -``` - -[Source](/recipe/prestashop.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Prestashop application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Prestashop** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The prestashop recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/prestashop.php#L9) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -[ - 'config/settings.inc.php', - '.htaccess', -] -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/prestashop.php#L13) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -[ - 'img', - 'log', - 'download', - 'upload', - 'translations', - 'mails', - 'themes/default-bootstrap/lang', - 'themes/default-bootstrap/mails', - 'themes/default-bootstrap/pdf/lang', -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/prestashop.php#L24) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -[ - 'img', - 'log', - 'cache', - 'download', - 'upload', - 'translations', - 'mails', - 'themes/default-bootstrap/lang', - 'themes/default-bootstrap/mails', - 'themes/default-bootstrap/pdf/lang', - 'themes/default-bootstrap/cache', -] -``` - - - diff --git a/docs/recipe/provision.md b/docs/recipe/provision.md deleted file mode 100644 index e0ba8cdd6..000000000 --- a/docs/recipe/provision.md +++ /dev/null @@ -1,134 +0,0 @@ - - - - -# Provision Recipe - -```php -require 'recipe/provision.php'; -``` - -[Source](/recipe/provision.php) - -* Requires - * [databases](/docs/recipe/provision/databases.md) - * [nodejs](/docs/recipe/provision/nodejs.md) - * [php](/docs/recipe/provision/php.md) - * [user](/docs/recipe/provision/user.md) - * [website](/docs/recipe/provision/website.md) - -## Configuration -### lsb_release -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L19) - -Name of lsb_release like: focal, bionic, etc. -As only Ubuntu 20.04 LTS is supported for provision should be the `focal`. - -```php title="Default value" -return run("lsb_release -s -c"); -``` - - -### provision_user -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L43) - -Default user to use for provisioning. - -```php title="Default value" -'root' -``` - - - -## Tasks - -### provision -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L24) - -Provision the server. - - - - -This task is group task which contains next tasks: -* [provision:check](/docs/recipe/provision.md#provisioncheck) -* [provision:configure](/docs/recipe/provision.md#provisionconfigure) -* [provision:update](/docs/recipe/provision.md#provisionupdate) -* [provision:upgrade](/docs/recipe/provision.md#provisionupgrade) -* [provision:install](/docs/recipe/provision.md#provisioninstall) -* [provision:ssh](/docs/recipe/provision.md#provisionssh) -* [provision:firewall](/docs/recipe/provision.md#provisionfirewall) -* [provision:user](/docs/recipe/provision/user.md#provisionuser) -* [provision:php](/docs/recipe/provision/php.md#provisionphp) -* [provision:node](/docs/recipe/provision/nodejs.md#provisionnode) -* [provision:databases](/docs/recipe/provision/databases.md#provisiondatabases) -* [provision:composer](/docs/recipe/provision/php.md#provisioncomposer) -* [provision:server](/docs/recipe/provision/website.md#provisionserver) -* [provision:website](/docs/recipe/provision/website.md#provisionwebsite) -* [provision:verify](/docs/recipe/provision.md#provisionverify) - - -### provision:check -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L46) - -Checks pre-required state. - - - - -### provision:configure -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L71) - -Collects required params. - - - - -### provision:update -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L123) - -Adds repositories and update. - - - - -### provision:upgrade -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L140) - -Upgrades all packages. - - - - -### provision:install -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L148) - -Installs packages. - - - - -### provision:ssh -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L183) - -Configures the ssh. - - - - -### provision:firewall -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L195) - -Setups a firewall. - - - - -### provision:verify -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision.php#L204) - -Verifies what provision was successful. - - - - diff --git a/docs/recipe/provision/databases.md b/docs/recipe/provision/databases.md deleted file mode 100644 index 2ef133460..000000000 --- a/docs/recipe/provision/databases.md +++ /dev/null @@ -1,90 +0,0 @@ - - - - -# Databases Recipe - -```php -require 'recipe/provision/databases.php'; -``` - -[Source](/recipe/provision/databases.php) - - -## Configuration -### db_type -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L5) - - -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - -### db_name -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L15) - - - -```php title="Default value" -return ask(' DB name: ', 'prod'); -``` - - -### db_user -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L19) - - - -```php title="Default value" -return ask(' DB user: ', 'deployer'); -``` - - -### db_password -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L23) - - - -```php title="Default value" -return askHiddenResponse(' DB password: '); -``` - - - -## Tasks - -### provision:databases -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L28) - -Provision databases. - - - - -### provision:mysql -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L40) - -Provision MySQL. - - - - -### provision:mariadb -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L51) - -Provision MariaDB. - - - - -### provision:postgresql -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/databases.php#L62) - -Provision PostgreSQL. - - - - diff --git a/docs/recipe/provision/nodejs.md b/docs/recipe/provision/nodejs.md deleted file mode 100644 index e7c56a2fd..000000000 --- a/docs/recipe/provision/nodejs.md +++ /dev/null @@ -1,35 +0,0 @@ - - - - -# Nodejs Recipe - -```php -require 'recipe/provision/nodejs.php'; -``` - -[Source](/recipe/provision/nodejs.php) - - -## Configuration -### node_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/nodejs.php#L8) - - - -```php title="Default value" -'23.x' -``` - - - -## Tasks - -### provision:node -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/nodejs.php#L11) - -Installs npm packages. - - - - diff --git a/docs/recipe/provision/php.md b/docs/recipe/provision/php.md deleted file mode 100644 index 144255456..000000000 --- a/docs/recipe/provision/php.md +++ /dev/null @@ -1,54 +0,0 @@ - - - - -# Php Recipe - -```php -require 'recipe/provision/php.php'; -``` - -[Source](/recipe/provision/php.php) - - -## Configuration -### php_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/php.php#L5) - - - -```php title="Default value" -$defaultPhpVersion = file_exists('composer.json') -? explode('|', preg_replace('/[^0-9.|]+/', '', json_decode(file_get_contents('composer.json'), true)['require']['php'] ?? '8.3'))[0] -: '8.3'; -return ask(' What PHP version to install? ', $defaultPhpVersion, ['5.6', '7.4', '8.0', '8.1', '8.2']); -``` - - - -## Tasks - -### provision:php -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/php.php#L13) - -Installs PHP packages. - - - - -### logs:php-fpm -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/php.php#L68) - -Shows php-fpm logs. - - - - -### provision:composer -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/php.php#L77) - -Installs Composer. - - - - diff --git a/docs/recipe/provision/user.md b/docs/recipe/provision/user.md deleted file mode 100644 index 12aec6b7d..000000000 --- a/docs/recipe/provision/user.md +++ /dev/null @@ -1,43 +0,0 @@ - - - - -# User Recipe - -```php -require 'recipe/provision/user.php'; -``` - -[Source](/recipe/provision/user.php) - - -## Configuration -### sudo_password -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/user.php#L7) - - - -```php title="Default value" -return askHiddenResponse(' Password for sudo: '); -``` - - - -## Tasks - -### provision:user -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/user.php#L13) - -Setups a deployer user. - - - - -### provision:ssh_copy_id -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/user.php#L59) - -Copy public key to remote server. - - - - diff --git a/docs/recipe/provision/website.md b/docs/recipe/provision/website.md deleted file mode 100644 index 4f2d20825..000000000 --- a/docs/recipe/provision/website.md +++ /dev/null @@ -1,69 +0,0 @@ - - - - -# Website Recipe - -```php -require 'recipe/provision/website.php'; -``` - -[Source](/recipe/provision/website.php) - - -## Configuration -### domain -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/website.php#L9) - - - -```php title="Default value" -return ask(' Domain: ', get('hostname')); -``` - - -### public_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/website.php#L13) - - - -```php title="Default value" -return ask(' Public path: ', 'public'); -``` - - - -## Tasks - -### provision:server -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/website.php#L18) - -Configures a server. - - - - -### provision:website -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/website.php#L27) - -Provision website. - - - - -### logs:access -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/website.php#L71) - -Shows access logs. - - - - -### logs:caddy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/provision/website.php#L76) - -Shows caddy syslog. - - - - diff --git a/docs/recipe/shopware.md b/docs/recipe/shopware.md deleted file mode 100644 index 5ac34d4bf..000000000 --- a/docs/recipe/shopware.md +++ /dev/null @@ -1,309 +0,0 @@ - - - - -# How to Deploy a Shopware Project - -```php -require 'recipe/shopware.php'; -``` - -[Source](/recipe/shopware.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Shopware application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Shopware** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [sw:writable:jwt](/docs/recipe/shopware.md#swwritablejwt) – -* [sw:deploy](/docs/recipe/shopware.md#swdeploy) – - * [sw:database:migrate](/docs/recipe/shopware.md#swdatabasemigrate) – - * [sw:plugin:refresh](/docs/recipe/shopware.md#swpluginrefresh) – - * [sw:theme:refresh](/docs/recipe/shopware.md#swthemerefresh) – - * [sw:scheduled-task:register](/docs/recipe/shopware.md#swscheduled-taskregister) – - * [sw:cache:clear](/docs/recipe/shopware.md#swcacheclear) – - * [sw:plugin:update:all](/docs/recipe/shopware.md#swpluginupdateall) – - * [sw:cache:clear](/docs/recipe/shopware.md#swcacheclear) – -* [deploy:clear_paths](/docs/recipe/deploy/clear_paths.md#deployclear_paths) – Cleanup files and/or directories -* [sw:cache:warmup](/docs/recipe/shopware.md#swcachewarmup) – -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The shopware recipe is based on the [common](/docs/recipe/common.md) recipe. - - -## Usage - -Add `repository` to your _deploy.php_ file: - -```php -set('repository', 'git@github.com:shopware/production.git'); -``` - -configure host: -```php -host('SSH-HOSTNAME') - ->set('remote_user', 'SSH-USER') - ->set('deploy_path', '/var/www/shopware') // This is the path, where deployer will create its directory structure - ->set('http_user', 'www-data') // Not needed, if the `user` is the same user, the webserver is running with - ->set('http_group', 'www-data') - ->set('writable_mode', 'chmod') - ->set('writable_recursive', true) - ->set('become', 'www-data'); // You might want to change user to execute remote tasks because of access rights of created cache files -``` - -:::note -Please remember that the installation must be modified so that it can be -[build without database](https://developer.shopware.com/docs/guides/hosting/installation-updates/deployments/build-w-o-db#compiling-the-storefront-without-database). -::: - - -## Configuration -### bin/console -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L35) - - - -```php title="Default value" -'{{bin/php}} {{release_or_current_path}}/bin/console' -``` - - -### default_timeout -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L37) - -Overrides [default_timeout](/docs/recipe/common.md#default_timeout) from `recipe/common.php`. - - - - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L40) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - -These files are shared among all releases. - -```php title="Default value" -[ - '.env.local', - 'install.lock', - 'public/.htaccess', - 'public/.user.ini', -] -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L48) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -These directories are shared among all releases. - -```php title="Default value" -[ - 'config/jwt', - 'files', - 'var/log', - 'public/media', - 'public/thumbnail', - 'public/sitemap', -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L59) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -These directories are made writable (the definition of "writable" requires attention). -Please note that the files in `config/jwt/*` receive special attention in the `sw:writable:jwt` task. - -```php title="Default value" -[ - 'config/jwt', - 'custom/plugins', - 'files', - 'public/bundles', - 'public/css', - 'public/fonts', - 'public/js', - 'public/media', - 'public/sitemap', - 'public/theme', - 'public/thumbnail', - 'var', -] -``` - - - -## Tasks - -### sw:cache:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L75) - - - -This task remotely executes the `cache:clear` console command on the target server. - - -### sw:cache:warmup -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L81) - - - -This task remotely executes the cache warmup console commands on the target server, so that the first user, who -visits the website, doesn't have to wait for the cache to be built up. - - -### sw:database:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L87) - - - -This task remotely executes the `database:migrate` console command on the target server. - - -### sw:plugin:refresh -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L91) - - - - - - -### sw:scheduled-task:register -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L95) - - - - - - -### sw:theme:refresh -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L99) - - - - - - -### sw:theme:compile -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L105) - - - -This task is not used per default, but can be used, e.g. in combination with `SHOPWARE_SKIP_THEME_COMPILE=1`, -to build the theme remotely instead of locally. - - -### sw:plugin:update:all -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L117) - - - - - - -### sw:writable:jwt -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L127) - - - - - - -### sw:deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L134) - - - -Grouped SW deploy tasks. - - -This task is group task which contains next tasks: -* [sw:database:migrate](/docs/recipe/shopware.md#swdatabasemigrate) -* [sw:plugin:refresh](/docs/recipe/shopware.md#swpluginrefresh) -* [sw:theme:refresh](/docs/recipe/shopware.md#swthemerefresh) -* [sw:scheduled-task:register](/docs/recipe/shopware.md#swscheduled-taskregister) -* [sw:cache:clear](/docs/recipe/shopware.md#swcacheclear) -* [sw:plugin:update:all](/docs/recipe/shopware.md#swpluginupdateall) -* [sw:cache:clear](/docs/recipe/shopware.md#swcacheclear) - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L145) - -Deploys your project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [sw:writable:jwt](/docs/recipe/shopware.md#swwritablejwt) -* [sw:deploy](/docs/recipe/shopware.md#swdeploy) -* [deploy:clear_paths](/docs/recipe/deploy/clear_paths.md#deployclear_paths) -* [sw:cache:warmup](/docs/recipe/shopware.md#swcachewarmup) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - -### sw-build-without-db:get-remote-config -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L164) - - - - - - -### sw-build-without-db:build -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L177) - - - - - - -### sw-build-without-db -[Source](https://github.com/deployphp/deployer/blob/master/recipe/shopware.php#L181) - - - - - - -This task is group task which contains next tasks: -* [sw-build-without-db:get-remote-config](/docs/recipe/shopware.md#sw-build-without-dbget-remote-config) -* [sw-build-without-db:build](/docs/recipe/shopware.md#sw-build-without-dbbuild) - - diff --git a/docs/recipe/silverstripe.md b/docs/recipe/silverstripe.md deleted file mode 100644 index 026756266..000000000 --- a/docs/recipe/silverstripe.md +++ /dev/null @@ -1,137 +0,0 @@ - - - - -# How to Deploy a Silverstripe Project - -```php -require 'recipe/silverstripe.php'; -``` - -[Source](/recipe/silverstripe.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Silverstripe application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Silverstripe** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [silverstripe:buildflush](/docs/recipe/silverstripe.md#silverstripebuildflush) – Runs /dev/build?flush=all -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The silverstripe recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### shared_assets -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L13) - -Silverstripe configuration - -```php title="Default value" -if (test('[ -d {{release_or_current_path}}/public ]') || test('[ -d {{deploy_path}}/shared/public ]')) { -return 'public/assets'; -} -return 'assets'; -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L22) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Silverstripe shared dirs - -```php title="Default value" -[ - '{{shared_assets}}', -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L27) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -Silverstripe writable dirs - -```php title="Default value" -[ - '{{shared_assets}}', -] -``` - - -### silverstripe_cli_script -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L32) - -Silverstripe cli script -:::info Autogenerated -The value of this configuration is autogenerated on access. -::: - - - - - -## Tasks - -### silverstripe:build -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L48) - -Runs /dev/build. - -Helper tasks - - -### silverstripe:buildflush -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L53) - -Runs /dev/build?flush=all. - - - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/silverstripe.php#L61) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [silverstripe:buildflush](/docs/recipe/silverstripe.md#silverstripebuildflush) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/spiral.md b/docs/recipe/spiral.md deleted file mode 100644 index 1cc64e987..000000000 --- a/docs/recipe/spiral.md +++ /dev/null @@ -1,287 +0,0 @@ - - - - -# How to Deploy a Spiral Project - -```php -require 'recipe/spiral.php'; -``` - -[Source](/recipe/spiral.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Spiral application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Spiral** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:environment](/docs/recipe/spiral.md#deployenvironment) – Create .env file if it doesn\'t exist -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [spiral:encrypt-key](/docs/recipe/spiral.md#spiralencrypt-key) – Generate new encryption key, if it doesn\'t exist -* [spiral:configure](/docs/recipe/spiral.md#spiralconfigure) – Configure project -* [deploy:download-rr](/docs/recipe/spiral.md#deploydownload-rr) – Download RoadRunner -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project -* [deploy:restart-rr](/docs/recipe/spiral.md#deployrestart-rr) – Restart RoadRunner - - -The spiral recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L10) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Spiral shared dirs - -```php title="Default value" -['runtime'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L13) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -Spiral writable dirs - -```php title="Default value" -['runtime', 'public'] -``` - - -### roadrunner_path -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L16) - -Path to the RoadRunner server - -```php title="Default value" -'{{release_or_current_path}}' -``` - - - -## Tasks - -### deploy:environment -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L19) - -Create .env file if it doesn\'t exist. - - - - -### spiral:configure -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L61) - -Configure project. - -Spiral Framework console commands - - -### spiral:cycle -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L64) - -Update (init) cycle schema from database and annotated classes. - - - - -### spiral:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L67) - -Perform all outstanding migrations. - - - - -### spiral:update -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L70) - -Update project state. - - - - -### spiral:cache:clean -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L73) - -Clean application runtime cache. - - - - -### spiral:i18n:reset -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L76) - -Reset translation cache. - - - - -### spiral:encrypt-key -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L79) - -Generate new encryption key, if it doesn\'t exist. - - - - -### spiral:views:compile -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L82) - -Warm-up view cache. - - - - -### spiral:views:reset -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L85) - -Clear view cache. - - - - -### cycle:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L91) - -Generate ORM schema migrations. - -Cycle ORM and migrations console commands - - -### cycle:render -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L94) - -Render available CycleORM schemas. - - - - -### cycle:sync -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L97) - -Sync Cycle ORM schema with database without intermediate migration (risk operation). - - - - -### migrate:init -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L100) - -Init migrations component (create migrations table). - - - - -### migrate:replay -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L103) - -Replay (down, up) one or multiple migrations. - - - - -### migrate:rollback -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L106) - -Rollback one (default) or multiple migrations. - - - - -### migrate:status -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L109) - -Get list of all available migrations and their statuses. - - - - -### roadrunner:serve -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L115) - -Start RoadRunner server. - -RoadRunner console commands - - -### roadrunner:stop -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L120) - -Stop RoadRunner server. - - - - -### roadrunner:reset -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L123) - -Reset workers of all services. - - - - -### deploy:download-rr -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L129) - -Download RoadRunner. - -Download and restart RoadRunner - - -### deploy:restart-rr -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L135) - -Restart RoadRunner. - - - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/spiral.php#L149) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:environment](/docs/recipe/spiral.md#deployenvironment) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [spiral:encrypt-key](/docs/recipe/spiral.md#spiralencrypt-key) -* [spiral:configure](/docs/recipe/spiral.md#spiralconfigure) -* [deploy:download-rr](/docs/recipe/spiral.md#deploydownload-rr) -* [deploy:publish](/docs/recipe/common.md#deploypublish) -* [deploy:restart-rr](/docs/recipe/spiral.md#deployrestart-rr) - - diff --git a/docs/recipe/statamic.md b/docs/recipe/statamic.md deleted file mode 100644 index cbcbe63ce..000000000 --- a/docs/recipe/statamic.md +++ /dev/null @@ -1,224 +0,0 @@ - - - - -# How to Deploy a Statamic Project - -```php -require 'recipe/statamic.php'; -``` - -[Source](/recipe/statamic.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Statamic application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Statamic** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [artisan:storage:link](/docs/recipe/laravel.md#artisanstoragelink) – Creates the symbolic links configured for the application -* [artisan:cache:clear](/docs/recipe/laravel.md#artisancacheclear) – Flushes the application cache -* [statamic:stache:clear](/docs/recipe/statamic.md#statamicstacheclear) – Clears the "Stache" cache -* [statamic:stache:warm](/docs/recipe/statamic.md#statamicstachewarm) – Builds the "Stache" cache -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The statamic recipe is based on the [laravel](/docs/recipe/laravel.md) recipe. - -## Configuration -### statamic_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L16) - - - -```php title="Default value" -$result = run('{{bin/php}} {{release_or_current_path}}/please --version'); -preg_match_all('/(\d+\.?)+/', $result, $matches); -return $matches[0][0] ?? 'unknown'; -``` - - - -## Tasks - -### statamic:addons:discover -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L27) - -Rebuilds the cached addon package manifest. - -Addons - - -### statamic:assets:generate-presets -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L34) - -Generates asset preset manipulations. - -Assets - - -### statamic:assets:meta -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L37) - -Generates asset metadata files. - - - - -### statamic:git:commit -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L44) - -Git add and commit tracked content. - -Git - - -### statamic:glide:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L51) - -Clears the Glide image cache. - -Glide - - -### statamic:responsive:generate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L58) - -Generates responsive images. - -Responsive Images (not in the core) - - -### statamic:responsive:regenerate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L61) - -Regenerate responsive images. - - - - -### statamic:search:insert -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L68) - -Inserts an item into its search indexes. - -Search - - -### statamic:search:update -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L71) - -Update a search index. - - - - -### statamic:stache:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L78) - -Clears the "Stache" cache. - -Stache - - -### statamic:stache:doctor -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L81) - -Diagnose any problems with the Stache. - - - - -### statamic:stache:refresh -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L84) - -Clears and rebuild the "Stache" cache. - - - - -### statamic:stache:warm -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L87) - -Builds the "Stache" cache. - - - - -### statamic:static:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L94) - -Clears the static page cache. - -Static - - -### statamic:static:warm -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L97) - -Warms the static cache by visiting all URLs. - - - - -### statamic:support:details -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L104) - -Outputs details helpful for support requests. - -Support - - -### statamic:updates:run -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L111) - -Runs update scripts from specific version. - -Updated - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/statamic.php#L119) - -Deploys your project. - -Main Deploy Script for Statamic, which -will overwrite the Laravel default. - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [artisan:storage:link](/docs/recipe/laravel.md#artisanstoragelink) -* [artisan:cache:clear](/docs/recipe/laravel.md#artisancacheclear) -* [statamic:stache:clear](/docs/recipe/statamic.md#statamicstacheclear) -* [statamic:stache:warm](/docs/recipe/statamic.md#statamicstachewarm) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/sulu.md b/docs/recipe/sulu.md deleted file mode 100644 index 44afc4fec..000000000 --- a/docs/recipe/sulu.md +++ /dev/null @@ -1,88 +0,0 @@ - - - - -# How to Deploy a Sulu Project - -```php -require 'recipe/sulu.php'; -``` - -[Source](/recipe/sulu.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Sulu application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Sulu** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [deploy:cache:clear](/docs/recipe/symfony.md#deploycacheclear) – Clears cache -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The sulu recipe is based on the [symfony](/docs/recipe/symfony.md) recipe. - -## Configuration -### bin/websiteconsole -[Source](https://github.com/deployphp/deployer/blob/master/recipe/sulu.php#L13) - - - -```php title="Default value" -return parse('{{bin/php}} {{release_or_current_path}}/bin/websiteconsole --no-interaction'); -``` - - - -## Tasks - -### phpcr:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/sulu.php#L18) - -Migrates PHPCR. - - - - -### deploy:website:cache:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/sulu.php#L23) - -Clears cache. - - - - -### deploy:website:cache:warmup -[Source](https://github.com/deployphp/deployer/blob/master/recipe/sulu.php#L28) - -Warmups cache. - - - - diff --git a/docs/recipe/symfony.md b/docs/recipe/symfony.md deleted file mode 100644 index e169ff439..000000000 --- a/docs/recipe/symfony.md +++ /dev/null @@ -1,202 +0,0 @@ - - - - -# How to Deploy a Symfony Application - -```php -require 'recipe/symfony.php'; -``` - -[Source](/recipe/symfony.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Symfony application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Symfony** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [deploy:cache:clear](/docs/recipe/symfony.md#deploycacheclear) – Clears cache -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The symfony recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### symfony_version -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L9) - - - -```php title="Default value" -$result = run('{{bin/console}} --version'); -preg_match_all('/(\d+\.?)+/', $result, $matches); -return $matches[0][0] ?? 5.0; -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L15) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -[ - 'var/log', -] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L19) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -[ - '.env.local', -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L23) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -[ - 'var', - 'var/cache', - 'var/log', - 'var/sessions', -] -``` - - -### log_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L30) - - - -```php title="Default value" -'var/log/*.log' -``` - - -### migrations_config -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L32) - - - - - -### doctrine_schema_validate_config -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L34) - - - - - -### bin/console -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L36) - - - -```php title="Default value" -'{{bin/php}} {{release_or_current_path}}/bin/console' -``` - - -### console_options -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L38) - - - -```php title="Default value" -return '--no-interaction'; -``` - - - -## Tasks - -### database:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L43) - -Migrates database. - - - - -### doctrine:schema:validate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L53) - -Validate the Doctrine mapping files. - - - - -### deploy:cache:clear -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L58) - -Clears cache. - - - - -### deploy:env -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L67) - -Optimize environment variables. - - - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/symfony.php#L74) - -Deploys project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:cache:clear](/docs/recipe/symfony.md#deploycacheclear) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/typo3.md b/docs/recipe/typo3.md deleted file mode 100644 index ebd8bdf92..000000000 --- a/docs/recipe/typo3.md +++ /dev/null @@ -1,124 +0,0 @@ - - - - -# How to Deploy a TYPO3 Project - -```php -require 'recipe/typo3.php'; -``` - -[Source](/recipe/typo3.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your TYPO3 application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **TYPO3** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The typo3 recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### typo3_webroot -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L12) - -DocumentRoot / WebRoot for the TYPO3 installation - -```php title="Default value" -'Web' -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L27) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Shared directories - -```php title="Default value" -[ - '{{typo3_webroot}}/fileadmin', - '{{typo3_webroot}}/typo3temp', - '{{typo3_webroot}}/uploads', -] -``` - - -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L36) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - -Shared files - -```php title="Default value" -[ - '{{typo3_webroot}}/.htaccess', -] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L43) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -Writeable directories - -```php title="Default value" -[ - '{{typo3_webroot}}/fileadmin', - '{{typo3_webroot}}/typo3temp', - '{{typo3_webroot}}/typo3conf', - '{{typo3_webroot}}/uploads', -] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L18) - -Deploys your project. - -Main TYPO3 task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/wordpress.md b/docs/recipe/wordpress.md deleted file mode 100644 index 418d9b7c2..000000000 --- a/docs/recipe/wordpress.md +++ /dev/null @@ -1,101 +0,0 @@ - - - - -# How to Deploy a WordPress Project - -```php -require 'recipe/wordpress.php'; -``` - -[Source](/recipe/wordpress.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your WordPress application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **WordPress** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The wordpress recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/wordpress.php#L9) - -Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['wp-config.php'] -``` - - -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/wordpress.php#L10) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - - - -```php title="Default value" -['wp-content/uploads'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/wordpress.php#L11) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - - - -```php title="Default value" -['wp-content/uploads'] -``` - - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/wordpress.php#L14) - -Deploys your project. - - - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/yii.md b/docs/recipe/yii.md deleted file mode 100644 index 1e9c97010..000000000 --- a/docs/recipe/yii.md +++ /dev/null @@ -1,101 +0,0 @@ - - - - -# How to Deploy a Yii2 Project - -```php -require 'recipe/yii.php'; -``` - -[Source](/recipe/yii.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Yii2 application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Yii2** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [deploy:migrate](/docs/recipe/yii.md#deploymigrate) – Runs Yii2 migrations for your project -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The yii recipe is based on the [common](/docs/recipe/common.md) recipe. - -## Configuration -### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/yii.php#L10) - -Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. - -Yii shared dirs - -```php title="Default value" -['runtime'] -``` - - -### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/yii.php#L13) - -Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. - -Yii writable dirs - -```php title="Default value" -['runtime'] -``` - - - -## Tasks - -### deploy:migrate -[Source](https://github.com/deployphp/deployer/blob/master/recipe/yii.php#L16) - -Runs Yii2 migrations for your project. - - - - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/yii.php#L24) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:migrate](/docs/recipe/yii.md#deploymigrate) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/recipe/zend_framework.md b/docs/recipe/zend_framework.md deleted file mode 100644 index f57d1f10d..000000000 --- a/docs/recipe/zend_framework.md +++ /dev/null @@ -1,66 +0,0 @@ - - - - -# How to Deploy a Zend Framework Project - -```php -require 'recipe/zend_framework.php'; -``` - -[Source](/recipe/zend_framework.php) - -Deployer is a free and open source deployment tool written in PHP. -It helps you to deploy your Zend Framework application to a server. -It is very easy to use and has a lot of features. - -Three main features of Deployer are: -- **Provisioning** - provision your server for you. -- **Zero downtime deployment** - deploy your application without a downtime. -- **Rollbacks** - rollback your application to a previous version, if something goes wrong. - -Additionally, Deployer has a lot of other features, like: -- **Easy to use** - Deployer is very easy to use. It has a simple and intuitive syntax. -- **Fast** - Deployer is very fast. It uses parallel connections to deploy your application. -- **Secure** - Deployer uses SSH to connect to your server. -- **Supports all major PHP frameworks** - Deployer supports all major PHP frameworks. - -You can read more about Deployer in [Getting Started](/docs/getting-started.md). - -The [deploy](#deploy) task of **Zend Framework** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:env](/docs/recipe/symfony.md#deployenv) – Optimize environment variables - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – Deploys your project - - -The zend_framework recipe is based on the [common](/docs/recipe/common.md) recipe. - - -## Tasks - -### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/zend_framework.php#L13) - -Deploys your project. - -Main task - - -This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:publish](/docs/recipe/common.md#deploypublish) - - diff --git a/docs/selector.md b/docs/selector.md deleted file mode 100644 index 349f88377..000000000 --- a/docs/selector.md +++ /dev/null @@ -1,198 +0,0 @@ -# Selector - -Deployer uses the selector to choose hosts. Each host can have a set of labels. -Labels are key-value pairs. - -For example, `stage: production` or `role: web`. - -You can use labels to select hosts. For example, `dep deploy stage=production` -will deploy to all hosts with `stage: production` label. - -Let's define two labels, **type** and **env**, to our hosts: - -```php -host('web.example.com') - ->setLabels([ - 'type' => 'web', - 'env' => 'prod', - ]); - -host('db.example.com') - ->setLabels([ - 'type' => 'db', - 'env' => 'prod', - ]); -``` -or use `->addLables()` method to add labels to the existing host. - -Now let's define a task to check labels: - -```php -task('info', function () { - writeln('type:' . get('labels')['type'] . ' env:' . get('labels')['env']); -}); -``` - -Now we can run this task with a selector: - -```bash -$ dep info env=prod -task info -[web.example.com] type:web env:prod -[db.example.com] type:db env:prod -``` - -As you can see, Deployer will run this task on all hosts with the `env: prod` label. -And if we define only the `type` label, Deployer will run this task on the specified host. - -```bash -dep info type=web -task info -[web.example.com] type:web env:prod -``` - -## Selector syntax - -Label syntax is represented by [disjunctive normal form](https://en.wikipedia.org/wiki/Disjunctive_normal_form) -(**OR of ANDs**). -``` -(condition1 AND condition2) OR (condition3 AND condition4) -``` - -Each condition in the subquery that is represented by [conjunctive normal form](https://en.wikipedia.org/wiki/Conjunctive_normal_form) -``` -(condition1 OR condition2) AND (condition3 OR condition4) -``` - -### Explanation - -For example, `type=web,env=prod` is a selector of: `type=web` **OR** `env=prod`. - -```bash -$ dep info 'type=web,env=prod' -task info -[web.example.com] type:web env:prod -[db.example.com] type:db env:prod -``` - -As you can see, both hosts are selected (as both of them have the `env: prod` label). - -We can use `&` to define **AND**. For example, `type=web & env=prod` is a selector -for hosts with `type: web` **AND** `env: prod` labels. - -```bash -$ dep info 'type=web & env=prod' -task info -[web.example.com] type:web env:prod -``` - -We can use `|` to define **OR** in a subquery. For example, `type=web|db & env=prod` is a selector -for hosts with (`type: web` **OR** `type: db`) **AND** `env: prod` labels. - -```bash -$ dep info 'type=web|db & env=prod' -task info -[web.example.com] type:web env:prod -``` - -We can also use `!=` to negate a label. For example, `type!=web` is a selector for -all hosts which do not have a `type: web` label. - -```bash -$ dep info 'type!=web' -task info -[db.example.com] type:db env:prod -``` - -:::note -Deployer CLI can take a few selectors as arguments. For example, -`dep info type=web env=prod` is the same as `dep info 'type=web,env=prod'`. - -You can install bash autocompletion for Deployer CLI, which will help you to -write selectors. See [installation](installation.md) for more. -::: - -Deployer also has a few special selectors: - -- `all` - select all hosts -- `alias=...` - select host by alias - -If a selector does not contain an `=` sign, Deployer will assume that it is an alias. - -For example `dep info web.example.com` is the same as `dep info alias=web.example.com`. - -```bash -$ dep info web.example.com -task info -[web.example.com] type:web env:prod -``` - -```bash -$ dep info 'web.example.com' 'db.example.com' -$ # Same as: -$ dep info 'alias=web.example.com,alias=db.example.com' -```` - -## Using the select() function - -You can use the [select()](api.md#select) function to select hosts by selector in your PHP code. - -```php -task('info', function () { - $hosts = select('type=web|db,env=prod'); - foreach ($hosts as $host) { - writeln('type:' . $host->get('labels')['type'] . ' env:' . $host->get('labels')['env']); - } -}); -``` - -Or you can use the [on()](api.md#on) function to run a task on selected hosts. - -```php -task('info', function () { - on(select('all'), function () { - writeln('type:' . get('labels')['type'] . ' env:' . get('labels')['env']); - }); -}); -``` - -## Task selectors - -To restrict a task to run only on selected hosts, you can use the [select()](tasks.md#select) method. - -```php -task('info', function () { - // ... -})->select('type=web|db,env=prod'); -``` - -## Labels in YAML - -You can also define labels in a YAML recipe. For example: - -```yaml -hosts: - web.example.com: - remote_user: deployer - env: - environment: production - labels: - env: prod -``` - -But make sure to distinguish between the `env` and `labels.env` keys. -`env` is a configuration key, and `labels.env` is a label. - -```php -task('info', function () { - writeln('env:' . get('env')['environment'] . ' labels.env:' . get('labels')['env']); -}); -``` - -Will print: - -```bash -$ dep info env=prod -task info -[web.example.com] env:production labels.env:prod -``` diff --git a/docs/sidebar.js b/docs/sidebar.js deleted file mode 100644 index c465bc5ab..000000000 --- a/docs/sidebar.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = [ - "installation", - "getting-started", - "basics", - { - type: "category", - label: "Main Concepts", - items: ["hosts", "tasks", "selector"], - }, - "ci-cd", - "yaml", - "cli", - "api", - { - type: "category", - label: "Other", - items: ["avoid-php-fpm-reloading", "UPGRADE", "KNOWN_BUGS"], - }, -]; diff --git a/docs/tasks.md b/docs/tasks.md deleted file mode 100644 index 0c07ed515..000000000 --- a/docs/tasks.md +++ /dev/null @@ -1,136 +0,0 @@ -# Tasks - -Define a task by using the [task](api.md#task) function. Also, you can give a description -for a task with the [desc](api.md#desc) function called before _task_: - -```php -desc('My task'); -task('my_task', function () { - .... -}); -``` - -To get the task or override task config, call the _task_ function without the second argument: - -```php -task('my_task')->disable(); -``` - -## Task config - -### desc() - -Sets task's description. - -```php -task('deploy', function () { - // ... -})->desc('Task description'); -``` - -Same as using [desc()](api.md#desc) function helper: - -```php -desc('Task description'); -task('deploy', function () { - // ... -}); -``` - -### once() - -Sets the task to run only on one of the selected hosts. - -### oncePerNode() - -Sets the task to run only on **one node** of the selected hosts. - -The node is identified by its [hostname](hosts.md#hostname). For instance, -multiple hosts might deploy to a single physical machine (with a unique hostname). - - -```php -host('foo')->setHostname('example.com'); -host('bar')->setHostname('example.com'); -host('pro')->setHostname('another.com'); - -task('apt:update', function () { - // This task will be executed twice, only on "foo" and "pro" hosts. - run('apt-get update'); -})->oncePerNode(); -``` - -### hidden() - -Hides the task from CLI usage page. - -### addBefore() - -Adds a before hook to the task. - -### addAfter() - -Adds an after hook to the task. - -### limit() - -Limits the number of hosts the task will be executed on in parallel. - -Default is unlimited (runs the task on all hosts in parallel). - -### select() - -Sets the task's host selector. - -### addSelector() - -Adds the task's selector. - -### verbose() - -Makes the task always verbose, as if the `-v` option is persistently enabled. - -### disable() - -Disables the task. the task will not be executed. - -### enable() - -Enables the task. - -## Task grouping - -You can combine tasks in groups: - -```php -task('deploy', [ - 'deploy:prepare', - 'deploy:update_code', - 'deploy:vendors', - 'deploy:symlink', - 'cleanup' -]); -``` - -## Task hooks - -You can define tasks to be run before or after specific tasks. - -```php -task('deploy:done', function () { - writeln('Deploy done!'); -}); - -after('deploy', 'deploy:done'); -``` - -After the `deploy` task executed, `deploy:done` will be triggered. - -:::note -You can see which hooks are enabled via the **dep tree** command. - -``` -dep tree deploy -``` - -::: diff --git a/docs/yaml.md b/docs/yaml.md deleted file mode 100644 index d597ec121..000000000 --- a/docs/yaml.md +++ /dev/null @@ -1,31 +0,0 @@ -# YAML - -Deployer supports recipes written in YAML. For validating the structure, Deployer uses -the JSON Schema declared in [schema.json](https://github.com/deployphp/deployer/blob/master/src/schema.json). - -Here is an example of a YAML recipe: - -```yaml -import: - - recipe/laravel.php - -config: - repository: "git@github.com:example/example.com.git" - remote_user: deployer - -hosts: - example.com: - deploy_path: "~/example" - -tasks: - build: - - cd: "{{release_path}}" - - run: "npm run build" - -after: - deploy:failed: deploy:unlock -``` - -YAML recipes can include recipes written in PHP. For example, some tasks maybe written in PHP and imported into YAML. - -Conversely, it's also possible to import a YAML recipe from PHP using the [import()](api.md#import) function. diff --git a/phpstan.neon b/phpstan.neon deleted file mode 100644 index cd31f8b37..000000000 --- a/phpstan.neon +++ /dev/null @@ -1,18 +0,0 @@ -includes: - - tests/phpstan-baseline.neon - -parameters: - level: 5 - paths: - - src - - recipe - - contrib - - ignoreErrors: - - "#^Constant DEPLOYER_VERSION not found\\.$#" - - "#^Constant DEPLOYER_BIN not found\\.$#" - - "#CpanelPhp#" - - "#AMQPMessage#" - - excludePaths: - - src/Component/PharUpdate/* diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100644 index 9d98c66bf..000000000 --- a/phpunit.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - src/ - recipe/ - - - vendor/ - bin/ - - - - - tests/src/ - - - tests/legacy/ - - - tests/joy/ - - - diff --git a/src/Collection/Collection.php b/src/Collection/Collection.php deleted file mode 100644 index 165a663d3..000000000 --- a/src/Collection/Collection.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. - */ - -namespace Deployer\Collection; - -use Countable; -use IteratorAggregate; - -class Collection implements Countable, IteratorAggregate -{ - /** - * @var array - */ - protected $values = []; - - public function all(): array - { - return $this->values; - } - - /** - * @return mixed - */ - public function get(string $name) - { - if ($this->has($name)) { - return $this->values[$name]; - } else { - $this->throwNotFound($name); - } - } - - public function has(string $name): bool - { - return array_key_exists($name, $this->values); - } - - /** - * @param mixed $object - */ - public function set(string $name, $object) - { - $this->values[$name] = $object; - } - - public function remove(string $name): void - { - if ($this->has($name)) { - unset($this->values[$name]); - } else { - $this->throwNotFound($name); - } - } - - public function count(): int - { - return count($this->values); - } - - public function select(callable $callback): array - { - $values = []; - - foreach ($this->values as $key => $value) { - if ($callback($value, $key)) { - $values[$key] = $value; - } - } - - return $values; - } - - /** - * @return \ArrayIterator|\Traversable - */ - #[\ReturnTypeWillChange] - public function getIterator() - { - return new \ArrayIterator($this->values); - } - - protected function throwNotFound(string $name): void - { - throw new \InvalidArgumentException("Element \"$name\" not found in collection."); - } -} diff --git a/src/Command/BlackjackCommand.php b/src/Command/BlackjackCommand.php deleted file mode 100644 index 2b19fb243..000000000 --- a/src/Command/BlackjackCommand.php +++ /dev/null @@ -1,399 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface as Input; -use Symfony\Component\Console\Output\OutputInterface as Output; -use Symfony\Component\Console\Question\ChoiceQuestion; -use Symfony\Component\Console\Style\SymfonyStyle; - -use function Deployer\Support\array_flatten; - -class BlackjackCommand extends Command -{ - use CommandCommon; - - /** - * @var Input - */ - private $input; - - /** - * @var Output - */ - private $output; - - public function __construct() - { - parent::__construct('blackjack'); - $this->setDescription('Play blackjack'); - } - - protected function execute(Input $input, Output $output): int - { - $this->input = $input; - $this->output = $output; - $this->telemetry(); - $io = new SymfonyStyle($this->input, $this->output); - - if (getenv('COLORTERM') === 'truecolor') { - $this->print("\x1b[38;2;255;95;109m╭\x1b[39m\x1b[38;2;255;95;107m─\x1b[39m\x1b[38;2;255;96;106m─\x1b[39m\x1b[38;2;255;96;104m─\x1b[39m\x1b[38;2;255;96;103m─\x1b[39m\x1b[38;2;255;97;101m─\x1b[39m\x1b[38;2;255;97;100m─\x1b[39m\x1b[38;2;255;97;99m─\x1b[39m\x1b[38;2;255;98;97m─\x1b[39m\x1b[38;2;255;100;98m─\x1b[39m\x1b[38;2;255;102;98m─\x1b[39m\x1b[38;2;255;104;98m─\x1b[39m\x1b[38;2;255;106;99m─\x1b[39m\x1b[38;2;255;108;99m─\x1b[39m\x1b[38;2;255;110;99m─\x1b[39m\x1b[38;2;255;112;100m─\x1b[39m\x1b[38;2;255;114;100m─\x1b[39m\x1b[38;2;255;116;100m─\x1b[39m\x1b[38;2;255;118;100m─\x1b[39m\x1b[38;2;255;120;101m─\x1b[39m\x1b[38;2;255;122;101m─\x1b[39m\x1b[38;2;255;124;101m─\x1b[39m\x1b[38;2;255;126;102m╮\x1b[39m"); - $this->print("\x1b[38;2;255;128;102m│\x1b[39m \x1b[38;2;255;130;102m│\x1b[39m"); - $this->print("\x1b[38;2;255;132;103m│\x1b[39m \x1b[38;2;255;134;103mW\x1b[39m\x1b[38;2;255;136;103me\x1b[39m\x1b[38;2;255;138;104ml\x1b[39m\x1b[38;2;255;140;104mc\x1b[39m\x1b[38;2;255;142;104mo\x1b[39m\x1b[38;2;255;144;104mm\x1b[39m\x1b[38;2;255;146;105me\x1b[39m\x1b[38;2;255;148;105m!\x1b[39m \x1b[38;2;255;150;105m│\x1b[39m"); - $this->print("\x1b[38;2;255;152;106m│\x1b[39m \x1b[38;2;255;153;106m│\x1b[39m"); - $this->print("\x1b[38;2;255;155;106m╰\x1b[39m\x1b[38;2;255;157;107m─\x1b[39m\x1b[38;2;255;159;107m─\x1b[39m\x1b[38;2;255;161;107m─\x1b[39m\x1b[38;2;255;163;108m─\x1b[39m\x1b[38;2;255;165;108m─\x1b[39m\x1b[38;2;255;166;108m─\x1b[39m\x1b[38;2;255;168;108m─\x1b[39m\x1b[38;2;255;170;109m─\x1b[39m\x1b[38;2;255;172;109m─\x1b[39m\x1b[38;2;255;174;109m─\x1b[39m\x1b[38;2;255;176;110m─\x1b[39m\x1b[38;2;255;177;110m─\x1b[39m\x1b[38;2;255;179;110m─\x1b[39m\x1b[38;2;255;181;111m─\x1b[39m\x1b[38;2;255;183;111m─\x1b[39m\x1b[38;2;255;185;111m─\x1b[39m\x1b[38;2;255;186;111m─\x1b[39m\x1b[38;2;255;188;112m─\x1b[39m\x1b[38;2;255;190;112m─\x1b[39m\x1b[38;2;255;192;112m─\x1b[39m\x1b[38;2;255;193;113m─\x1b[39m\x1b[38;2;255;195;113m╯\x1b[0m"); - } else { - $this->print("╭─────────────────────╮"); - $this->print("│ │"); - $this->print("│ Welcome! │"); - $this->print("│ │"); - $this->print("╰─────────────────────╯"); - } - - $money = 100; - - if (md5(strval(getenv('MONEY'))) === '5a7c2f336d0cc43b68951e75cdffe333') { - $money += 25; - $this->print('You got an extra $25.'); - } elseif (md5(strval(getenv('MONEY'))) === '530029252abcbda4a2a2069036ccc7fc') { - $money += 100; - $this->print('You got an extra $100.'); - } elseif (md5(strval(getenv('MONEY'))) === '1aa827a06ecbfa5d6fa7c62ad245f3a3') { - $money = 100000; - } - - $hasWatch = true; - $orderWhiskey = false; - $whiskeyLevel = 0; - - $deck = $this->newDeck(); - $graveyard = []; - $dealersHand = []; - $playersHand = []; - shuffle($deck); - $deal = function () use (&$deck, &$graveyard) { - if (count($deck) == 0) { - shuffle($graveyard); - $deck = $graveyard; - $graveyard = []; - } - return array_pop($deck); - }; - - start: - $this->print("You have $$money."); - if ($money > 0) { - $bet = (int) $io->ask('Your bet', '5'); - if ($bet <= 0) { - goto start; - } - if ($bet > $money) { - goto start; - } - } elseif ($hasWatch) { // @phpstan-ignore-line - $answer = $io->askQuestion(new ChoiceQuestion('?', ['leave', '- Here, take my watch! [$25]'], 0)); - if ($answer == 'leave') { - goto leave; - } else { - $hasWatch = false; - $money = 25; - $bet = 25; - } - } else { - goto leave; - } - - $graveyard = array_merge($graveyard, $dealersHand); - $dealersHand = []; - $dealersHand[] = $deal(); - $this->print("Dealers hand:"); - $this->printHand($dealersHand); - - $graveyard = array_merge($graveyard, $playersHand); - $playersHand = []; - $playersHand[] = $deal(); - $playersHand[] = $deal(); - $this->print("Your hand:"); - $this->printHand($playersHand, 2); - - while (true) { - $question = new ChoiceQuestion('Your turn', ['hit', 'stand'], 0); - $answer = $io->askQuestion($question); - - if ($answer === 'hit') { - $playersHand[] = $deal(); - usleep(200000); - } - - if ($answer === 'stand') { - break; - } - - $this->printHand($playersHand); - $handValue = self::handValue($playersHand); - - if ($handValue > 21) { - $this->print("You got $handValue."); - $this->print("Bust!"); - $this->print("-$$bet"); - $money -= $bet; - goto nextRound; - } - } - - $this->printHand($dealersHand); - $this->print("Dealer: " . self::handValue($dealersHand)); - sleep(1); - - while (self::handValue($dealersHand) <= 17) { - $dealersHand[] = $deal(); - $this->printHand($dealersHand); - $this->print("Dealer: " . self::handValue($dealersHand)); - sleep(1); - } - - $d = self::handValue($dealersHand); - $p = self::handValue($playersHand); - $this->print("You got $p and dealer $d."); - - if ($d > 21 || $p > $d) { - $this->print("You won!"); - $this->print("+$$bet"); - $money += $bet; - } elseif ($p < $d) { - $this->print("You lose!"); - $this->print("-$$bet"); - $money -= $bet; - } else { - $this->print("Push!"); - } - - nextRound: - $choices = ['continue', 'leave']; - if ($orderWhiskey) { - $orderWhiskey = false; - $whiskeyLevel = 4; - $this->print(); - $this->print('The waitress brought whiskey and says:'); - $this->print(' - Your whiskey, sir.'); - if ($money >= 5) { - array_push($choices, 'tip the waitress [$5]'); - } - } elseif ($money >= 5) { - array_push($choices, 'order whiskey [$5]'); - } - - if ($whiskeyLevel > 0) { - $this->printWhiskey($whiskeyLevel); - $whiskeyLevel--; - } - $answer = $io->askQuestion(new ChoiceQuestion('?', $choices, 0)); - - if ($answer == 'leave') { - goto leave; - } elseif ($money >= 5 && $answer == 'order whiskey [$5]') { - $orderWhiskey = true; - $this->print('You say:'); - $this->print(' - Whiskey, please.'); - $money -= 5; - } elseif ($money >= 5 && $answer == 'tip the waitress [$5]') { - $this->print('The waitress says:'); - $this->print(' - Thank you, sir!'); - $money -= 5; - } - $this->print(); - $this->print("=====> Next round <====="); - goto start; - - leave: - if ($money >= 5) { - $answer = $io->ask('Leave a $5 tip to the dealer?', 'yes'); - if ($answer === 'yes') { - $this->print("You can leave a tip here:"); - $this->print(); - $this->print("- https://github.com/sponsors/antonmedv"); - $this->print("- https://paypal.me/antonmedv"); - $this->print(); - } - } - $this->print('Thanks for playing, Come again!'); - return 0; - } - - private function newDeck(): array - { - $deck = []; - foreach (['♠', '♣', '♥', '♦'] as $suit) { - for ($i = 2; $i <= 10; $i++) { - $deck[] = [strval($i), $suit]; - } - $deck[] = ['J', $suit]; - $deck[] = ['Q', $suit]; - $deck[] = ['K', $suit]; - $deck[] = ['A', $suit]; - } - return $deck; - } - - public static function handValue(array $hand): int - { - $aces = 0; - $value = 0; - foreach ($hand as [$rank]) { - switch ($rank) { - case '2': - $value += 2; - break; - case '3': - $value += 3; - break; - case '4': - $value += 4; - break; - case '5': - $value += 5; - break; - case '6': - $value += 6; - break; - case '7': - $value += 7; - break; - case '8': - $value += 8; - break; - case '9': - $value += 9; - break; - case '10': - case 'J': - case 'Q': - case 'K': - $value += 10; - break; - case 'A': - $aces++; - break; - } - } - $variants = [$value]; - while ($aces-- > 0) { - $variants = array_flatten(array_map(function ($v) { - return [$v + 1, $v + 11]; - }, $variants)); - } - $sum = $variants[0]; - for ($i = 1; $i < count($variants); $i++) { - if ($variants[$i] <= 21) { - $sum = $variants[$i]; - } else { - break; - } - } - return $sum; - } - - private function print(string $text = "") - { - $this->output->writeln(" $text"); - } - - private function printHand(array $hand, int $offset = 1) - { - $cards = []; - for ($i = 0; $i < count($hand) - $offset; $i++) { - [$rank] = $hand[$i]; - $cards[] = [ - "┌───", - "│" . str_pad($rank, 3), - "│ ", - "│ ", - "│ ", - "│ ", - "└───", - ]; - } - - for (; $i < count($hand); $i++) { - [$rank, $suit] = $hand[$i]; - $cards[] = [ - "┌───────┐", - "│" . str_pad($rank, 7) . "│", - "│ │", - "│ " . $suit . " │", - "│ │", - "│" . str_pad($rank, 7, " ", STR_PAD_LEFT) . "│", - "└───────┘", - ]; - } - - for ($i = 0; $i < 7; $i++) { - $this->output->write(" "); - foreach ($cards as $lines) { - $this->output->write($lines[$i]); - } - $this->output->write("\n"); - } - } - - private function printWhiskey(int $whiskeyLevel) - { - if ($whiskeyLevel == 4) { - echo << - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Deployer; -use Deployer\Support\Reporter; - -trait CommandCommon -{ - /** - * Collecting anonymous stat helps Deployer team improve developer experience. - * If you are not comfortable with this, you will always be able to disable this - * by setting DO_NOT_TRACK environment variable to `1`. - * @codeCoverageIgnore - */ - protected function telemetry(array $data = []): void - { - if (getenv('DO_NOT_TRACK') === 'true') { - return; - } - try { - Reporter::report(array_merge([ - 'command_name' => $this->getName(), - 'deployer_version' => DEPLOYER_VERSION, - 'deployer_phar' => Deployer::isPharArchive(), - 'php_version' => phpversion(), - 'os' => defined('PHP_OS_FAMILY') ? PHP_OS_FAMILY : (stristr(PHP_OS, 'DAR') ? 'OSX' : (stristr(PHP_OS, 'WIN') ? 'WIN' : (stristr(PHP_OS, 'LINUX') ? 'LINUX' : PHP_OS))), - ], $data)); - } catch (\Throwable $e) { - return; - } - } - -} diff --git a/src/Command/ConfigCommand.php b/src/Command/ConfigCommand.php deleted file mode 100644 index 6db5624fb..000000000 --- a/src/Command/ConfigCommand.php +++ /dev/null @@ -1,79 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Deployer; -use Deployer\Exception\WillAskUser; -use Deployer\Task\Context; -use Symfony\Component\Console\Input\InputInterface as Input; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\NullOutput; -use Symfony\Component\Console\Output\OutputInterface as Output; -use Symfony\Component\Yaml\Yaml; - -class ConfigCommand extends SelectCommand -{ - public function __construct(Deployer $deployer) - { - parent::__construct('config', $deployer); - $this->setDescription('Get all configuration options for hosts'); - } - - protected function configure() - { - parent::configure(); - $this->addOption('format', null, InputOption::VALUE_OPTIONAL, 'The output format (json, yaml)', 'yaml'); - $this->getDefinition()->getArgument('selector')->setDefault(['all']); - } - - protected function execute(Input $input, Output $output): int - { - $this->deployer->input = $input; - $this->deployer->output = new NullOutput(); - $hosts = $this->selectHosts($input, $output); - $data = []; - $keys = $this->deployer->config->keys(); - define('DEPLOYER_NO_ASK', true); - foreach ($hosts as $host) { - Context::push(new Context($host)); - $values = []; - foreach ($keys as $key) { - try { - $values[$key] = $host->get($key); - } catch (WillAskUser $exception) { - $values[$key] = ['ask' => $exception->getMessage()]; - } catch (\Throwable $exception) { - $values[$key] = ['error' => $exception->getMessage()]; - } - } - foreach ($host->config()->persist() as $k => $v) { - $values[$k] = $v; - } - ksort($values); - $data[$host->getAlias()] = $values; - Context::pop(); - } - $format = $input->getOption('format'); - switch ($format) { - case 'json': - $output->writeln(json_encode($data, JSON_PRETTY_PRINT)); - break; - - case 'yaml': - $output->write(Yaml::dump($data)); - break; - - default: - throw new \Exception("Unknown format: $format."); - } - return 0; - } -} diff --git a/src/Command/CustomOption.php b/src/Command/CustomOption.php deleted file mode 100644 index 1d043e3dd..000000000 --- a/src/Command/CustomOption.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Host\Host; - -trait CustomOption -{ - /** - * @param Host[] $hosts - * @param string[] $options - */ - protected function applyOverrides(array $hosts, array $options) - { - $override = []; - foreach ($options as $option) { - [$name, $value] = explode('=', $option); - $value = $this->castValueToPhpType(trim($value)); - $override[trim($name)] = $value; - } - - foreach ($hosts as $host) { - foreach ($override as $key => $value) { - $host->set($key, $value); - } - } - } - - /** - * @param mixed $value - * @return bool|mixed - */ - protected function castValueToPhpType($value) - { - switch ($value) { - case 'true': - return true; - case 'false': - return false; - default: - return $value; - } - } -} diff --git a/src/Command/InitCommand.php b/src/Command/InitCommand.php deleted file mode 100644 index 25643ac2c..000000000 --- a/src/Command/InitCommand.php +++ /dev/null @@ -1,263 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\Process\Exception\RuntimeException; -use Symfony\Component\Process\PhpProcess; -use Symfony\Component\Process\Process; - -class InitCommand extends Command -{ - use CommandCommon; - - protected function configure() - { - $this - ->setName('init') - ->setDescription('Initialize deployer in your project') - ->addOption('path', 'p', InputOption::VALUE_OPTIONAL, 'Recipe path'); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - if (getenv('COLORTERM') === 'truecolor') { - $output->write( - <<write( - <<getOption('path'); - - $language = $io->choice('Select recipe language', ['php', 'yaml'], 'php'); - if (empty($recipePath)) { - $recipePath = "deploy.$language"; - } - - // Avoid accidentally override of existing file. - if (file_exists($recipePath)) { - $io->warning("$recipePath already exists"); - if (!$io->confirm("Do you want to override the existing file?", false)) { - $io->block('👍🏻'); - exit(1); - } - } - - // Template - $template = $io->choice('Select project template', $this->recipes(), 'common'); - - // Repo - $default = ''; - try { - $process = Process::fromShellCommandline('git remote get-url origin'); - $default = $process->mustRun()->getOutput(); - $default = trim($default); - } catch (RuntimeException $e) { - } - $repository = $io->ask('Repository', $default); - - // Guess host - if (preg_match('/github.com:(?[A-Za-z0-9_.\-]+)\//', $repository, $m)) { - $org = $m['org']; - $tempHostFile = tempnam(sys_get_temp_dir(), 'temp-host-file'); - $php = new PhpProcess( - <<blog, PHP_URL_HOST); - file_put_contents('$tempHostFile', \$host); - EOF, - ); - $php->start(); - } - - // Project - $default = ''; - try { - $process = Process::fromShellCommandline('basename "$PWD"'); - $default = $process->mustRun()->getOutput(); - $default = trim($default); - } catch (RuntimeException $e) { - } - $project = $io->ask('Project name', $default); - - // Hosts - $host = null; - if (isset($tempHostFile)) { - $host = file_get_contents($tempHostFile); - } - $hostsString = $io->ask('Hosts (comma separated)', $host); - if ($hostsString !== null) { - $hosts = explode(',', $hostsString); - } else { - $hosts = []; - } - - file_put_contents($recipePath, $this->$language($template, $project, $repository, $hosts)); - - $this->telemetry(); - $output->writeln(sprintf( - 'Successfully created %s', - $recipePath, - )); - return 0; - } - - private function php(string $template, string $project, string $repository, array $hosts): string - { - $h = ""; - foreach ($hosts as $host) { - $h .= "host('{$host}')\n" . - " ->set('remote_user', 'deployer')\n" . - " ->set('deploy_path', '~/{$project}');\n"; - } - - return <<getAdditionalConfigs($template); - - return <<isDot()) { - continue; - } - if ($fileinfo->isDir()) { - continue; - } - - $recipe = pathinfo($fileinfo->getFilename(), PATHINFO_FILENAME); - - if ($recipe === 'README') { - continue; - } - - $recipes[] = $recipe; - } - - sort($recipes); - return $recipes; - } -} diff --git a/src/Command/MainCommand.php b/src/Command/MainCommand.php deleted file mode 100644 index 63772fddf..000000000 --- a/src/Command/MainCommand.php +++ /dev/null @@ -1,203 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Configuration\Configuration; -use Deployer\Deployer; -use Deployer\Exception\Exception; -use Deployer\Exception\GracefulShutdownException; -use Deployer\Executor\Planner; -use Deployer\Utility\Httpie; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Input\InputInterface as Input; -use Symfony\Component\Console\Input\InputOption as Option; -use Symfony\Component\Console\Output\OutputInterface as Output; - -use function Deployer\Support\find_config_line; -use function Deployer\warning; - -class MainCommand extends SelectCommand -{ - use CustomOption; - use CommandCommon; - - public function __construct(string $name, ?string $description, Deployer $deployer) - { - parent::__construct($name, $deployer); - if ($description) { - $this->setDescription($description); - } - } - - protected function configure() - { - parent::configure(); - - // Add global options defined with `option()` func. - $this->getDefinition()->addOptions($this->deployer->inputDefinition->getOptions()); - - $this->addOption( - 'option', - 'o', - Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, - 'Set configuration option', - ); - $this->addOption( - 'limit', - 'l', - Option::VALUE_REQUIRED, - 'How many tasks to run in parallel?', - ); - $this->addOption( - 'no-hooks', - null, - Option::VALUE_NONE, - 'Run tasks without after/before hooks', - ); - $this->addOption( - 'plan', - null, - Option::VALUE_NONE, - 'Show execution plan', - ); - $this->addOption( - 'start-from', - null, - Option::VALUE_REQUIRED, - 'Start execution from this task', - ); - $this->addOption( - 'log', - null, - Option::VALUE_REQUIRED, - 'Write log to a file', - ); - $this->addOption( - 'profile', - null, - Option::VALUE_REQUIRED, - 'Write profile to a file', - ); - } - - protected function execute(Input $input, Output $output): int - { - $this->deployer->input = $input; - $this->deployer->output = $output; - $this->deployer['log'] = $input->getOption('log'); - $this->telemetry([ - 'project_hash' => empty($this->deployer->config['repository']) ? null : sha1($this->deployer->config['repository']), - 'hosts_count' => $this->deployer->hosts->count(), - 'recipes' => $this->deployer->config->get('recipes', []), - ]); - - $hosts = $this->selectHosts($input, $output); - $this->applyOverrides($hosts, $input->getOption('option')); - - // Save selected_hosts for selectedHosts() func. - $hostsAliases = []; - foreach ($hosts as $host) { - $hostsAliases[] = $host->getAlias(); - } - // Save selected_hosts per each host, and not globally. Otherwise it will - // not be accessible for workers. - foreach ($hosts as $host) { - $host->set('selected_hosts', $hostsAliases); - } - - $plan = $input->getOption('plan') ? new Planner($output, $hosts) : null; - - $this->deployer->scriptManager->setHooksEnabled(!$input->getOption('no-hooks')); - $startFrom = $input->getOption('start-from'); - if ($startFrom && !$this->deployer->tasks->has($startFrom)) { - throw new Exception("Task $startFrom does not exist."); - } - $skippedTasks = []; - $tasks = $this->deployer->scriptManager->getTasks($this->getName(), $startFrom, $skippedTasks); - - if (empty($tasks)) { - throw new Exception('No task will be executed, because the selected hosts do not meet the conditions of the tasks'); - } - - if (!$plan) { - $this->checkUpdates(); - $this->deployer->server->start(); - - if (!empty($skippedTasks)) { - foreach ($skippedTasks as $taskName) { - $output->writeln("skip $taskName"); - } - } - } - $exitCode = $this->deployer->master->run($tasks, $hosts, $plan); - - if ($plan) { - $plan->render(); - return 0; - } - - if ($exitCode === 0) { - $this->showBanner(); - return 0; - } - if ($exitCode === GracefulShutdownException::EXIT_CODE) { - return 1; - } - - // Check if we have tasks to execute on failure. - if ($this->deployer['fail']->has($this->getName())) { - $taskName = $this->deployer['fail']->get($this->getName()); - $tasks = $this->deployer->scriptManager->getTasks($taskName); - $this->deployer->master->run($tasks, $hosts); - } - - return $exitCode; - } - - private function checkUpdates() - { - try { - fwrite(STDERR, Httpie::get('https://deployer.org/check-updates/' . DEPLOYER_VERSION)->send()); - } catch (\Throwable $e) { - // Meh - } - } - - private function showBanner() - { - if (getenv('DO_NOT_SHOW_BANNER') === 'true') { - return; - } - - try { - $withColors = ''; - if (function_exists('posix_isatty') && posix_isatty(STDOUT)) { - $withColors = '_with_colors'; - } - fwrite(STDERR, Httpie::get("https://deployer.medv.io/banners/" . $this->getName() . $withColors)->send()); - } catch (\Throwable $e) { - // Meh - } - } - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - parent::complete($input, $suggestions); - if ($input->mustSuggestOptionValuesFor('start-from')) { - $taskNames = []; - foreach ($this->deployer->scriptManager->getTasks($this->getName()) as $task) { - $taskNames[] = $task->getName(); - } - $suggestions->suggestValues($taskNames); - } - } -} diff --git a/src/Command/RunCommand.php b/src/Command/RunCommand.php deleted file mode 100644 index 07139c733..000000000 --- a/src/Command/RunCommand.php +++ /dev/null @@ -1,91 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Deployer; -use Deployer\Task\Context; -use Deployer\Task\Task; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface as Input; -use Symfony\Component\Console\Input\InputOption as Option; -use Symfony\Component\Console\Output\OutputInterface as Output; - -use function Deployer\cd; -use function Deployer\get; -use function Deployer\has; -use function Deployer\run; -use function Deployer\test; - -class RunCommand extends SelectCommand -{ - use CustomOption; - - public function __construct(Deployer $deployer) - { - parent::__construct('run', $deployer); - $this->setDescription('Run any arbitrary command on hosts'); - } - - protected function configure() - { - $this->addArgument( - 'command-to-run', - InputArgument::REQUIRED, - 'Command to run on a remote host', - ); - parent::configure(); - $this->addOption( - 'option', - 'o', - Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, - 'Set configuration option', - ); - $this->addOption( - 'timeout', - 't', - Option::VALUE_REQUIRED, - 'Command timeout in seconds', - ); - } - - protected function execute(Input $input, Output $output): int - { - $this->deployer->input = $input; - $this->deployer->output = $output; - - $command = $input->getArgument('command-to-run') ?? ''; - $hosts = $this->selectHosts($input, $output); - $this->applyOverrides($hosts, $input->getOption('option')); - - $task = new Task($command, function () use ($input, $command) { - if (has('current_path')) { - $path = get('current_path'); - if (test("[ -d $path ]")) { - cd($path); - } - } - run($command, [ - 'real_time_output' => true, - 'timeout' => intval($input->getOption('timeout')), - ]); - }); - - foreach ($hosts as $host) { - try { - $task->run(new Context($host)); - } catch (\Throwable $exception) { - $this->deployer->messenger->renderException($exception, $host); - } - } - - return 0; - } -} diff --git a/src/Command/SelectCommand.php b/src/Command/SelectCommand.php deleted file mode 100644 index 23a07a7c8..000000000 --- a/src/Command/SelectCommand.php +++ /dev/null @@ -1,122 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Deployer; -use Deployer\Exception\ConfigurationException; -use Deployer\Exception\Exception; -use Deployer\Host\Host; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Formatter\OutputFormatterStyle; -use Symfony\Component\Console\Helper\QuestionHelper; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface as Input; -use Symfony\Component\Console\Output\OutputInterface as Output; -use Symfony\Component\Console\Question\ChoiceQuestion; - -abstract class SelectCommand extends Command -{ - /** - * @var Deployer - */ - protected $deployer; - - public function __construct(string $name, Deployer $deployer) - { - $this->deployer = $deployer; - parent::__construct($name); - } - - protected function configure() - { - $this->addArgument('selector', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Host selector'); - } - - /** - * @return Host[] - */ - protected function selectHosts(Input $input, Output $output): array - { - $output->getFormatter()->setStyle('success', new OutputFormatterStyle('green')); - if (!$output->isDecorated() && !defined('NO_ANSI')) { - define('NO_ANSI', 'true'); - } - $selector = Deployer::get()->config->get('default_selector', $input->getArgument('selector')); - $selectExpression = is_array($selector) ? implode(',', $selector) : $selector; - - if (empty($selectExpression)) { - if (count($this->deployer->hosts) === 0) { - throw new ConfigurationException("No host configured.\nSpecify at least one host: `localhost();`."); - } elseif (count($this->deployer->hosts) === 1) { - $hosts = $this->deployer->hosts->all(); - } elseif ($input->isInteractive()) { - $hostsAliases = []; - foreach ($this->deployer->hosts as $host) { - $hostsAliases[] = $host->getAlias(); - } - /** @var QuestionHelper $helper */ - $helper = $this->getHelper('question'); - $question = new ChoiceQuestion( - 'Select hosts: (comma separated)', - $hostsAliases, - ); - $question->setMultiselect(true); - $question->setErrorMessage('There is no "%s" host.'); - $answer = $helper->ask($input, $output, $question); - $answer = array_unique($answer); - $hosts = $this->deployer->hosts->select(function (Host $host) use ($answer) { - return in_array($host->getAlias(), $answer, true); - }); - } - } else { - $hosts = $this->deployer->selector->select($selectExpression); - } - - if (empty($hosts)) { - $message = 'No host selected.'; - if (!empty($selectExpression)) { - $message .= " Please, check your selector:\n\n $selectExpression"; - } - throw new Exception($message); - } - - return $hosts; - } - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - parent::complete($input, $suggestions); - if ($input->mustSuggestArgumentValuesFor('selector')) { - $selectors = ['all']; - $configs = []; - foreach ($this->deployer->hosts as $host) { - $configs[$host->getAlias()] = $host->config()->persist(); - } - foreach ($configs as $alias => $c) { - $selectors[] = $alias; - foreach ($c['labels'] ?? [] as $label => $value) { - $selectors[] = "$label=$value"; - } - } - $selectors = array_unique($selectors); - $suggestions->suggestValues($selectors); - } - if ($input->mustSuggestOptionValuesFor('option')) { - $values = []; - foreach ($this->deployer->config->keys() as $key) { - $values[] = $key . '='; - } - $suggestions->suggestValues($values); - } - } -} diff --git a/src/Command/SshCommand.php b/src/Command/SshCommand.php deleted file mode 100644 index 9001d3420..000000000 --- a/src/Command/SshCommand.php +++ /dev/null @@ -1,114 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Deployer; -use Deployer\Host\Localhost; -use Deployer\Task\Context; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Helper\QuestionHelper; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Question\ChoiceQuestion; - -/** - * @codeCoverageIgnore - */ -class SshCommand extends Command -{ - use CommandCommon; - - /** - * @var Deployer - */ - private $deployer; - - public function __construct(Deployer $deployer) - { - parent::__construct('ssh'); - $this->setDescription('Connect to host through ssh'); - $this->deployer = $deployer; - } - - protected function configure() - { - $this->addArgument( - 'hostname', - InputArgument::OPTIONAL, - 'Hostname', - ); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - $this->telemetry(); - $hostname = $input->getArgument('hostname'); - if (!empty($hostname)) { - $host = $this->deployer->hosts->get($hostname); - } else { - $hostsAliases = []; - foreach ($this->deployer->hosts as $host) { - if ($host instanceof Localhost) { - continue; - } - $hostsAliases[] = $host->getAlias(); - } - - if (count($hostsAliases) === 0) { - $output->writeln('No remote hosts.'); - return 2; // Because there are no hosts. - } - - if (count($hostsAliases) === 1) { - $host = $this->deployer->hosts->get($hostsAliases[0]); - } else { - /** @var QuestionHelper $helper */ - $helper = $this->getHelper('question'); - $question = new ChoiceQuestion( - 'Select host:', - $hostsAliases, - ); - $question->setErrorMessage('There is no "%s" host.'); - - $hostname = $helper->ask($input, $output, $question); - $host = $this->deployer->hosts->get($hostname); - } - } - - $shell_path = 'exec $SHELL -l'; - if ($host->has('shell_path')) { - $shell_path = 'exec ' . $host->get('shell_path') . ' -l'; - } - - Context::push(new Context($host)); - $host->setSshMultiplexing(false); - $options = $host->connectionOptionsString(); - $deployPath = $host->get('deploy_path', '~'); - - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - passthru("ssh -t $options {$host->connectionString()} \"cd $deployPath/current 2>/dev/null || cd $deployPath; $shell_path\""); - } else { - passthru("ssh -t $options {$host->connectionString()} 'cd $deployPath/current 2>/dev/null || cd $deployPath; $shell_path'"); - } - return 0; - } - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - parent::complete($input, $suggestions); - if ($input->mustSuggestArgumentValuesFor('hostname')) { - $suggestions->suggestValues(array_keys($this->deployer->hosts->all())); - } - } -} diff --git a/src/Command/TreeCommand.php b/src/Command/TreeCommand.php deleted file mode 100644 index ba39c7e6a..000000000 --- a/src/Command/TreeCommand.php +++ /dev/null @@ -1,180 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Deployer; -use Deployer\Task\GroupTask; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface as Input; -use Symfony\Component\Console\Output\OutputInterface as Output; - -class TreeCommand extends Command -{ - /** - * @var Output - */ - protected $output; - /** - * @var Deployer - */ - private $deployer; - /** - * @var array - */ - private $tree; - /** - * @var int - */ - private $depth = 0; - /** - * @var array - */ - private $openGroupDepths = []; - - public function __construct(Deployer $deployer) - { - parent::__construct('tree'); - $this->setDescription('Display the task-tree for a given task'); - $this->deployer = $deployer; - $this->tree = []; - } - - protected function configure() - { - $this->addArgument( - 'task', - InputArgument::REQUIRED, - 'Task to display the tree for', - ); - } - - protected function execute(Input $input, Output $output): int - { - $this->output = $output; - - $rootTaskName = $input->getArgument('task'); - - $this->buildTree($rootTaskName); - $this->outputTree($rootTaskName); - return 0; - } - - private function buildTree(string $taskName) - { - $this->createTreeFromTaskName($taskName, '', true); - } - - private function createTreeFromTaskName(string $taskName, string $postfix = '', bool $isLast = false) - { - $task = $this->deployer->tasks->get($taskName); - - if (!$task->isEnabled()) { - if (empty($postfix)) { - $postfix = ' // disabled'; - } else { - $postfix .= '; disabled'; - } - } - - if ($task->getBefore()) { - $beforePostfix = sprintf(" // before %s", $task->getName()); - - foreach ($task->getBefore() as $beforeTask) { - $this->createTreeFromTaskName($beforeTask, $beforePostfix); - } - } - - if ($task instanceof GroupTask) { - $isLast = $isLast && empty($task->getAfter()); - - $this->addTaskToTree($task->getName() . $postfix, $isLast); - - if (!$isLast) { - $this->openGroupDepths[] = $this->depth; - } - - $this->depth++; - - $taskGroup = $task->getGroup(); - foreach ($taskGroup as $subtask) { - $isLastSubtask = $subtask === end($taskGroup); - $this->createTreeFromTaskName($subtask, '', $isLastSubtask); - } - - if (!$isLast) { - array_pop($this->openGroupDepths); - } - - $this->depth--; - } else { - $this->addTaskToTree($task->getName() . $postfix, $isLast); - } - - if ($task->getAfter()) { - $afterPostfix = sprintf(" // after %s", $task->getName()); - - foreach ($task->getAfter() as $afterTask) { - $this->createTreeFromTaskName($afterTask, $afterPostfix); - } - } - } - - private function addTaskToTree(string $taskName, bool $isLast = false) - { - $this->tree[] = [ - 'taskName' => $taskName, - 'depth' => $this->depth, - 'isLast' => $isLast, - 'openDepths' => $this->openGroupDepths, - ]; - } - - private function outputTree(string $taskName) - { - $this->output->writeln("The task-tree for $taskName:"); - - /** - * @var int number of spaces for each depth increase - */ - $REPEAT_COUNT = 4; - - foreach ($this->tree as $treeItem) { - $depth = $treeItem['depth']; - - $startSymbol = $treeItem['isLast'] || $treeItem === end($this->tree) ? '└' : '├'; - - $prefix = ''; - - for ($i = 0; $i < $depth; $i++) { - if (in_array($i, $treeItem['openDepths'])) { - $prefix .= '│' . str_repeat(' ', $REPEAT_COUNT - 1); - } else { - $prefix .= str_repeat(' ', $REPEAT_COUNT); - } - } - - $prefix .= $startSymbol . '──'; - - $this->output->writeln(sprintf('%s %s', $prefix, $treeItem['taskName'])); - } - } - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - parent::complete($input, $suggestions); - if ($input->mustSuggestArgumentValuesFor('task')) { - $suggestions->suggestValues(array_keys($this->deployer->tasks->all())); - } - } -} diff --git a/src/Command/WorkerCommand.php b/src/Command/WorkerCommand.php deleted file mode 100644 index 311692e9b..000000000 --- a/src/Command/WorkerCommand.php +++ /dev/null @@ -1,60 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Command; - -use Deployer\Deployer; -use Deployer\Executor\Worker; -use Deployer\Host\Localhost; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption as Option; -use Symfony\Component\Console\Output\OutputInterface; - -use function Deployer\localhost; - -class WorkerCommand extends MainCommand -{ - public function __construct(Deployer $deployer) - { - parent::__construct('worker', null, $deployer); - $this->setHidden(true); - } - - protected function configure() - { - parent::configure(); - $this->addOption('task', null, Option::VALUE_REQUIRED); - $this->addOption('host', null, Option::VALUE_REQUIRED); - $this->addOption('port', null, Option::VALUE_REQUIRED); - $this->addOption('decorated', null, Option::VALUE_NONE); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - $this->deployer->input = $input; - $this->deployer->output = $output; - $this->deployer['log'] = $input->getOption('log'); - $output->setDecorated($input->getOption('decorated')); - if (!$output->isDecorated() && !defined('NO_ANSI')) { - define('NO_ANSI', 'true'); - } - $this->deployer->config->set('master_url', 'http://localhost:' . $input->getOption('port')); - - $task = $this->deployer->tasks->get($input->getOption('task')); - $host = $this->deployer->hosts->get($input->getOption('host')); - $host->config()->load(); - - $worker = new Worker($this->deployer); - $exitCode = $worker->execute($task, $host); - - $host->config()->save(); - return $exitCode; - } -} diff --git a/src/Component/PharUpdate/Console/Command.php b/src/Component/PharUpdate/Console/Command.php deleted file mode 100644 index a3e10e645..000000000 --- a/src/Component/PharUpdate/Console/Command.php +++ /dev/null @@ -1,134 +0,0 @@ - - */ -class Command extends Base -{ - /** - * Disable the ability to upgrade? - * - * @var boolean - */ - private $disableUpgrade = false; - - /** - * The manifest file URI. - * - * @var string - */ - private $manifestUri; - - /** - * The running file (the Phar that will be updated). - * - * @var string - */ - private $runningFile; - - /** - * @param string $name The command name. - * @param boolean $disable Disable upgrading? - */ - public function __construct(string $name, bool $disable = false) - { - $this->disableUpgrade = $disable; - - parent::__construct($name); - } - - /** - * Sets the manifest URI. - * - * @param string $uri The URI. - */ - public function setManifestUri(string $uri) - { - $this->manifestUri = $uri; - } - - /** - * Sets the running file (the Phar that will be updated). - * - * @param string $file The file name or path. - */ - public function setRunningFile(string $file): void - { - $this->runningFile = $file; - } - - /** - * {@inheritdoc} - */ - protected function configure() - { - $this->setDescription('Updates the application.'); - $this->addOption( - 'pre', - 'p', - InputOption::VALUE_NONE, - 'Allow pre-release updates.', - ); - $this->addOption( - 'redo', - 'r', - InputOption::VALUE_NONE, - 'Redownload update if already using current version.', - ); - - if (false === $this->disableUpgrade) { - $this->addOption( - 'upgrade', - 'u', - InputOption::VALUE_NONE, - 'Upgrade to next major release, if available.', - ); - } - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - if (null === $this->manifestUri) { - throw new LogicException( - 'No manifest URI has been configured.', - ); - } - - $output->writeln('Looking for updates...'); - - /** @var Helper */ - $pharUpdate = $this->getHelper('phar-update'); - /** @var Manager $manager */ - $manager = $pharUpdate->getManager($this->manifestUri); - $manager->setRunningFile($this->runningFile); - - if ($manager->update( - $this->getApplication()->getVersion(), - $this->disableUpgrade ?: (false === $input->getOption('upgrade')), - $input->getOption('pre'), - )) { - $output->writeln('Update successful!'); - } else { - $output->writeln('Already up-to-date.'); - } - - // Force exit to prevent warnings - die(0); - } -} diff --git a/src/Component/PharUpdate/Console/Helper.php b/src/Component/PharUpdate/Console/Helper.php deleted file mode 100644 index 270c1999c..000000000 --- a/src/Component/PharUpdate/Console/Helper.php +++ /dev/null @@ -1,34 +0,0 @@ - - */ -class Helper extends Base -{ - /** - * Returns the update manager. - * - * @param string $uri The manifest file URI. - * - * @return Manager The update manager. - */ - public function getManager(string $uri): Manager - { - return new Manager(Manifest::loadFile($uri)); - } - - public function getName(): string - { - return 'phar-update'; - } -} diff --git a/src/Component/PharUpdate/Exception/Exception.php b/src/Component/PharUpdate/Exception/Exception.php deleted file mode 100644 index a6b5f6dbd..000000000 --- a/src/Component/PharUpdate/Exception/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ - - */ -class Exception extends \Exception implements ExceptionInterface -{ - /** - * Creates a new exception using a format and values. - * - * @param mixed $value,... The value(s). - */ - public static function create(string $format, $value = null): self - { - if (0 < func_num_args()) { - $format = vsprintf($format, array_slice(func_get_args(), 1)); - } - - return new static($format); - } - - /** - * Creates an exception for the last error message. - */ - public static function lastError(): self - { - $error = error_get_last(); - - return new static($error['message']); - } -} diff --git a/src/Component/PharUpdate/Exception/ExceptionInterface.php b/src/Component/PharUpdate/Exception/ExceptionInterface.php deleted file mode 100644 index ab96f57c9..000000000 --- a/src/Component/PharUpdate/Exception/ExceptionInterface.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ -interface ExceptionInterface {} diff --git a/src/Component/PharUpdate/Exception/FileException.php b/src/Component/PharUpdate/Exception/FileException.php deleted file mode 100644 index 8e1f349c4..000000000 --- a/src/Component/PharUpdate/Exception/FileException.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ -class FileException extends Exception {} diff --git a/src/Component/PharUpdate/Exception/InvalidArgumentException.php b/src/Component/PharUpdate/Exception/InvalidArgumentException.php deleted file mode 100644 index 2658c4efb..000000000 --- a/src/Component/PharUpdate/Exception/InvalidArgumentException.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ -class InvalidArgumentException extends Exception {} diff --git a/src/Component/PharUpdate/Exception/LogicException.php b/src/Component/PharUpdate/Exception/LogicException.php deleted file mode 100644 index 1c7f5c80e..000000000 --- a/src/Component/PharUpdate/Exception/LogicException.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ -class LogicException extends Exception {} diff --git a/src/Component/PharUpdate/Manager.php b/src/Component/PharUpdate/Manager.php deleted file mode 100644 index 86ddffc33..000000000 --- a/src/Component/PharUpdate/Manager.php +++ /dev/null @@ -1,114 +0,0 @@ - - */ -class Manager -{ - /** - * The update manifest. - * - * @var Manifest - */ - private $manifest; - - /** - * The running file (the Phar that will be updated). - * - * @var string - */ - private $runningFile; - - /** - * Sets the update manifest. - * - * @param Manifest $manifest The manifest. - */ - public function __construct(Manifest $manifest) - { - $this->manifest = $manifest; - } - - /** - * Returns the manifest. - * - * @return Manifest The manifest. - */ - public function getManifest(): Manifest - { - return $this->manifest; - } - - /** - * Returns the running file (the Phar that will be updated). - * - * @return string The file. - */ - public function getRunningFile(): string - { - if (null === $this->runningFile) { - $this->runningFile = realpath($_SERVER['argv'][0]); - } - - return $this->runningFile; - } - - /** - * Sets the running file (the Phar that will be updated). - * - * @param string $file The file name or path. - * - * @throws Exception\Exception - * @throws InvalidArgumentException If the file path is invalid. - */ - public function setRunningFile(string $file): void - { - if (false === is_file($file)) { - throw InvalidArgumentException::create( - 'The file "%s" is not a file or it does not exist.', - $file, - ); - } - - $this->runningFile = $file; - } - - /** - * Updates the running Phar if any is available. - * - * @param string|Version $version The current version. - * @param boolean $major Lock to current major version? - * @param boolean $pre Allow pre-releases? - * - * @return boolean TRUE if an update was performed, FALSE if none available. - */ - public function update($version, bool $major = false, bool $pre = false): bool - { - if (false === ($version instanceof Version)) { - $version = Parser::toVersion($version); - } - - if (null !== ($update = $this->manifest->findRecent( - $version, - $major, - $pre, - ))) { - $update->getFile(); - $update->copyTo($this->getRunningFile()); - - return true; - } - - return false; - } -} diff --git a/src/Component/PharUpdate/Manifest.php b/src/Component/PharUpdate/Manifest.php deleted file mode 100644 index a03d03d08..000000000 --- a/src/Component/PharUpdate/Manifest.php +++ /dev/null @@ -1,133 +0,0 @@ - - */ -class Manifest -{ - /** - * The list of updates in the manifest. - * - * @var Update[] - */ - private $updates; - - /** - * Sets the list of updates from the manifest. - * - * @param Update[] $updates The updates. - */ - public function __construct(array $updates = []) - { - $this->updates = $updates; - } - - /** - * Finds the most recent update and returns it. - * - * @param Version $version The current version. - * @param boolean $major Lock to major version? - * @param boolean $pre Allow pre-releases? - */ - public function findRecent(Version $version, bool $major = false, bool $pre = false): ?Update - { - /** @var Update|null */ - $current = null; - $major = $major ? $version->getMajor() : null; - - foreach ($this->updates as $update) { - if ($major && ($major !== $update->getVersion()->getMajor())) { - continue; - } - - if ((false === $pre) - && !$update->getVersion()->isStable()) { - continue; - } - - $test = $current ? $current->getVersion() : $version; - - if (false === $update->isNewer($test)) { - continue; - } - - $current = $update; - } - - return $current; - } - - /** - * Returns the list of updates in the manifest. - * - * @return Update[] The updates. - */ - public function getUpdates(): array - { - return $this->updates; - } - - /** - * Loads the manifest from a JSON encoded string. - * - * @param string $json The JSON encoded string. - */ - public static function load(string $json): self - { - return self::create(json_decode($json)); - } - - /** - * Loads the manifest from a JSON encoded file. - * - * @param string $file The JSON encoded file. - */ - public static function loadFile(string $file): self - { - return self::create(json_decode(file_get_contents($file))); - } - - /** - * Validates the data, processes it, and returns a new instance of Manifest. - * - * @param array $decoded The decoded JSON data. - * - * @return static The new instance. - */ - private static function create(array $decoded): self - { - $updates = []; - - foreach ($decoded as $update) { - $updates[] = new Update( - $update->name, - $update->sha1, - $update->url, - Parser::toVersion($update->version), - $update->publicKey ?? null, - ); - } - - usort( - $updates, - function (Update $a, Update $b) { - return Comparator::isGreaterThan( - $a->getVersion(), - $b->getVersion(), - ) ? 1 : 0; - }, - ); - - return new static($updates); - } -} diff --git a/src/Component/PharUpdate/Update.php b/src/Component/PharUpdate/Update.php deleted file mode 100644 index 44f0a5970..000000000 --- a/src/Component/PharUpdate/Update.php +++ /dev/null @@ -1,274 +0,0 @@ - - */ -class Update -{ - /** - * The temporary file path. - * - * @var string|null - */ - private $file; - - /** - * The name of the update file. - * - * @var string - */ - private $name; - - /** - * The URL where the public key can be downloaded from. - * - * @var string - */ - private $publicKey; - - /** - * The SHA1 file checksum. - * - * @var string - */ - private $sha1; - - /** - * The URL where the update can be downloaded from. - * - * @var string - */ - private $url; - - /** - * The version of the update. - * - * @var Version - */ - private $version; - - /** - * Sets the update information. - * - * @param string $name The name of the update file. - * @param string $sha1 The SHA1 file checksum. - * @param string $url The URL where the update can be downloaded from. - * @param Version $version The version of the update. - * @param string $key The URL where the public key can be downloaded - * from. - */ - public function __construct( - string $name, - string $sha1, - string $url, - Version $version, - string $key = null - ) { - $this->name = $name; - $this->publicKey = $key; - $this->sha1 = $sha1; - $this->url = $url; - $this->version = $version; - } - - /** - * Copies the update file to the destination. - * - * @param string $file The target file. - * - * @throws Exception\Exception - * @throws FileException If the file could not be replaced. - */ - public function copyTo(string $file): void - { - if (null === $this->file) { - throw LogicException::create( - 'The update file has not been downloaded.', - ); - } - - $mode = 0o755; - - if (file_exists($file)) { - $mode = fileperms($file) & 511; - } - - if (false === @copy($this->file, $file)) { - throw FileException::lastError(); - } - - if (false === @chmod($file, $mode)) { - throw FileException::lastError(); - } - - $key = $file . '.pubkey'; - - if (file_exists($this->file . '.pubkey')) { - if (false === @copy($this->file . '.pubkey', $key)) { - throw FileException::lastError(); - } - } elseif (file_exists($key)) { - if (false === @unlink($key)) { - throw FileException::lastError(); - } - } - } - - /** - * Cleans up by deleting the temporary update file. - * - * @throws FileException If the file could not be deleted. - */ - public function deleteFile(): void - { - if ($this->file) { - if (file_exists($this->file)) { - if (false === @unlink($this->file)) { - throw FileException::lastError(); - } - } - - if (file_exists($this->file . '.pubkey')) { - if (false === @unlink($this->file . '.pubkey')) { - throw FileException::lastError(); - } - } - - $dir = dirname($this->file); - - if (file_exists($dir)) { - if (false === @rmdir($dir)) { - throw FileException::lastError(); - } - } - - $this->file = null; - } - } - - /** - * Downloads the update file to a temporary location. - * - * @return string The temporary file path. - * - * @throws Exception\Exception - * @throws FileException If the SHA1 checksum differs. - * @throws UnexpectedValueException If the Phar is corrupt. - */ - public function getFile(): ?string - { - if (null === $this->file) { - unlink($this->file = tempnam(sys_get_temp_dir(), 'upd')); - mkdir($this->file); - - $this->file .= DIRECTORY_SEPARATOR . $this->name; - - $in = new SplFileObject($this->url, 'rb', false); - $out = new SplFileObject($this->file, 'wb', false); - - while (false === $in->eof()) { - $out->fwrite($in->fgets()); - } - - unset($in, $out); - - if ($this->publicKey) { - $in = new SplFileObject($this->publicKey, 'r', false); - $out = new SplFileObject($this->file . '.pubkey', 'w', false); - - while (false === $in->eof()) { - $out->fwrite($in->fgets()); - } - - unset($in, $out); - } - - if ($this->sha1 !== ($sha1 = sha1_file($this->file))) { - $this->deleteFile(); - - throw FileException::create( - 'Mismatch of the SHA1 checksum (%s) of the downloaded file (%s).', - $this->sha1, - $sha1, - ); - } - - // double check - try { - new Phar($this->file); - } catch (UnexpectedValueException $exception) { - $this->deleteFile(); - - throw $exception; - } - } - - return $this->file; - } - - /** - * Returns name of the update file. - */ - public function getName(): string - { - return $this->name; - } - - /** - * Returns the URL where the public key can be downloaded from. - */ - public function getPublicKey(): string - { - return $this->publicKey; - } - - /** - * Returns the SHA1 file checksum. - */ - public function getSha1(): string - { - return $this->sha1; - } - - /** - * Returns the URL where the update can be downloaded from. - */ - public function getUrl(): string - { - return $this->url; - } - - /** - * Returns the version of the update. - */ - public function getVersion(): Version - { - return $this->version; - } - - /** - * Checks if this update is newer than the version given. - * - * @param Version $version The current version. - * - * @return boolean TRUE if the update is newer, FALSE if not. - */ - public function isNewer(Version $version): bool - { - return Comparator::isGreaterThan($this->version, $version); - } -} diff --git a/src/Component/PharUpdate/Version/Builder.php b/src/Component/PharUpdate/Version/Builder.php deleted file mode 100644 index 2319de6a3..000000000 --- a/src/Component/PharUpdate/Version/Builder.php +++ /dev/null @@ -1,280 +0,0 @@ - - */ -class Builder extends Version -{ - /** - * Removes the build metadata identifiers. - */ - public function clearBuild(): void - { - $this->build = []; - } - - /** - * Removes the pre-release version identifiers. - */ - public function clearPreRelease(): void - { - $this->preRelease = []; - } - - /** - * Creates a new Version builder. - * - * @return Builder The Version builder. - */ - public static function create(): Builder - { - return new Builder(); - } - - /** - * Returns a readonly Version instance. - * - * @return Version The readonly Version instance. - */ - public function getVersion(): Version - { - return new Version( - $this->major, - $this->minor, - $this->patch, - $this->preRelease, - $this->build, - ); - } - - /** - * Imports the version components. - * - * @param array $components The components. - * - * @return Builder The Version builder. - */ - public function importComponents(array $components): self - { - if (isset($components[Parser::BUILD])) { - $this->build = $components[Parser::BUILD]; - } else { - $this->build = []; - } - - if (isset($components[Parser::MAJOR])) { - $this->major = $components[Parser::MAJOR]; - } else { - $this->major = 0; - } - - if (isset($components[Parser::MINOR])) { - $this->minor = $components[Parser::MINOR]; - } else { - $this->minor = 0; - } - - if (isset($components[Parser::PATCH])) { - $this->patch = $components[Parser::PATCH]; - } else { - $this->patch = 0; - } - - if (isset($components[Parser::PRE_RELEASE])) { - $this->preRelease = $components[Parser::PRE_RELEASE]; - } else { - $this->preRelease = []; - } - - return $this; - } - - /** - * Imports the version string representation. - * - * @param string $version The string representation. - * - * @return Builder The Version builder. - */ - public function importString(string $version): self - { - return $this->importComponents(Parser::toComponents($version)); - } - - /** - * Imports an existing Version instance. - * - * @param Version $version A Version instance. - * - * @return Builder The Version builder. - */ - public function importVersion(Version $version): self - { - return $this - ->setMajor($version->getMajor()) - ->setMinor($version->getMinor()) - ->setPatch($version->getPatch()) - ->setPreRelease($version->getPreRelease()) - ->setBuild($version->getBuild()); - } - - /** - * Increments the major version number and resets the minor and patch - * version numbers to zero. - * - * @param int $amount Increment by what amount? - * - * @return Builder The Version builder. - */ - public function incrementMajor(int $amount = 1): self - { - $this->major += $amount; - $this->minor = 0; - $this->patch = 0; - - return $this; - } - - /** - * Increments the minor version number and resets the patch version number - * to zero. - * - * @param int $amount Increment by what amount? - * - * @return Builder The Version builder. - */ - public function incrementMinor(int $amount = 1): self - { - $this->minor += $amount; - $this->patch = 0; - - return $this; - } - - /** - * Increments the patch version number. - * - * @param int $amount Increment by what amount? - * - * @return Builder The Version builder. - */ - public function incrementPatch(int $amount = 1): self - { - $this->patch += $amount; - - return $this; - } - - /** - * Sets the build metadata identifiers. - * - * @param array $identifiers The build metadata identifiers. - * - * @return Builder The Version builder. - * - * @throws InvalidIdentifierException If an identifier is invalid. - */ - public function setBuild(array $identifiers): self - { - foreach ($identifiers as $identifier) { - if (!Validator::isIdentifier($identifier)) { - throw new InvalidIdentifierException($identifier); - } - } - - $this->build = $identifiers; - - return $this; - } - - /** - * Sets the major version number. - * - * @param int $number The major version number. - * - * @return Builder The Version builder. - * - * @throws InvalidNumberException If the number is invalid. - */ - public function setMajor(int $number): self - { - if (!Validator::isNumber($number)) { - throw new InvalidNumberException($number); - } - - $this->major = intval($number); - - return $this; - } - - /** - * Sets the minor version number. - * - * @param int $number The minor version number. - * - * @return Builder The Version builder. - * - * @throws InvalidNumberException If the number is invalid. - */ - public function setMinor(int $number): self - { - if (!Validator::isNumber($number)) { - throw new InvalidNumberException($number); - } - - $this->minor = intval($number); - - return $this; - } - - /** - * Sets the patch version number. - * - * @param int $number The patch version number. - * - * @return Builder The Version builder. - * - * @throws InvalidNumberException If the number is invalid. - */ - public function setPatch(int $number): self - { - if (!Validator::isNumber($number)) { - throw new InvalidNumberException($number); - } - - $this->patch = intval($number); - - return $this; - } - - /** - * Sets the pre-release version identifiers. - * - * @param array $identifiers The pre-release version identifiers. - * - * @return Builder The Version builder. - * - * @throws InvalidIdentifierException If an identifier is invalid. - */ - public function setPreRelease(array $identifiers): self - { - foreach ($identifiers as $identifier) { - if (!Validator::isIdentifier($identifier)) { - throw new InvalidIdentifierException($identifier); - } - } - - $this->preRelease = $identifiers; - - return $this; - } -} diff --git a/src/Component/PharUpdate/Version/Comparator.php b/src/Component/PharUpdate/Version/Comparator.php deleted file mode 100644 index 8a0e73739..000000000 --- a/src/Component/PharUpdate/Version/Comparator.php +++ /dev/null @@ -1,176 +0,0 @@ - - */ -class Comparator -{ - /** - * The version is equal to another. - */ - public const EQUAL_TO = 0; - - /** - * The version is greater than another. - */ - public const GREATER_THAN = 1; - - /** - * The version is less than another. - */ - public const LESS_THAN = -1; - - /** - * Compares one version with another. - * - * @param Version $left The left version to compare. - * @param Version $right The right version to compare. - * - * @return integer Returns Comparator::EQUAL_TO if the two versions are - * equal. If the left version is less than the right - * version, Comparator::LESS_THAN is returned. If the left - * version is greater than the right version, - * Comparator::GREATER_THAN is returned. - */ - public static function compareTo(Version $left, Version $right) - { - switch (true) { - case ($left->getMajor() < $right->getMajor()): - return self::LESS_THAN; - case ($left->getMajor() > $right->getMajor()): - return self::GREATER_THAN; - case ($left->getMinor() > $right->getMinor()): - return self::GREATER_THAN; - case ($left->getMinor() < $right->getMinor()): - return self::LESS_THAN; - case ($left->getPatch() > $right->getPatch()): - return self::GREATER_THAN; - case ($left->getPatch() < $right->getPatch()): - return self::LESS_THAN; - // @codeCoverageIgnoreStart - } - // @codeCoverageIgnoreEnd - - return self::compareIdentifiers( - $left->getPreRelease(), - $right->getPreRelease(), - ); - } - - /** - * Checks if the left version is equal to the right. - * - * @param Version $left The left version to compare. - * @param Version $right The right version to compare. - * - * @return boolean TRUE if the left version is equal to the right, FALSE - * if not. - */ - public static function isEqualTo(Version $left, Version $right) - { - return (self::EQUAL_TO === self::compareTo($left, $right)); - } - - /** - * Checks if the left version is greater than the right. - * - * @param Version $left The left version to compare. - * @param Version $right The right version to compare. - * - * @return boolean TRUE if the left version is greater than the right, - * FALSE if not. - */ - public static function isGreaterThan(Version $left, Version $right) - { - return (self::GREATER_THAN === self::compareTo($left, $right)); - } - - /** - * Checks if the left version is less than the right. - * - * @param Version $left The left version to compare. - * @param Version $right The right version to compare. - * - * @return boolean TRUE if the left version is less than the right, - * FALSE if not. - */ - public static function isLessThan(Version $left, Version $right) - { - return (self::LESS_THAN === self::compareTo($left, $right)); - } - - /** - * Compares the identifier components of the left and right versions. - * - * @param array $left The left identifiers. - * @param array $right The right identifiers. - * - * @return integer Returns Comparator::EQUAL_TO if the two identifiers are - * equal. If the left identifiers is less than the right - * identifiers, Comparator::LESS_THAN is returned. If the - * left identifiers is greater than the right identifiers, - * Comparator::GREATER_THAN is returned. - */ - public static function compareIdentifiers(array $left, array $right) - { - if ($left && empty($right)) { - return self::LESS_THAN; - } elseif (empty($left) && $right) { - return self::GREATER_THAN; - } - - $l = $left; - $r = $right; - $x = self::GREATER_THAN; - $y = self::LESS_THAN; - - if (count($l) < count($r)) { - $l = $right; - $r = $left; - $x = self::LESS_THAN; - $y = self::GREATER_THAN; - } - - foreach (array_keys($l) as $i) { - if (!isset($r[$i])) { - return $x; - } - - if ($l[$i] === $r[$i]) { - continue; - } - - if (true === ($li = (false != preg_match('/^\d+$/', $l[$i])))) { - $l[$i] = intval($l[$i]); - } - - if (true === ($ri = (false != preg_match('/^\d+$/', $r[$i])))) { - $r[$i] = intval($r[$i]); - } - - if ($li && $ri) { - return ($l[$i] > $r[$i]) ? $x : $y; - } elseif (!$li && $ri) { - return $x; - } elseif ($li && !$ri) { - return $y; - } - - $result = strcmp($l[$i], $r[$i]); - - if ($result > 0) { - return $x; - } elseif ($result < 0) { - return $y; - } - } - - return self::EQUAL_TO; - } -} diff --git a/src/Component/PharUpdate/Version/Dumper.php b/src/Component/PharUpdate/Version/Dumper.php deleted file mode 100644 index 88a2e5490..000000000 --- a/src/Component/PharUpdate/Version/Dumper.php +++ /dev/null @@ -1,54 +0,0 @@ - - */ -class Dumper -{ - /** - * Returns the components of a Version instance. - * - * @param Version $version A version. - * - * @return array The components. - */ - public static function toComponents(Version $version) - { - return [ - Parser::MAJOR => $version->getMajor(), - Parser::MINOR => $version->getMinor(), - Parser::PATCH => $version->getPatch(), - Parser::PRE_RELEASE => $version->getPreRelease(), - Parser::BUILD => $version->getBuild(), - ]; - } - - /** - * Returns the string representation of a Version instance. - * - * @param Version $version A version. - * - * @return string The string representation. - */ - public static function toString(Version $version) - { - return sprintf( - '%d.%d.%d%s%s', - $version->getMajor(), - $version->getMinor(), - $version->getPatch(), - $version->getPreRelease() - ? '-' . join('.', $version->getPreRelease()) - : '', - $version->getBuild() - ? '+' . join('.', $version->getBuild()) - : '', - ); - } -} diff --git a/src/Component/PharUpdate/Version/Exception/InvalidIdentifierException.php b/src/Component/PharUpdate/Version/Exception/InvalidIdentifierException.php deleted file mode 100644 index 0768d0bcf..000000000 --- a/src/Component/PharUpdate/Version/Exception/InvalidIdentifierException.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ -class InvalidIdentifierException extends VersionException -{ - /** - * The invalid identifier. - * - * @var string - */ - private $identifier; - - /** - * Sets the invalid identifier. - * - * @param string $identifier The invalid identifier. - */ - public function __construct(string $identifier) - { - parent::__construct( - sprintf( - 'The identifier "%s" is invalid.', - $identifier, - ), - ); - - $this->identifier = $identifier; - } - - /** - * Returns the invalid identifier. - * - * @return string The invalid identifier. - */ - public function getIdentifier(): string - { - return $this->identifier; - } -} diff --git a/src/Component/PharUpdate/Version/Exception/InvalidNumberException.php b/src/Component/PharUpdate/Version/Exception/InvalidNumberException.php deleted file mode 100644 index 575a1a25a..000000000 --- a/src/Component/PharUpdate/Version/Exception/InvalidNumberException.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ -class InvalidNumberException extends VersionException -{ - /** - * The invalid version number. - * - * @var mixed - */ - private $number; - - /** - * Sets the invalid version number. - * - * @param mixed $number The invalid version number. - */ - public function __construct($number) - { - parent::__construct( - sprintf( - 'The version number "%s" is invalid.', - $number, - ), - ); - - $this->number = $number; - } - - /** - * Returns the invalid version number. - * - * @return mixed The invalid version number. - */ - public function getNumber() - { - return $this->number; - } -} diff --git a/src/Component/PharUpdate/Version/Exception/InvalidStringRepresentationException.php b/src/Component/PharUpdate/Version/Exception/InvalidStringRepresentationException.php deleted file mode 100644 index 6946f129d..000000000 --- a/src/Component/PharUpdate/Version/Exception/InvalidStringRepresentationException.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ -class InvalidStringRepresentationException extends VersionException -{ - /** - * The invalid string representation. - * - * @var string - */ - private $version; - - /** - * Sets the invalid string representation. - * - * @param string $version The string representation. - */ - public function __construct(string $version) - { - parent::__construct( - sprintf( - 'The version string representation "%s" is invalid.', - $version, - ), - ); - - $this->version = $version; - } - - /** - * Returns the invalid string representation. - * - * @return string The invalid string representation. - */ - public function getVersion(): string - { - return $this->version; - } -} diff --git a/src/Component/PharUpdate/Version/Exception/VersionException.php b/src/Component/PharUpdate/Version/Exception/VersionException.php deleted file mode 100644 index 7aa91543c..000000000 --- a/src/Component/PharUpdate/Version/Exception/VersionException.php +++ /dev/null @@ -1,14 +0,0 @@ - - */ -class VersionException extends Exception {} diff --git a/src/Component/PharUpdate/Version/Parser.php b/src/Component/PharUpdate/Version/Parser.php deleted file mode 100644 index c49b9a93f..000000000 --- a/src/Component/PharUpdate/Version/Parser.php +++ /dev/null @@ -1,117 +0,0 @@ - - */ -class Parser -{ - /** - * The build metadata component. - */ - public const BUILD = 'build'; - - /** - * The major version number component. - */ - public const MAJOR = 'major'; - - /** - * The minor version number component. - */ - public const MINOR = 'minor'; - - /** - * The patch version number component. - */ - public const PATCH = 'patch'; - - /** - * The pre-release version number component. - */ - public const PRE_RELEASE = 'pre'; - - /** - * Returns a Version builder for the string representation. - * - * @param string $version The string representation. - * - * @return Builder A Version builder. - */ - public static function toBuilder(string $version): Builder - { - return Builder::create()->importComponents( - self::toComponents($version), - ); - } - - /** - * Returns the components of the string representation. - * - * @param string $version The string representation. - * - * @return array The components of the version. - * - * @throws InvalidStringRepresentationException If the string representation - * is invalid. - */ - public static function toComponents(string $version): array - { - if (!Validator::isVersion($version)) { - throw new InvalidStringRepresentationException($version); - } - - if (false !== strpos($version, '+')) { - [$version, $build] = explode('+', $version); - - $build = explode('.', $build); - } - - if (false !== strpos($version, '-')) { - [$version, $pre] = explode('-', $version); - - $pre = explode('.', $pre); - } - - [ - $major, - $minor, - $patch, - ] = explode('.', $version); - - return [ - self::MAJOR => intval($major), - self::MINOR => intval($minor), - self::PATCH => intval($patch), - self::PRE_RELEASE => $pre ?? [], - self::BUILD => $build ?? [], - ]; - } - - /** - * Returns a Version instance for the string representation. - * - * @param string $version The string representation. - * - * @return Version A Version instance. - */ - public static function toVersion(string $version): Version - { - $components = self::toComponents($version); - - return new Version( - $components['major'], - $components['minor'], - $components['patch'], - $components['pre'], - $components['build'], - ); - } -} diff --git a/src/Component/PharUpdate/Version/Validator.php b/src/Component/PharUpdate/Version/Validator.php deleted file mode 100644 index febcffb87..000000000 --- a/src/Component/PharUpdate/Version/Validator.php +++ /dev/null @@ -1,59 +0,0 @@ - - */ -class Validator -{ - /** - * The regular expression for a valid identifier. - */ - public const IDENTIFIER_REGEX = '/^[0-9A-Za-z\-]+$/'; - - /** - * The regular expression for a valid semantic version number. - */ - public const VERSION_REGEX = '/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/'; - - /** - * Checks if a identifier is valid. - * - * @param string $identifier A identifier. - * - * @return boolean TRUE if the identifier is valid, FALSE If not. - */ - public static function isIdentifier(string $identifier): bool - { - return (true == preg_match(self::IDENTIFIER_REGEX, $identifier)); - } - - /** - * Checks if a number is a valid version number. - * - * @param integer $number A number. - * - * @return boolean TRUE if the number is valid, FALSE If not. - */ - public static function isNumber(int $number): bool - { - return (true == preg_match('/^(0|[1-9]\d*)$/', (string) $number)); - } - - /** - * Checks if the string representation of a version number is valid. - * - * @param string $version The string representation. - * - * @return boolean TRUE if the string representation is valid, FALSE if not. - */ - public static function isVersion(string $version): bool - { - return (true == preg_match(self::VERSION_REGEX, $version)); - } -} diff --git a/src/Component/PharUpdate/Version/Version.php b/src/Component/PharUpdate/Version/Version.php deleted file mode 100644 index e178c4018..000000000 --- a/src/Component/PharUpdate/Version/Version.php +++ /dev/null @@ -1,141 +0,0 @@ - - */ -class Version -{ - /** - * The build metadata identifiers. - * - * @var array - */ - protected $build; - - /** - * The major version number. - * - * @var integer - */ - protected $major; - - /** - * The minor version number. - * - * @var integer - */ - protected $minor; - - /** - * The patch version number. - * - * @var integer - */ - protected $patch; - - /** - * The pre-release version identifiers. - * - * @var array - */ - protected $preRelease; - - /** - * Sets the version information. - * - * @param int $major The major version number. - * @param int $minor The minor version number. - * @param int $patch The patch version number. - * @param array $pre The pre-release version identifiers. - * @param array $build The build metadata identifiers. - */ - public function __construct( - int $major = 0, - int $minor = 0, - int $patch = 0, - array $pre = [], - array $build = [] - ) { - $this->build = $build; - $this->major = $major; - $this->minor = $minor; - $this->patch = $patch; - $this->preRelease = $pre; - } - - /** - * Returns the build metadata identifiers. - * - * @return array The build metadata identifiers. - */ - public function getBuild(): array - { - return $this->build; - } - - /** - * Returns the major version number. - * - * @return int The major version number. - */ - public function getMajor(): int - { - return $this->major; - } - - /** - * Returns the minor version number. - * - * @return int The minor version number. - */ - public function getMinor(): int - { - return $this->minor; - } - - /** - * Returns the patch version number. - * - * @return int The patch version number. - */ - public function getPatch(): int - { - return $this->patch; - } - - /** - * Returns the pre-release version identifiers. - * - * @return array The pre-release version identifiers. - */ - public function getPreRelease(): array - { - return $this->preRelease; - } - - /** - * Checks if the version number is stable. - * - * @return boolean TRUE if it is stable, FALSE if not. - */ - public function isStable(): bool - { - return empty($this->preRelease) && $this->major !== 0; - } - - /** - * Returns string representation. - * - * @return string The string representation. - */ - public function __toString(): string - { - return Dumper::toString($this); - } -} diff --git a/src/Component/Pimple/Container.php b/src/Component/Pimple/Container.php deleted file mode 100644 index 423c421e6..000000000 --- a/src/Component/Pimple/Container.php +++ /dev/null @@ -1,289 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Pimple; - -use Deployer\Component\Pimple\Exception\ExpectedInvokableException; -use Deployer\Component\Pimple\Exception\FrozenServiceException; -use Deployer\Component\Pimple\Exception\InvalidServiceIdentifierException; -use Deployer\Component\Pimple\Exception\UnknownIdentifierException; - -/** - * Container main class. - * - * @author Fabien Potencier - */ -class Container implements \ArrayAccess -{ - /** - * @var array - */ - private $values = []; - /** - * @var \SplObjectStorage - */ - private $factories; - /** - * @var \SplObjectStorage - */ - private $protected; - /** - * @var array - */ - private $frozen = []; - /** - * @var array - */ - private $raw = []; - /** - * @var array - */ - private $keys = []; - - /** - * Instantiates the container. - * - * Objects and parameters can be passed as argument to the constructor. - * - * @param array $values The parameters or objects - */ - public function __construct(array $values = []) - { - $this->factories = new \SplObjectStorage(); - $this->protected = new \SplObjectStorage(); - - foreach ($values as $key => $value) { - $this->offsetSet($key, $value); - } - } - - /** - * Sets a parameter or an object. - * - * Objects must be defined as Closures. - * - * Allowing any PHP callable leads to difficult to debug problems - * as function names (strings) are callable (creating a function with - * the same name as an existing parameter would break your container). - * - * @param string $id The unique identifier for the parameter or object - * @param mixed $value The value of the parameter or a closure to define an object - * - * @throws FrozenServiceException Prevent override of a frozen service - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint - */ - #[\ReturnTypeWillChange] - public function offsetSet($id, $value) - { - if (isset($this->frozen[$id])) { - throw new FrozenServiceException($id); - } - - $this->values[$id] = $value; - $this->keys[$id] = true; - } - - /** - * Gets a parameter or an object. - * - * @param string $id The unique identifier for the parameter or object - * - * @return mixed The value of the parameter or an object - * - * @throws UnknownIdentifierException If the identifier is not defined - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint - */ - #[\ReturnTypeWillChange] - public function offsetGet($id) - { - if (!isset($this->keys[$id])) { - throw new UnknownIdentifierException($id); - } - - if ( - isset($this->raw[$id]) - || !\is_object($this->values[$id]) - || isset($this->protected[$this->values[$id]]) - || !\method_exists($this->values[$id], '__invoke') - ) { - return $this->values[$id]; - } - - if (isset($this->factories[$this->values[$id]])) { - return $this->values[$id]($this); - } - - $raw = $this->values[$id]; - $val = $this->values[$id] = $raw($this); - $this->raw[$id] = $raw; - - $this->frozen[$id] = true; - - return $val; - } - - /** - * Checks if a parameter or an object is set. - * - * @param string $id The unique identifier for the parameter or object - * - * @return bool - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint - */ - #[\ReturnTypeWillChange] - public function offsetExists($id) - { - return isset($this->keys[$id]); - } - - /** - * Unsets a parameter or an object. - * - * @param string $id The unique identifier for the parameter or object - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint - */ - #[\ReturnTypeWillChange] - public function offsetUnset($id) - { - if (isset($this->keys[$id])) { - if (\is_object($this->values[$id])) { - unset($this->factories[$this->values[$id]], $this->protected[$this->values[$id]]); - } - - unset($this->values[$id], $this->frozen[$id], $this->raw[$id], $this->keys[$id]); - } - } - - /** - * Marks a callable as being a factory service. - * - * @param callable $callable A service definition to be used as a factory - * - * @return callable The passed callable - * - * @throws ExpectedInvokableException Service definition has to be a closure or an invokable object - */ - public function factory(callable $callable) - { - if (!\method_exists($callable, '__invoke')) { - throw new ExpectedInvokableException('Service definition is not a Closure or invokable object.'); - } - - $this->factories->attach($callable); - - return $callable; - } - - /** - * Protects a callable from being interpreted as a service. - * - * This is useful when you want to store a callable as a parameter. - * - * @param callable $callable A callable to protect from being evaluated - * - * @return callable The passed callable - * - * @throws ExpectedInvokableException Service definition has to be a closure or an invokable object - */ - public function protect(callable $callable) - { - if (!\method_exists($callable, '__invoke')) { - throw new ExpectedInvokableException('Callable is not a Closure or invokable object.'); - } - - $this->protected->attach($callable); - - return $callable; - } - - /** - * Gets a parameter or the closure defining an object. - * - * @param string $id The unique identifier for the parameter or object - * - * @return mixed The value of the parameter or the closure defining an object - * - * @throws UnknownIdentifierException If the identifier is not defined - */ - public function raw(string $id) - { - if (!isset($this->keys[$id])) { - throw new UnknownIdentifierException($id); - } - - if (isset($this->raw[$id])) { - return $this->raw[$id]; - } - - return $this->values[$id]; - } - - /** - * Extends an object definition. - * - * Useful when you want to extend an existing object definition, - * without necessarily loading that object. - * - * @param string $id The unique identifier for the object - * @param callable $callable A service definition to extend the original - * - * @return callable The wrapped callable - * - * @throws UnknownIdentifierException If the identifier is not defined - * @throws FrozenServiceException If the service is frozen - * @throws InvalidServiceIdentifierException If the identifier belongs to a parameter - * @throws ExpectedInvokableException If the extension callable is not a closure or an invokable object - */ - public function extend(string $id, callable $callable) - { - if (!isset($this->keys[$id])) { - throw new UnknownIdentifierException($id); - } - - if (isset($this->frozen[$id])) { - throw new FrozenServiceException($id); - } - - if (!\is_object($this->values[$id]) || !\method_exists($this->values[$id], '__invoke')) { - throw new InvalidServiceIdentifierException($id); - } - - if (isset($this->protected[$this->values[$id]])) { - @\trigger_error(\sprintf('How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure "%s" should be protected?', $id), E_USER_DEPRECATED); - } - - if (!\is_object($callable) || !\method_exists($callable, '__invoke')) { - throw new ExpectedInvokableException('Extension service definition is not a Closure or invokable object.'); - } - - $factory = $this->values[$id]; - - $extended = function ($c) use ($callable, $factory) { - return $callable($factory($c), $c); - }; - - if (isset($this->factories[$factory])) { - $this->factories->detach($factory); - $this->factories->attach($extended); - } - - return $this[$id] = $extended; - } - - /** - * Returns all defined value names. - * - * @return array An array of value names - */ - public function keys() - { - return \array_keys($this->values); - } -} diff --git a/src/Component/Pimple/Exception/ExpectedInvokableException.php b/src/Component/Pimple/Exception/ExpectedInvokableException.php deleted file mode 100644 index f244a0a60..000000000 --- a/src/Component/Pimple/Exception/ExpectedInvokableException.php +++ /dev/null @@ -1,20 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Pimple\Exception; - -use Psr\Container\ContainerExceptionInterface; - -/** - * A closure or invokable object was expected. - * - * @author Pascal Luna - */ -class ExpectedInvokableException extends \InvalidArgumentException implements ContainerExceptionInterface {} diff --git a/src/Component/Pimple/Exception/FrozenServiceException.php b/src/Component/Pimple/Exception/FrozenServiceException.php deleted file mode 100644 index f332c5347..000000000 --- a/src/Component/Pimple/Exception/FrozenServiceException.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Pimple\Exception; - -use Psr\Container\ContainerExceptionInterface; - -/** - * An attempt to modify a frozen service was made. - * - * @author Pascal Luna - */ -class FrozenServiceException extends \RuntimeException implements ContainerExceptionInterface -{ - /** - * @param string $id Identifier of the frozen service - */ - public function __construct(string $id) - { - parent::__construct(\sprintf('Cannot override frozen service "%s".', $id)); - } -} diff --git a/src/Component/Pimple/Exception/InvalidServiceIdentifierException.php b/src/Component/Pimple/Exception/InvalidServiceIdentifierException.php deleted file mode 100644 index 99358ec76..000000000 --- a/src/Component/Pimple/Exception/InvalidServiceIdentifierException.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Pimple\Exception; - -use Psr\Container\NotFoundExceptionInterface; - -/** - * An attempt to perform an operation that requires a service identifier was made. - * - * @author Pascal Luna - */ -class InvalidServiceIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface -{ - /** - * @param string $id The invalid identifier - */ - public function __construct(string $id) - { - parent::__construct(\sprintf('Identifier "%s" does not contain an object definition.', $id)); - } -} diff --git a/src/Component/Pimple/Exception/UnknownIdentifierException.php b/src/Component/Pimple/Exception/UnknownIdentifierException.php deleted file mode 100644 index d2aa39a1d..000000000 --- a/src/Component/Pimple/Exception/UnknownIdentifierException.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Pimple\Exception; - -use Psr\Container\NotFoundExceptionInterface; - -/** - * The identifier of a valid service or parameter was expected. - * - * @author Pascal Luna - */ -class UnknownIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface -{ - /** - * @param string $id The unknown identifier - */ - public function __construct(string $id) - { - parent::__construct(\sprintf('Identifier "%s" is not defined.', $id)); - } -} diff --git a/src/Component/ProcessRunner/Printer.php b/src/Component/ProcessRunner/Printer.php deleted file mode 100644 index cc7967f9b..000000000 --- a/src/Component/ProcessRunner/Printer.php +++ /dev/null @@ -1,76 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\ProcessRunner; - -use Deployer\Host\Host; -use Symfony\Component\Console\Output\OutputInterface; - -class Printer -{ - /** - * @var OutputInterface - */ - private $output; - - public function __construct(OutputInterface $output) - { - $this->output = $output; - } - - public function command(Host $host, string $type, string $command): void - { - // -v for run command - if ($this->output->isVerbose()) { - $this->output->writeln("[$host] $type $command"); - } - } - - /** - * Returns a callable for use with the symfony Process->run($callable) method. - * - * @return callable A function expecting a int $type (e.g. Process::OUT or Process::ERR) and string $buffer parameters. - */ - public function callback(Host $host, bool $forceOutput): callable - { - return function ($type, $buffer) use ($forceOutput, $host) { - if ($this->output->isVerbose() || $forceOutput) { - $this->printBuffer($type, $host, $buffer); - } - }; - } - - /** - * @param string $type Process::OUT or Process::ERR - */ - public function printBuffer(string $type, Host $host, string $buffer): void - { - foreach (explode("\n", rtrim($buffer)) as $line) { - $this->writeln($type, $host, $line); - } - } - - public function writeln(string $type, Host $host, string $line): void - { - $line = self::filterOutput($line); - - // Omit empty lines - if (empty($line)) { - return; - } - - $this->output->writeln("[$host] $line"); - } - - public static function filterOutput(string $output): string - { - return preg_replace('/\[exit_code:(.*?)]/', '', $output); - } -} diff --git a/src/Component/ProcessRunner/ProcessRunner.php b/src/Component/ProcessRunner/ProcessRunner.php deleted file mode 100644 index ef73c0a92..000000000 --- a/src/Component/ProcessRunner/ProcessRunner.php +++ /dev/null @@ -1,92 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\ProcessRunner; - -use Deployer\Exception\RunException; -use Deployer\Exception\TimeoutException; -use Deployer\Host\Host; -use Deployer\Logger\Logger; -use Symfony\Component\Process\Exception\ProcessFailedException; -use Symfony\Component\Process\Exception\ProcessTimedOutException; -use Symfony\Component\Process\Process; - -class ProcessRunner -{ - /** - * @var Printer - */ - private $pop; - /** - * @var Logger - */ - private $logger; - - public function __construct(Printer $pop, Logger $logger) - { - $this->pop = $pop; - $this->logger = $logger; - } - - /** - * Runs a command, consider deployer global configs (timeout,...) - * - * @throws RunException - */ - public function run(Host $host, string $command, array $config = []): string - { - $defaults = [ - 'timeout' => $host->get('default_timeout', 300), - 'idle_timeout' => null, - 'cwd' => getenv('DEPLOYER_ROOT') !== false ? getenv('DEPLOYER_ROOT') : (defined('DEPLOYER_DEPLOY_FILE') ? dirname(DEPLOYER_DEPLOY_FILE) : null), - 'real_time_output' => false, - 'shell' => 'bash -s', - ]; - $config = array_merge($defaults, $config); - - $this->pop->command($host, 'run', $command); - - $terminalOutput = $this->pop->callback($host, $config['real_time_output']); - $callback = function ($type, $buffer) use ($host, $terminalOutput) { - $this->logger->printBuffer($host, $type, $buffer); - $terminalOutput($type, $buffer); - }; - - $command = str_replace('%secret%', $config['secret'] ?? '', $command); - $command = str_replace('%sudo_pass%', $config['sudo_pass'] ?? '', $command); - - $process = Process::fromShellCommandline($config['shell']) - ->setInput($command) - ->setTimeout($config['timeout']) - ->setIdleTimeout($config['idle_timeout']); - - if ($config['cwd'] !== null) { - $process->setWorkingDirectory($config['cwd']); - } - - try { - $process->mustRun($callback); - return $process->getOutput(); - } catch (ProcessFailedException $exception) { - throw new RunException( - $host, - $command, - $process->getExitCode(), - $process->getOutput(), - $process->getErrorOutput(), - ); - } catch (ProcessTimedOutException $exception) { // @phpstan-ignore-line can be thrown but is absent from the phpdoc - throw new TimeoutException( - $command, - $exception->getExceededTimeout(), - ); - } - } -} diff --git a/src/Component/Ssh/Client.php b/src/Component/Ssh/Client.php deleted file mode 100644 index 358686fae..000000000 --- a/src/Component/Ssh/Client.php +++ /dev/null @@ -1,130 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Ssh; - -use Deployer\Component\ProcessRunner\Printer; -use Deployer\Exception\Exception; -use Deployer\Exception\RunException; -use Deployer\Exception\TimeoutException; -use Deployer\Host\Host; -use Deployer\Logger\Logger; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Process\Exception\ProcessTimedOutException; -use Symfony\Component\Process\Process; - -use function Deployer\Support\parse_home_dir; - -class Client -{ - /** - * @var OutputInterface - */ - private $output; - - /** - * @var Printer - */ - private $pop; - - /** - * @var Logger - */ - private $logger; - - public function __construct(OutputInterface $output, Printer $pop, Logger $logger) - { - $this->output = $output; - $this->pop = $pop; - $this->logger = $logger; - } - - /** - * @throws RunException|TimeoutException|Exception - */ - public function run(Host $host, string $command, array $config = []): string - { - $defaults = [ - 'timeout' => $host->get('default_timeout', 300), - 'idle_timeout' => null, - 'real_time_output' => false, - 'no_throw' => false, - ]; - $config = array_merge($defaults, $config); - - $shellId = bin2hex(random_bytes(10)); - $shellCommand = $host->getShell(); - if ($host->has('become') && !empty($host->get('become'))) { - $shellCommand = "sudo -H -u {$host->get('become')} " . $shellCommand; - } - - $ssh = array_merge(['ssh'], $host->connectionOptionsArray(), [$host->connectionString(), ": $shellId; $shellCommand"]); - - // -vvv for ssh command - if ($this->output->isDebug()) { - $sshString = $ssh[0]; - for ($i = 1; $i < count($ssh); $i++) { - $sshString .= ' ' . escapeshellarg((string) $ssh[$i]); - } - $this->output->writeln("[$host] $sshString"); - } - - $this->pop->command($host, 'run', $command); - $this->logger->log("[{$host->getAlias()}] run $command"); - - $command = str_replace('%secret%', strval($config['secret'] ?? ''), $command); - $command = str_replace('%sudo_pass%', strval($config['sudo_pass'] ?? ''), $command); - - $process = new Process($ssh); - $process - ->setInput("( $command ); printf '[exit_code:%s]' $?;") - ->setTimeout((null === $config['timeout']) ? null : (float) $config['timeout']) - ->setIdleTimeout((null === $config['idle_timeout']) ? null : (float) $config['idle_timeout']); - - $callback = function ($type, $buffer) use ($config, $host) { - $this->logger->printBuffer($host, $type, $buffer); - $this->pop->callback($host, boolval($config['real_time_output']))($type, $buffer); - }; - - try { - $process->run($callback); - } catch (ProcessTimedOutException $exception) { - // Let's try to kill all processes started by this command. - $pid = $this->run($host, "ps x | grep $shellId | grep -v grep | awk '{print \$1}'"); - // Minus before pid means all processes in this group. - $this->run($host, "kill -9 -$pid"); - throw new TimeoutException( - $command, - $exception->getExceededTimeout(), - ); - } - - $output = $this->pop->filterOutput($process->getOutput()); - $exitCode = $this->parseExitStatus($process); - - if ($exitCode !== 0 && !$config['no_throw']) { - throw new RunException( - $host, - $command, - $exitCode, - $output, - $process->getErrorOutput(), - ); - } - - return $output; - } - - private function parseExitStatus(Process $process): int - { - preg_match('/\[exit_code:(\d*)]/', $process->getOutput(), $match); - return (int) ($match[1] ?? -1); - } -} diff --git a/src/Component/Ssh/IOArguments.php b/src/Component/Ssh/IOArguments.php deleted file mode 100644 index d492caa63..000000000 --- a/src/Component/Ssh/IOArguments.php +++ /dev/null @@ -1,75 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Ssh; - -use Deployer\Exception\Exception; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class IOArguments -{ - public static function collect(InputInterface $input, OutputInterface $output): array - { - $arguments = []; - foreach ($input->getOptions() as $name => $value) { - if (!$input->getOption($name)) { - continue; - } - if ($name === 'file') { - $arguments[] = "--file"; - $arguments[] = ltrim($value, '='); - continue; - } - if (in_array($name, ['verbose'], true)) { - continue; - } - if (!is_array($value)) { - $value = [$value]; - } - foreach ($value as $v) { - if (is_bool($v)) { - $arguments[] = "--$name"; - continue; - } - - $arguments[] = "--$name"; - $arguments[] = $v; - } - } - - if ($output->isDecorated()) { - $arguments[] = '--decorated'; - } - $verbosity = self::verbosity($output->getVerbosity()); - if (!empty($verbosity)) { - $arguments[] = $verbosity; - } - return $arguments; - } - - private static function verbosity(int $verbosity): string - { - switch ($verbosity) { - case OutputInterface::VERBOSITY_QUIET: - return '-q'; - case OutputInterface::VERBOSITY_NORMAL: - return ''; - case OutputInterface::VERBOSITY_VERBOSE: - return '-v'; - case OutputInterface::VERBOSITY_VERY_VERBOSE: - return '-vv'; - case OutputInterface::VERBOSITY_DEBUG: - return '-vvv'; - default: - throw new Exception('Unknown verbosity level: ' . $verbosity); - } - } -} diff --git a/src/Configuration/Configuration.php b/src/Configuration/Configuration.php deleted file mode 100644 index ebf62953e..000000000 --- a/src/Configuration/Configuration.php +++ /dev/null @@ -1,244 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Configuration; - -use Deployer\Exception\ConfigurationException; -use Deployer\Utility\Httpie; - -use function Deployer\Support\array_merge_alternate; -use function Deployer\Support\is_closure; -use function Deployer\Support\normalize_line_endings; - -class Configuration implements \ArrayAccess -{ - /** - * @var Configuration|null - */ - private $parent; - - /** - * @var array - */ - private $values = []; - - public function __construct(?Configuration $parent = null) - { - $this->parent = $parent; - } - - public function update(array $values): void - { - $this->values = array_merge($this->values, $values); - } - - public function bind(Configuration $parent): void - { - $this->parent = $parent; - } - - /** - * @param mixed $value - */ - public function set(string $name, $value): void - { - $this->values[$name] = $value; - } - - public function has(string $name): bool - { - $ok = array_key_exists($name, $this->values); - if ($ok) { - return true; - } - if ($this->parent) { - return $this->parent->has($name); - } - return false; - } - - public function hasOwn(string $name): bool - { - return array_key_exists($name, $this->values); - } - - public function add(string $name, array $array): void - { - if ($this->has($name)) { - $config = $this->get($name); - if (!is_array($config)) { - throw new ConfigurationException("Config option \"$name\" isn't array."); - } - $this->set($name, array_merge_alternate($config, $array)); - } else { - $this->set($name, $array); - } - } - - /** - * @param mixed|null $default - * @return mixed|null - */ - public function get(string $name, $default = null) - { - if (array_key_exists($name, $this->values)) { - if (is_closure($this->values[$name])) { - return $this->values[$name] = $this->parse(call_user_func($this->values[$name])); - } else { - return $this->parse($this->values[$name]); - } - } - - if ($this->parent) { - $rawValue = $this->parent->fetch($name); - if ($rawValue !== null) { - if (is_closure($rawValue)) { - return $this->values[$name] = $this->parse(call_user_func($rawValue)); - } else { - return $this->values[$name] = $this->parse($rawValue); - } - } - } - - if (func_num_args() >= 2) { - return $this->parse($default); - } - - throw new ConfigurationException("Config option \"$name\" does not exist."); - } - - /** - * @return mixed|null - */ - public function fetch(string $name) - { - if (array_key_exists($name, $this->values)) { - return $this->values[$name]; - } - if ($this->parent) { - return $this->parent->fetch($name); - } - return null; - } - - /** - * @param string|mixed $value - * @return string|mixed - */ - public function parse($value) - { - if (is_string($value)) { - $normalizedValue = normalize_line_endings($value); - return preg_replace_callback('/\{\{\s*([\w\.\/-]+)\s*\}\}/', [$this, 'parseCallback'], $normalizedValue); - } - - return $value; - } - - public function ownValues(): array - { - return $this->values; - } - - public function keys(): array - { - return array_keys($this->values); - } - - /** - * @param array $matches - * @return mixed|null - */ - private function parseCallback(array $matches) - { - return isset($matches[1]) ? $this->get($matches[1]) : null; - } - - /** - * @param mixed $offset - * @return bool - */ - #[\ReturnTypeWillChange] - public function offsetExists($offset) - { - return $this->has($offset); - } - - /** - * @param string $offset - * @return mixed|null - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint - */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) - { - return $this->get($offset); - } - - /** - * @param string $offset - * @param mixed $value - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint - */ - #[\ReturnTypeWillChange] - public function offsetSet($offset, $value): void - { - $this->set($offset, $value); - } - - /** - * @param mixed $offset - */ - #[\ReturnTypeWillChange] - public function offsetUnset($offset): void - { - unset($this->values[$offset]); - } - - public function load(): void - { - if (!$this->has('master_url')) { - return; - } - - $values = Httpie::get($this->get('master_url') . '/load') - ->jsonBody([ - 'host' => $this->get('alias'), - ]) - ->getJson(); - $this->update($values); - } - - public function save(): void - { - if (!$this->has('master_url')) { - return; - } - - Httpie::get($this->get('master_url') . '/save') - ->jsonBody([ - 'host' => $this->get('alias'), - 'config' => $this->persist(), - ]) - ->getJson(); - } - - public function persist(): array - { - $values = []; - foreach ($this->values as $key => $value) { - if (is_closure($value)) { - continue; - } - $values[$key] = $value; - } - return $values; - } -} diff --git a/src/Deployer.php b/src/Deployer.php deleted file mode 100755 index 21963bd7f..000000000 --- a/src/Deployer.php +++ /dev/null @@ -1,382 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Deployer\Collection\Collection; -use Deployer\Command\BlackjackCommand; -use Deployer\Command\ConfigCommand; -use Deployer\Command\InitCommand; -use Deployer\Command\MainCommand; -use Deployer\Command\RunCommand; -use Deployer\Command\SshCommand; -use Deployer\Command\TreeCommand; -use Deployer\Command\WorkerCommand; -use Deployer\Component\PharUpdate\Console\Command as PharUpdateCommand; -use Deployer\Component\PharUpdate\Console\Helper as PharUpdateHelper; -use Deployer\Component\Pimple\Container; -use Deployer\Component\ProcessRunner\Printer; -use Deployer\Component\ProcessRunner\ProcessRunner; -use Deployer\Component\Ssh\Client; -use Deployer\Configuration\Configuration; -use Deployer\Executor\Master; -use Deployer\Executor\Messenger; -use Deployer\Executor\Server; -use Deployer\Host\Host; -use Deployer\Host\HostCollection; -use Deployer\Host\Localhost; -use Deployer\Importer\Importer; -use Deployer\Logger\Handler\FileHandler; -use Deployer\Logger\Handler\NullHandler; -use Deployer\Logger\Logger; -use Deployer\Selector\Selector; -use Deployer\Task; -use Deployer\Task\ScriptManager; -use Deployer\Task\TaskCollection; -use Deployer\Utility\Httpie; -use Deployer\Utility\Rsync; -use Symfony\Component\Console; -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\ConsoleOutput; -use Symfony\Component\Console\Output\OutputInterface; -use Throwable; - -/** - * Deployer class represents DI container for configuring - * - * @property Application $console - * @property InputInterface $input - * @property OutputInterface $output - * @property Task\TaskCollection|Task\Task[] $tasks - * @property HostCollection|Host[] $hosts - * @property Configuration $config - * @property Rsync $rsync - * @property Client $sshClient - * @property ProcessRunner $processRunner - * @property Task\ScriptManager $scriptManager - * @property Selector $selector - * @property Server $server - * @property Master $master - * @property Messenger $messenger - * @property Messenger $logger - * @property Printer $pop - * @property Collection $fail - * @property InputDefinition $inputDefinition - * @property Importer $importer - */ -class Deployer extends Container -{ - /** - * Global instance of deployer. It's can be accessed only after constructor call. - * @var Deployer - */ - private static $instance; - - public function __construct(Application $console) - { - parent::__construct(); - - /****************************** - * Console * - ******************************/ - - $console->getDefinition()->addOption( - new InputOption('file', 'f', InputOption::VALUE_REQUIRED, 'Recipe file path'), - ); - - $this['console'] = function () use ($console) { - return $console; - }; - $this['input'] = function () { - throw new \RuntimeException('Uninitialized "input" in Deployer container.'); - }; - $this['output'] = function () { - throw new \RuntimeException('Uninitialized "output" in Deployer container.'); - }; - $this['inputDefinition'] = function () { - return new InputDefinition(); - }; - $this['questionHelper'] = function () { - return $this->getHelper('question'); - }; - - /****************************** - * Config * - ******************************/ - - $this['config'] = function () { - return new Configuration(); - }; - // -l act as if it had been invoked as a login shell (i.e. source ~/.profile file) - // -s commands are read from the standard input (no arguments should remain after this option) - $this->config['shell'] = function () { - if (currentHost() instanceof Localhost) { - return 'bash -s'; // Non-login shell for localhost. - } - return 'bash -ls'; - }; - $this->config['forward_agent'] = true; - $this->config['ssh_multiplexing'] = true; - - /****************************** - * Core * - ******************************/ - - $this['pop'] = function ($c) { - return new Printer($c['output']); - }; - $this['sshClient'] = function ($c) { - return new Client($c['output'], $c['pop'], $c['logger']); - }; - $this['rsync'] = function ($c) { - return new Rsync($c['pop'], $c['output']); - }; - $this['processRunner'] = function ($c) { - return new ProcessRunner($c['pop'], $c['logger']); - }; - $this['tasks'] = function () { - return new TaskCollection(); - }; - $this['hosts'] = function () { - return new HostCollection(); - }; - $this['scriptManager'] = function ($c) { - return new ScriptManager($c['tasks']); - }; - $this['selector'] = function ($c) { - return new Selector($c['hosts']); - }; - $this['fail'] = function () { - return new Collection(); - }; - $this['messenger'] = function ($c) { - return new Messenger($c['input'], $c['output'], $c['logger']); - }; - $this['server'] = function ($c) { - return new Server( - $c['output'], - $this, - ); - }; - $this['master'] = function ($c) { - return new Master( - $c['input'], - $c['output'], - $c['server'], - $c['messenger'], - ); - }; - $this['importer'] = function () { - return new Importer(); - }; - - /****************************** - * Logger * - ******************************/ - - $this['log_handler'] = function () { - return !empty($this['log']) - ? new FileHandler($this['log']) - : new NullHandler(); - }; - $this['logger'] = function () { - return new Logger($this['log_handler']); - }; - - self::$instance = $this; - } - - public static function get(): self - { - return self::$instance; - } - - /** - * Init console application - */ - public function init() - { - $this->addTaskCommands(); - $this->getConsole()->add(new BlackjackCommand()); - $this->getConsole()->add(new ConfigCommand($this)); - $this->getConsole()->add(new WorkerCommand($this)); - $this->getConsole()->add(new InitCommand()); - $this->getConsole()->add(new TreeCommand($this)); - $this->getConsole()->add(new SshCommand($this)); - $this->getConsole()->add(new RunCommand($this)); - if (self::isPharArchive()) { - $selfUpdate = new PharUpdateCommand('self-update'); - $selfUpdate->setDescription('Updates deployer.phar to the latest version'); - $selfUpdate->setManifestUri('https://deployer.org/manifest.json'); - $selfUpdate->setRunningFile(DEPLOYER_BIN); - $this->getConsole()->add($selfUpdate); - $this->getConsole()->getHelperSet()->set(new PharUpdateHelper()); - } - } - - /** - * Transform tasks to console commands. - */ - public function addTaskCommands() - { - foreach ($this->tasks as $name => $task) { - $command = new MainCommand($name, $task->getDescription(), $this); - $command->setHidden($task->isHidden()); - - $this->getConsole()->add($command); - } - } - - /** - * @return mixed - * @throws \InvalidArgumentException - */ - public function __get(string $name) - { - if (isset($this[$name])) { - return $this[$name]; - } else { - throw new \InvalidArgumentException("Property \"$name\" does not exist."); - } - } - - /** - * @param mixed $value - */ - public function __set(string $name, $value) - { - $this[$name] = $value; - } - - public function getConsole(): Application - { - return $this['console']; - } - - public function getHelper(string $name): Console\Helper\HelperInterface - { - return $this->getConsole()->getHelperSet()->get($name); - } - - /** - * Run Deployer - */ - public static function run(string $version, ?string $deployFile) - { - if (str_contains($version, 'master')) { - // Get version from composer.lock - $lockFile = __DIR__ . '/../../../../composer.lock'; - if (file_exists($lockFile)) { - $content = file_get_contents($lockFile); - $json = json_decode($content); - foreach ($json->packages as $package) { - if ($package->name === 'deployer/deployer') { - $version = $package->version; - } - } - } - } - - // Version must be without "v" prefix. - // Incorrect: v7.0.0 - // Correct: 7.0.0 - // But deployphp/deployer uses tags with "v", and it gets passed to - // the composer.json file. Let's manually remove it from the version. - if (preg_match("/^v/", $version)) { - $version = substr($version, 1); - } - - if (!defined('DEPLOYER_VERSION')) { - define('DEPLOYER_VERSION', $version); - } - - $input = new ArgvInput(); - $output = new ConsoleOutput(); - - try { - // Init Deployer - $console = new Application('Deployer', $version); - $deployer = new self($console); - - // Import recipe file - if (is_readable($deployFile ?? '')) { - $deployer->importer->import($deployFile); - } - - // Run Deployer - $deployer->init(); - $console->run($input, $output); - - } catch (Throwable $exception) { - if (str_contains("$input", "-vvv")) { - $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); - } - self::printException($output, $exception); - - exit(1); - } - } - - public static function printException(OutputInterface $output, Throwable $exception) - { - $class = get_class($exception); - $file = basename($exception->getFile()); - $output->writeln([ - " {$class} in {$file} on line {$exception->getLine()}:", - "", - implode("\n", array_map(function ($line) { - return " " . $line; - }, explode("\n", $exception->getMessage()))), - "", - ]); - if ($output->isDebug()) { - $output->writeln($exception->getTraceAsString()); - } - - if ($exception->getPrevious()) { - self::printException($output, $exception->getPrevious()); - } - } - - public static function isWorker(): bool - { - return Deployer::get()->config->has('master_url'); - } - - /** - * @param mixed ...$arguments - * @return array|bool|string - * @throws \Exception - */ - public static function proxyCallToMaster(Host $host, string $func, ...$arguments) - { - // As request to master will stop master permanently, - // wait a little bit in order for periodic timer of - // master gather worker outputs and print it to user. - usleep(100000); // Sleep 100ms. - return Httpie::get(get('master_url') . '/proxy') - ->setopt(CURLOPT_TIMEOUT, 0) // no timeout - ->jsonBody([ - 'host' => $host->getAlias(), - 'func' => $func, - 'arguments' => $arguments, - ]) - ->getJson(); - } - - public static function isPharArchive(): bool - { - return 'phar:' === substr(__FILE__, 0, 5); - } -} diff --git a/src/Documentation/ApiGen.php b/src/Documentation/ApiGen.php deleted file mode 100644 index 31793e1eb..000000000 --- a/src/Documentation/ApiGen.php +++ /dev/null @@ -1,113 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Documentation; - -class ApiGen -{ - /** - * @var array - */ - private $fns = []; - - public function parse(string $source): void - { - $comment = ''; - $params = ''; - - $source = str_replace("\r\n", "\n", $source); - - $state = 'root'; - foreach (explode("\n", $source) as $lineNumber => $line) { - switch ($state) { - case 'root': - if (str_starts_with($line, '/**')) { - $state = 'comment'; - break; - } - if (str_starts_with($line, 'function')) { - $signature = preg_replace('/^function\s+/', '', $line); - $funcName = preg_replace('/\(.+$/', '', $signature); - $this->fns[] = [ - 'comment' => $comment, - 'params' => $params, - 'funcName' => $funcName, - 'signature' => $signature, - ]; - $comment = ''; - $params = ''; - break; - } - break; - - case 'comment': - if (str_ends_with($line, '*/')) { - $state = 'root'; - break; - } - if (preg_match('/^\s\*\s@param\s(?.+?)\$(?.+?)\s(?.+)$/', $line, $matches)) { - if (empty($params)) { - $params = "| Argument | Type | Comment |\n|---|---|---|\n"; - } - $type = implode(' or ', array_map(function ($t) { - $t = trim($t, ' '); - return "`$t`"; - }, explode('|', $matches['type']))); - $params .= "| `\${$matches['name']}` | $type | {$matches['comment']} |\n"; - break; - } - if (str_starts_with($line, ' * @')) { - break; - } - $comment .= preg_replace('/^\s\*\s?/', '', $line) . "\n"; - break; - } - } - } - - public function markdown(): string - { - $output = << - - - - # API Reference - - - MD; - - foreach ($this->fns as $fn) { - [ - 'comment' => $comment, - 'params' => $params, - 'funcName' => $funcName, - 'signature' => $signature, - ] = $fn; - - if (!empty($params)) { - $params = "\n$params"; - } - - $output .= << - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Documentation; - -class DocConfig -{ - /** - * @var string - */ - public $name; - /** - * @var string - */ - public $defaultValue; - /** - * @var string - */ - public $comment; - /** - * @var string - */ - public $recipePath; - /** - * @var int - */ - public $lineNumber; -} diff --git a/src/Documentation/DocGen.php b/src/Documentation/DocGen.php deleted file mode 100644 index 0e8ee636a..000000000 --- a/src/Documentation/DocGen.php +++ /dev/null @@ -1,412 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Documentation; - -use RecursiveDirectoryIterator; -use RecursiveIteratorIterator; -use RecursiveRegexIterator; -use RegexIterator; - -use function Deployer\Support\str_contains as str_contains; - -class DocGen -{ - /** - * @var string - */ - public $root; - /** - * @var DocRecipe[] - */ - public $recipes = []; - - public function __construct(string $root) - { - $this->root = str_replace(DIRECTORY_SEPARATOR, '/', realpath($root)); - } - - public function parse(string $source): void - { - $directory = new RecursiveDirectoryIterator($source); - $iterator = new RegexIterator(new RecursiveIteratorIterator($directory), '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH); - foreach ($iterator as [$path]) { - $realPath = str_replace(DIRECTORY_SEPARATOR, '/', realpath($path)); - $recipePath = str_replace($this->root . '/', '', $realPath); - $recipeName = preg_replace('/\.php$/i', '', basename($recipePath)); - $recipe = new DocRecipe($recipeName, $recipePath); - $recipe->parse(file_get_contents($path)); - $this->recipes[$recipePath] = $recipe; - } - } - - public function gen(string $destination): ?string - { - foreach ($this->recipes as $recipe) { - // $find will try to return DocConfig for a given config $name. - $findConfig = function (string $name) use ($recipe): ?DocConfig { - if (array_key_exists($name, $recipe->config)) { - return $recipe->config[$name]; - } - foreach ($recipe->require as $r) { - if (array_key_exists($r, $this->recipes)) { - if (array_key_exists($name, $this->recipes[$r]->config)) { - return $this->recipes[$r]->config[$name]; - } - } - } - foreach ($this->recipes as $r) { - if (array_key_exists($name, $r->config)) { - return $r->config[$name]; - } - } - return null; - }; - $findConfigOverride = function (DocRecipe $recipe, string $name) use (&$findConfigOverride): ?DocConfig { - foreach ($recipe->require as $r) { - if (array_key_exists($r, $this->recipes)) { - if (array_key_exists($name, $this->recipes[$r]->config)) { - return $this->recipes[$r]->config[$name]; - } - } - } - foreach ($recipe->require as $r) { - if (array_key_exists($r, $this->recipes)) { - return $findConfigOverride($this->recipes[$r], $name); - } - } - return null; - }; - // Replace all {{name}} with link to correct config declaration. - $replaceLinks = function (string $comment) use ($findConfig): string { - $output = ''; - $code = false; - foreach (explode("\n", $comment) as $i => $line) { - if (str_starts_with($line, '```') || str_starts_with($line, '~~~')) { - $code = !$code; - } - if ($code) { - $output .= $line; - $output .= "\n"; - continue; - } - $output .= preg_replace_callback('#(\{\{(?[\w_:\-/]+)\}\})#', function ($m) use ($findConfig) { - $name = $m['name']; - $config = $findConfig($name); - if ($config !== null) { - $md = php_to_md($config->recipePath); - $anchor = anchor($name); - return "[$name](/docs/$md#$anchor)"; - } - return "{{" . $name . "}}"; - }, $line); - $output .= "\n"; - } - return $output; - }; - $findTask = function (string $name, bool $searchOtherRecipes = true) use ($recipe): ?DocTask { - if (array_key_exists($name, $recipe->tasks)) { - return $recipe->tasks[$name]; - } - foreach ($recipe->require as $r) { - if (array_key_exists($r, $this->recipes)) { - if (array_key_exists($name, $this->recipes[$r]->tasks)) { - return $this->recipes[$r]->tasks[$name]; - } - } - } - if ($searchOtherRecipes) { - foreach ($this->recipes as $r) { - if (array_key_exists($name, $r->tasks)) { - return $r->tasks[$name]; - } - } - } - return null; - }; - - $title = join(' ', array_map('ucfirst', explode('_', $recipe->recipeName))) . ' Recipe'; - $config = ''; - $tasks = ''; - $intro = <<recipePath'; - ``` - - [Source](/$recipe->recipePath) - - - MD; - if (is_framework_recipe($recipe)) { - $brandName = framework_brand_name($recipe->recipeName); - $typeOfProject = preg_match('/^symfony/i', $recipe->recipeName) ? 'Application' : 'Project'; - $title = "How to Deploy a $brandName $typeOfProject"; - - $intro .= <<group as $taskName) { - $t = $findTask($taskName); - if ($t !== null) { - $intro .= "$ident* {$t->mdLink()} – $t->desc\n"; - if ($t->group !== null) { - $map($t, $ident . ' '); - } - } - } - }; - $deployTask = $findTask('deploy'); - if ($deployTask !== null) { - $intro .= "The [deploy](#deploy) task of **$brandName** consists of:\n"; - $map($deployTask); - } - - $intro .= "\n\n"; - - $artifactBuildTask = $findTask('artifact:build', false); - $artifactDeployTask = $findTask('artifact:deploy', false); - if ($artifactDeployTask !== null && $artifactBuildTask !== null) { - $intro .= "In addition the **$brandName** recipe contains an artifact deployment.\n"; - $intro .= <<set('local', true); - ``` - to your deploy.php or - ```yaml - hosts: - localhost: - local: true - ``` - to your deploy yaml. - - The [artifact:build](#artifact:build) command of **$brandName** consists of: - MD; - $map($artifactBuildTask); - - $intro .= "\n\n The [artifact:deploy](#artifact:deploy) command of **$brandName** consists of:\n"; - - $map($artifactDeployTask); - - $intro .= "\n\n"; - } - } - if (count($recipe->require) > 0) { - if (is_framework_recipe($recipe)) { - $link = recipe_to_md_link($recipe->require[0]); - $intro .= "The $recipe->recipeName recipe is based on the $link recipe.\n"; - } else { - $intro .= "* Requires\n"; - foreach ($recipe->require as $r) { - $link = recipe_to_md_link($r); - $intro .= " * {$link}\n"; - } - } - } - if (!empty($recipe->comment)) { - $intro .= "\n$recipe->comment\n"; - } - if (count($recipe->config) > 0) { - $config .= "## Configuration\n"; - foreach ($recipe->config as $c) { - $config .= "### {$c->name}\n"; - $config .= "[Source](https://github.com/deployphp/deployer/blob/master/{$c->recipePath}#L{$c->lineNumber})\n\n"; - $o = $findConfigOverride($recipe, $c->name); - if ($o !== null) { - $md = php_to_md($o->recipePath); - $anchor = anchor($c->name); - $config .= "Overrides [{$c->name}](/docs/$md#$anchor) from `$o->recipePath`.\n\n"; - } - $config .= $replaceLinks($c->comment); - $config .= "\n"; - if ( - !empty($c->defaultValue) - && $c->defaultValue !== "''" - && $c->defaultValue !== '[]' - ) { - $config .= "```php title=\"Default value\"\n"; - $config .= $c->defaultValue; - $config .= "\n"; - $config .= "```\n"; - } - $config .= "\n\n"; - } - } - if (count($recipe->tasks) > 0) { - $tasks .= "## Tasks\n\n"; - foreach ($recipe->tasks as $t) { - $tasks .= "### {$t->name}\n"; - $tasks .= "[Source](https://github.com/deployphp/deployer/blob/master/{$t->recipePath}#L{$t->lineNumber})\n\n"; - $tasks .= add_tailing_dot($t->desc) . "\n\n"; - $tasks .= $replaceLinks($t->comment); - if (is_array($t->group)) { - $tasks .= "\n\n"; - $tasks .= "This task is group task which contains next tasks:\n"; - foreach ($t->group as $taskName) { - $t = $findTask($taskName); - if ($t !== null) { - $tasks .= "* {$t->mdLink()}\n"; - } else { - $tasks .= "* `$taskName`\n"; - } - } - } - $tasks .= "\n\n"; - } - } - - $output = << - - - - # $title - - $intro - $config - $tasks - MD; - - $filePath = "$destination/" . php_to_md($recipe->recipePath); - if (!file_exists(dirname($filePath))) { - mkdir(dirname($filePath), 0o755, true); - } - $output = remove_text_emoji($output); - file_put_contents($filePath, $output); - } - $this->generateRecipesIndex($destination); - $this->generateContribIndex($destination); - return null; - } - - public function generateRecipesIndex(string $destination) - { - $index = "# All Recipes\n\n"; - $list = []; - foreach ($this->recipes as $recipe) { - if (preg_match('/^recipe\/[^\/]+\.php$/', $recipe->recipePath)) { - $name = framework_brand_name($recipe->recipeName); - $list[] = "* [$name Recipe](/docs/recipe/{$recipe->recipeName}.md)"; - } - } - sort($list); - $index .= implode("\n", $list); - file_put_contents("$destination/recipe/README.md", $index); - } - - public function generateContribIndex(string $destination) - { - $index = "# All Contrib Recipes\n\n"; - $list = []; - foreach ($this->recipes as $recipe) { - if (preg_match('/^contrib\/[^\/]+\.php$/', $recipe->recipePath)) { - $name = ucfirst($recipe->recipeName); - $list[] = "* [$name Recipe](/docs/contrib/$recipe->recipeName.md)"; - } - } - sort($list); - $index .= implode("\n", $list); - file_put_contents("$destination/contrib/README.md", $index); - } -} - -function trim_comment(string $line): string -{ - return preg_replace('#^(/\*\*?\s?|\s\*\s?|//\s?)#', '', $line); -} - -function indent(string $text): string -{ - return implode("\n", array_map(function ($line) { - return " " . $line; - }, explode("\n", $text))); -} - -function php_to_md(string $file): string -{ - return preg_replace('#\.php$#', '.md', $file); -} - -function anchor(string $s): string -{ - return strtolower(str_replace(':', '', $s)); -} - -function remove_text_emoji(string $text): string -{ - return preg_replace('/:(bowtie|smile|laughing|blush|smiley|relaxed|smirk|heart_eyes|kissing_heart|kissing_closed_eyes|flushed|relieved|satisfied|grin|wink|stuck_out_tongue_winking_eye|stuck_out_tongue_closed_eyes|grinning|kissing|kissing_smiling_eyes|stuck_out_tongue|sleeping|worried|frowning|anguished|open_mouth|grimacing|confused|hushed|expressionless|unamused|sweat_smile|sweat|disappointed_relieved|weary|pensive|disappointed|confounded|fearful|cold_sweat|persevere|cry|sob|joy|astonished|scream|neckbeard|tired_face|angry|rage|triumph|sleepy|yum|mask|sunglasses|dizzy_face|imp|smiling_imp|neutral_face|no_mouth|innocent|alien|yellow_heart|blue_heart|purple_heart|heart|green_heart|broken_heart|heartbeat|heartpulse|two_hearts|revolving_hearts|cupid|sparkling_heart|sparkles|star|star2|dizzy|boom|collision|anger|exclamation|question|grey_exclamation|grey_question|zzz|dash|sweat_drops|notes|musical_note|fire|hankey|poop|shit|\+1|thumbsup|\-1|thumbsdown|ok_hand|punch|facepunch|fist|v|wave|hand|raised_hand|open_hands|point_up|point_down|point_left|point_right|raised_hands|pray|point_up_2|clap|muscle|metal|fu|walking|runner|running|couple|family|two_men_holding_hands|two_women_holding_hands|dancer|dancers|ok_woman|no_good|information_desk_person|raising_hand|bride_with_veil|person_with_pouting_face|person_frowning|bow|couplekiss|couple_with_heart|massage|haircut|nail_care|boy|girl|woman|man|baby|older_woman|older_man|person_with_blond_hair|man_with_gua_pi_mao|man_with_turban|construction_worker|cop|angel|princess|smiley_cat|smile_cat|heart_eyes_cat|kissing_cat|smirk_cat|scream_cat|crying_cat_face|joy_cat|pouting_cat|japanese_ogre|japanese_goblin|see_no_evil|hear_no_evil|speak_no_evil|guardsman|skull|feet|lips|kiss|droplet|ear|eyes|nose|tongue|love_letter|bust_in_silhouette|busts_in_silhouette|speech_balloon|thought_balloon|feelsgood|finnadie|goberserk|godmode|hurtrealbad|rage1|rage2|rage3|rage4|suspect|trollface|sunny|umbrella|cloud|snowflake|snowman|zap|cyclone|foggy|ocean|cat|dog|mouse|hamster|rabbit|wolf|frog|tiger|koala|bear|pig|pig_nose|cow|boar|monkey_face|monkey|horse|racehorse|camel|sheep|elephant|panda_face|snake|bird|baby_chick|hatched_chick|hatching_chick|chicken|penguin|turtle|bug|honeybee|ant|beetle|snail|octopus|tropical_fish|fish|whale|whale2|dolphin|cow2|ram|rat|water_buffalo|tiger2|rabbit2|dragon|goat|rooster|dog2|pig2|mouse2|ox|dragon_face|blowfish|crocodile|dromedary_camel|leopard|cat2|poodle|paw_prints|bouquet|cherry_blossom|tulip|four_leaf_clover|rose|sunflower|hibiscus|maple_leaf|leaves|fallen_leaf|herb|mushroom|cactus|palm_tree|evergreen_tree|deciduous_tree|chestnut|seedling|blossom|ear_of_rice|shell|globe_with_meridians|sun_with_face|full_moon_with_face|new_moon_with_face|new_moon|waxing_crescent_moon|first_quarter_moon|waxing_gibbous_moon|full_moon|waning_gibbous_moon|last_quarter_moon|waning_crescent_moon|last_quarter_moon_with_face|first_quarter_moon_with_face|moon|earth_africa|earth_americas|earth_asia|volcano|milky_way|partly_sunny|octocat|squirrel|bamboo|gift_heart|dolls|school_satchel|mortar_board|flags|fireworks|sparkler|wind_chime|rice_scene|jack_o_lantern|ghost|santa|christmas_tree|gift|bell|no_bell|tanabata_tree|tada|confetti_ball|balloon|crystal_ball|cd|dvd|floppy_disk|camera|video_camera|movie_camera|computer|tv|iphone|phone|telephone|telephone_receiver|pager|fax|minidisc|vhs|sound|speaker|mute|loudspeaker|mega|hourglass|hourglass_flowing_sand|alarm_clock|watch|radio|satellite|loop|mag|mag_right|unlock|lock|lock_with_ink_pen|closed_lock_with_key|key|bulb|flashlight|high_brightness|low_brightness|electric_plug|battery|calling|email|mailbox|postbox|bath|bathtub|shower|toilet|wrench|nut_and_bolt|hammer|seat|moneybag|yen|dollar|pound|euro|credit_card|money_with_wings|e-mail|inbox_tray|outbox_tray|envelope|incoming_envelope|postal_horn|mailbox_closed|mailbox_with_mail|mailbox_with_no_mail|door|smoking|bomb|gun|hocho|pill|syringe|page_facing_up|page_with_curl|bookmark_tabs|bar_chart|chart_with_upwards_trend|chart_with_downwards_trend|scroll|clipboard|calendar|date|card_index|file_folder|open_file_folder|scissors|pushpin|paperclip|black_nib|pencil2|straight_ruler|triangular_ruler|closed_book|green_book|blue_book|orange_book|notebook|notebook_with_decorative_cover|ledger|books|bookmark|name_badge|microscope|telescope|newspaper|football|basketball|soccer|baseball|tennis|8ball|rugby_football|bowling|golf|mountain_bicyclist|bicyclist|horse_racing|snowboarder|swimmer|surfer|ski|spades|hearts|clubs|diamonds|gem|ring|trophy|musical_score|musical_keyboard|violin|space_invader|video_game|black_joker|flower_playing_cards|game_die|dart|mahjong|clapper|memo|pencil|book|art|microphone|headphones|trumpet|saxophone|guitar|shoe|sandal|high_heel|lipstick|boot|shirt|tshirt|necktie|womans_clothes|dress|running_shirt_with_sash|jeans|kimono|bikini|ribbon|tophat|crown|womans_hat|mans_shoe|closed_umbrella|briefcase|handbag|pouch|purse|eyeglasses|fishing_pole_and_fish|coffee|tea|sake|baby_bottle|beer|beers|cocktail|tropical_drink|wine_glass|fork_and_knife|pizza|hamburger|fries|poultry_leg|meat_on_bone|spaghetti|curry|fried_shrimp|bento|sushi|fish_cake|rice_ball|rice_cracker|rice|ramen|stew|oden|dango|egg|bread|doughnut|custard|icecream|ice_cream|shaved_ice|birthday|cake|cookie|chocolate_bar|candy|lollipop|honey_pot|apple|green_apple|tangerine|lemon|cherries|grapes|watermelon|strawberry|peach|melon|banana|pear|pineapple|sweet_potato|eggplant|tomato|corn|house|house_with_garden|school|office|post_office|hospital|bank|convenience_store|love_hotel|hotel|wedding|church|department_store|european_post_office|city_sunrise|city_sunset|japanese_castle|european_castle|tent|factory|tokyo_tower|japan|mount_fuji|sunrise_over_mountains|sunrise|stars|statue_of_liberty|bridge_at_night|carousel_horse|rainbow|ferris_wheel|fountain|roller_coaster|ship|speedboat|boat|sailboat|rowboat|anchor|rocket|airplane|helicopter|steam_locomotive|tram|mountain_railway|bike|aerial_tramway|suspension_railway|mountain_cableway|tractor|blue_car|oncoming_automobile|car|red_car|taxi|oncoming_taxi|articulated_lorry|bus|oncoming_bus|rotating_light|police_car|oncoming_police_car|fire_engine|ambulance|minibus|truck|train|station|train2|bullettrain_front|bullettrain_side|light_rail|monorail|railway_car|trolleybus|ticket|fuelpump|vertical_traffic_light|traffic_light|warning|construction|beginner|atm|slot_machine|busstop|barber|hotsprings|checkered_flag|crossed_flags|izakaya_lantern|moyai|circus_tent|performing_arts|round_pushpin|triangular_flag_on_post|jp|kr|cn|us|fr|es|it|ru|gb|uk|de|one|two|three|four|five|six|seven|eight|nine|keycap_ten|1234|zero|hash|symbols|arrow_backward|arrow_down|arrow_forward|arrow_left|capital_abcd|abcd|abc|arrow_lower_left|arrow_lower_right|arrow_right|arrow_up|arrow_upper_left|arrow_upper_right|arrow_double_down|arrow_double_up|arrow_down_small|arrow_heading_down|arrow_heading_up|leftwards_arrow_with_hook|arrow_right_hook|left_right_arrow|arrow_up_down|arrow_up_small|arrows_clockwise|arrows_counterclockwise|rewind|fast_forward|information_source|ok|twisted_rightwards_arrows|repeat|repeat_one|new|top|up|cool|free|ng|cinema|koko|signal_strength|u5272|u5408|u55b6|u6307|u6708|u6709|u6e80|u7121|u7533|u7a7a|u7981|sa|restroom|mens|womens|baby_symbol|no_smoking|parking|wheelchair|metro|baggage_claim|accept|wc|potable_water|put_litter_in_its_place|secret|congratulations|m|passport_control|left_luggage|customs|ideograph_advantage|cl|sos|id|no_entry_sign|underage|no_mobile_phones|do_not_litter|non-potable_water|no_bicycles|no_pedestrians|children_crossing|no_entry|eight_spoked_asterisk|eight_pointed_black_star|heart_decoration|vs|vibration_mode|mobile_phone_off|chart|currency_exchange|aries|taurus|gemini|cancer|leo|virgo|libra|scorpius|sagittarius|capricorn|aquarius|pisces|ophiuchus|six_pointed_star|negative_squared_cross_mark|a|b|ab|o2|diamond_shape_with_a_dot_inside|recycle|end|on|soon|clock1|clock130|clock10|clock1030|clock11|clock1130|clock12|clock1230|clock2|clock230|clock3|clock330|clock4|clock430|clock5|clock530|clock6|clock630|clock7|clock730|clock8|clock830|clock9|clock930|heavy_dollar_sign|copyright|registered|tm|x|heavy_exclamation_mark|bangbang|interrobang|o|heavy_multiplication_x|heavy_plus_sign|heavy_minus_sign|heavy_division_sign|white_flower|100|heavy_check_mark|ballot_box_with_check|radio_button|link|curly_loop|wavy_dash|part_alternation_mark|trident|black_square|white_square|white_check_mark|black_square_button|white_square_button|black_circle|white_circle|red_circle|large_blue_circle|large_blue_diamond|large_orange_diamond|small_blue_diamond|small_orange_diamond|small_red_triangle|small_red_triangle_down|shipit):/i', ':​\1:', $text); -} - -function add_tailing_dot(string $sentence): string -{ - if (empty($sentence)) { - return $sentence; - } - if (str_ends_with($sentence, '.')) { - return $sentence; - } - return $sentence . '.'; -} - -function recipe_to_md_link(string $recipe): string -{ - $md = php_to_md($recipe); - $basename = basename($recipe, '.php'); - return "[$basename](/docs/$md)"; -} - -function is_framework_recipe(DocRecipe $recipe): bool -{ - return preg_match('/recipe\/[\w_\d]+\.php$/', $recipe->recipePath) && - !in_array($recipe->recipeName, ['common', 'composer', 'provision'], true); -} - -function framework_brand_name(string $brandName): string -{ - $brandName = preg_replace('/(\w+)(\d)/', '$1 $2', $brandName); - $brandName = preg_replace('/typo 3/', 'TYPO3', $brandName); - $brandName = preg_replace('/yii/', 'Yii2', $brandName); - $brandName = preg_replace('/wordpress/', 'WordPress', $brandName); - $brandName = preg_replace('/_/', ' ', $brandName); - $brandName = preg_replace('/framework/', 'Framework', $brandName); - return ucfirst($brandName); -} diff --git a/src/Documentation/DocRecipe.php b/src/Documentation/DocRecipe.php deleted file mode 100644 index 5f24bb6cc..000000000 --- a/src/Documentation/DocRecipe.php +++ /dev/null @@ -1,184 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Documentation; - -class DocRecipe -{ - /** - * @var string - */ - public $recipeName; - /** - * @var string - */ - public $recipePath; - /** - * @var string - */ - public $comment; - /** - * @var string[] - */ - public $require = []; - /** - * @var DocConfig[] - */ - public $config = []; - /** - * @var DocTask[] - */ - public $tasks = []; - - public function __construct(string $recipeName, string $recipePath) - { - $this->recipeName = $recipeName; - $this->recipePath = $recipePath; - } - - /** - * @return bool|int - */ - public function parse(string $content) - { - $comment = ''; - $desc = ''; - $currentTask = null; - - $content = str_replace("\r\n", "\n", $content); - - $state = 'root'; - $lines = explode("\n", $content); - - for ($i = 0; $i < count($lines); $i++) { - $line = $lines[$i]; - - if (empty($line)) { - continue; // Skip empty lines - } - - $m = []; - $match = function ($regexp) use ($line, &$m) { - return preg_match("#$regexp#", $line, $m); - }; - switch ($state) { - case 'root': - if ($match('^/\*\*?')) { - $state = 'comment'; - $comment .= trim_comment($line) . "\n"; - break; - } - if ($match('^//')) { - $comment .= trim_comment($line) . "\n"; - break; - } - if ($match('^require.+?[\'"](?.+?)[\'"]')) { - $this->require[] = dirname($this->recipePath) . $m['recipe']; - break; - } - if ($match('^set\([\'"](?[\w_:\-/]+?)[\'"]')) { - $set = new DocConfig(); - $set->name = $m['config_name']; - $set->comment = trim($comment); - $comment = ''; - $set->recipePath = $this->recipePath; - $set->lineNumber = $i + 1; - if (preg_match('#^set\(.+?,\s(?.+?)\);$#', $line, $m)) { - $set->defaultValue = $m['value']; - } - if (preg_match('#^set\(.+?,\s\[$#', $line, $m)) { - $multiLineArray = "[\n"; - $line = $lines[++$i]; - while (!preg_match('/^]/', $line)) { - $multiLineArray .= $line . "\n"; - $line = $lines[++$i]; - } - $multiLineArray .= "]"; - $set->defaultValue = $multiLineArray; - } - if (preg_match('/^set\(.+?, function/', $line, $m)) { - $body = []; - $line = $lines[++$i]; - while (!preg_match('/^}\);$/', $line)) { - $body[] = trim($line); - $line = $lines[++$i]; - } - if (count($body) === 1 && preg_match('/throw new/', $body[0])) { - $set->comment .= "\n:::info Required\nThrows exception if not set.\n:::\n"; - } elseif (count($body) <= 4) { - $set->defaultValue = implode("\n", $body); - } else { - $set->comment .= "\n:::info Autogenerated\nThe value of this configuration is autogenerated on access.\n:::\n"; - } - } - $this->config[$set->name] = $set; - break; - } - if ($match('^desc\([\'"](?.+?)[\'"]\);$')) { - $desc = $m['desc']; - break; - } - if ($match('^task\([\'"](?[\w_:-]+?)[\'"],\s\[$')) { - $task = new DocTask(); - $task->name = $m['task_name']; - $task->desc = $desc; - $task->comment = trim($comment); - $comment = ''; - $task->group = []; - $task->recipePath = $this->recipePath; - $task->lineNumber = $i + 1; - $this->tasks[$task->name] = $task; - $state = 'group_task'; - $currentTask = $task; - break; - } - if ($match('^task\([\'"](?[\w_:-]+?)[\'"],')) { - $task = new DocTask(); - $task->name = $m['task_name']; - $task->desc = $desc; - $task->comment = trim($comment); - $comment = ''; - $task->recipePath = $this->recipePath; - $task->lineNumber = $i + 1; - $this->tasks[$task->name] = $task; - break; - } - if ($match('^<\?php')) { - break; - } - if ($match('^namespace Deployer;$')) { - $this->comment = $comment; - break; - } - - $desc = ''; - $comment = ''; - break; - - case 'comment': - if ($match('\*/\s*$')) { - $state = 'root'; - break; - } - $comment .= trim_comment($line) . "\n"; - break; - - case 'group_task': - if ($match('^\s+\'(?[\w_:-]+?)\',$')) { - $currentTask->group[] = $m['task_name']; - break; - } - $state = 'root'; - break; - } - } - return false; - } -} diff --git a/src/Documentation/DocTask.php b/src/Documentation/DocTask.php deleted file mode 100644 index 600b12f38..000000000 --- a/src/Documentation/DocTask.php +++ /dev/null @@ -1,46 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Documentation; - -class DocTask -{ - /** - * @var string - */ - public $name; - /** - * @var string - */ - public $desc; - /** - * @var string - */ - public $comment; - /** - * @var array - */ - public $group; - /** - * @var string - */ - public $recipePath; - /** - * @var int - */ - public $lineNumber; - - public function mdLink(): string - { - $md = php_to_md($this->recipePath); - $anchor = anchor($this->name); - return "[$this->name](/docs/$md#$anchor)"; - } -} diff --git a/src/Exception/ConfigurationException.php b/src/Exception/ConfigurationException.php deleted file mode 100644 index 91b313d66..000000000 --- a/src/Exception/ConfigurationException.php +++ /dev/null @@ -1,13 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -class ConfigurationException extends \RuntimeException {} diff --git a/src/Exception/Exception.php b/src/Exception/Exception.php deleted file mode 100644 index 1aa73becf..000000000 --- a/src/Exception/Exception.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -use Throwable; - -class Exception extends \Exception -{ - /** - * @var string - */ - private static $taskSourceLocation = ''; - /** - * @var string - */ - private $taskFilename = ''; - /** - * @var int|mixed - */ - private $taskLineNumber = 0; - - public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null) - { - if (function_exists('debug_backtrace')) { - $trace = debug_backtrace(); - foreach ($trace as $t) { - if (!empty($t['file']) && $t['file'] === self::$taskSourceLocation) { - $this->taskFilename = basename($t['file']); - $this->taskLineNumber = $t['line']; - break; - } - } - } - parent::__construct($message, $code, $previous); - } - - public static function setTaskSourceLocation(string $filepath): void - { - self::$taskSourceLocation = $filepath; - } - - public function getTaskFilename(): string - { - return $this->taskFilename; - } - - public function getTaskLineNumber(): int - { - return $this->taskLineNumber; - } - - public function setTaskFilename(string $taskFilename): void - { - $this->taskFilename = $taskFilename; - } - - public function setTaskLineNumber(int $taskLineNumber): void - { - $this->taskLineNumber = $taskLineNumber; - } -} diff --git a/src/Exception/GracefulShutdownException.php b/src/Exception/GracefulShutdownException.php deleted file mode 100644 index a5b0bb303..000000000 --- a/src/Exception/GracefulShutdownException.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -/** - * Then this exception thrown, it will not trigger "fail" callback. - * - * fail('deploy', 'deploy:failed'); - * - * task('deploy', function () { - * throw new GracefulShutdownException(...); - * }); - * - * In example above task `deploy:failed` will not be called. - */ -class GracefulShutdownException extends Exception -{ - public const EXIT_CODE = 42; -} diff --git a/src/Exception/HttpieException.php b/src/Exception/HttpieException.php deleted file mode 100644 index c5a15b117..000000000 --- a/src/Exception/HttpieException.php +++ /dev/null @@ -1,13 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -class HttpieException extends \RuntimeException {} diff --git a/src/Exception/RunException.php b/src/Exception/RunException.php deleted file mode 100644 index cf767aa21..000000000 --- a/src/Exception/RunException.php +++ /dev/null @@ -1,85 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -use Deployer\Host\Host; -use Symfony\Component\Process\Process; - -class RunException extends Exception -{ - /** - * @var Host - */ - private $host; - /** - * @var string - */ - private $command; - /** - * @var int - */ - private $exitCode; - /** - * @var string - */ - private $output; - /** - * @var string - */ - private $errorOutput; - - public function __construct( - Host $host, - string $command, - int $exitCode, - string $output, - string $errorOutput - ) { - $this->host = $host; - $this->command = $command; - $this->exitCode = $exitCode; - $this->output = $output; - $this->errorOutput = $errorOutput; - - $message = sprintf('The command "%s" failed.', $command); - parent::__construct($message, $exitCode); - } - - public function getHost(): Host - { - return $this->host; - } - - public function getCommand(): string - { - return $this->command; - } - - public function getExitCode(): int - { - return $this->exitCode; - } - - public function getExitCodeText(): string - { - return Process::$exitCodes[$this->exitCode] ?? 'Unknown error'; - } - - public function getOutput(): string - { - return $this->output; - } - - public function getErrorOutput(): string - { - return $this->errorOutput; - } -} diff --git a/src/Exception/TimeoutException.php b/src/Exception/TimeoutException.php deleted file mode 100644 index cda25191d..000000000 --- a/src/Exception/TimeoutException.php +++ /dev/null @@ -1,22 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -class TimeoutException extends Exception -{ - public function __construct( - string $command, - ?float $timeout - ) { - $message = sprintf('The command "%s" exceeded the timeout of %s seconds.', $command, $timeout); - parent::__construct($message, 1); - } -} diff --git a/src/Exception/WillAskUser.php b/src/Exception/WillAskUser.php deleted file mode 100644 index eea4bf733..000000000 --- a/src/Exception/WillAskUser.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Exception; - -class WillAskUser extends Exception -{ - public function __construct(string $message) - { - parent::__construct($message); - } -} diff --git a/src/Executor/Master.php b/src/Executor/Master.php deleted file mode 100644 index fd4bb06af..000000000 --- a/src/Executor/Master.php +++ /dev/null @@ -1,291 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Executor; - -use Deployer\Component\Ssh\Client; -use Deployer\Component\Ssh\IOArguments; -use Deployer\Deployer; -use Deployer\Host\Host; -use Deployer\Host\Localhost; -use Deployer\Selector\Selector; -use Deployer\Task\Task; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Process\PhpExecutableFinder; -use Symfony\Component\Process\Process; - -const FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; - -function spinner(string $message = ''): string -{ - $frame = FRAMES[(int) ((int) (new \DateTime())->format('u') / 1e5) % count(FRAMES)]; - return " $frame $message\r"; -} - -class Master -{ - /** - * @var InputInterface - */ - private $input; - - /** - * @var OutputInterface - */ - private $output; - - /** - * @var Server - */ - private $server; - - /** - * @var Messenger - */ - private $messenger; - - /** - * @var false|string - */ - private $phpBin; - - public function __construct( - InputInterface $input, - OutputInterface $output, - Server $server, - Messenger $messenger - ) { - $this->input = $input; - $this->output = $output; - $this->server = $server; - $this->messenger = $messenger; - $this->phpBin = (new PhpExecutableFinder())->find(); - } - - /** - * @param Task[] $tasks - * @param Host[] $hosts - */ - public function run(array $tasks, array $hosts, ?Planner $plan = null): int - { - $globalLimit = (int) $this->input->getOption('limit') ?: count($hosts); - - foreach ($tasks as $task) { - if (!$plan) { - $this->messenger->startTask($task); - } - - $plannedHosts = $hosts; - - $limit = min($globalLimit, $task->getLimit() ?? $globalLimit); - - if ($task->isOnce()) { - $plannedHosts = []; - foreach ($hosts as $currentHost) { - if (Selector::apply($task->getSelector(), $currentHost)) { - $plannedHosts[] = $currentHost; - break; - } - } - } elseif ($task->isOncePerNode()) { - $plannedHosts = []; - foreach ($hosts as $currentHost) { - if (Selector::apply($task->getSelector(), $currentHost)) { - $nodeLabel = $currentHost->getHostname(); - $labels = $currentHost->config()->get('labels', []); - if (is_array($labels) && array_key_exists('node', $labels)) { - $nodeLabel = $labels['node']; - } - if (array_key_exists($nodeLabel, $plannedHosts)) { - continue; - } - $plannedHosts[$nodeLabel] = $currentHost; - } - } - } - - if ($limit === 1 || count($plannedHosts) === 1) { - foreach ($plannedHosts as $currentHost) { - if (!Selector::apply($task->getSelector(), $currentHost)) { - if ($plan) { - $plan->commit([], $task); - } - continue; - } - - if ($plan) { - $plan->commit([$currentHost], $task); - continue; - } - - $exitCode = $this->runTask($task, [$currentHost]); - if ($exitCode !== 0) { - return $exitCode; - } - } - } else { - foreach (array_chunk($plannedHosts, $limit) as $chunk) { - $selectedHosts = []; - foreach ($chunk as $currentHost) { - if (Selector::apply($task->getSelector(), $currentHost)) { - $selectedHosts[] = $currentHost; - } - } - - if ($plan) { - $plan->commit($selectedHosts, $task); - continue; - } - - $exitCode = $this->runTask($task, $selectedHosts); - if ($exitCode !== 0) { - return $exitCode; - } - } - } - - if (!$plan) { - $this->messenger->endTask($task); - } - } - - return 0; - } - - /** - * @param Host[] $hosts - */ - private function runTask(Task $task, array $hosts): int - { - if (getenv('DEPLOYER_LOCAL_WORKER') === 'true') { - // This allows to code coverage all recipe, - // as well as speedup tests by not spawning - // lots of processes. Also there is a few tests - // what runs with workers for tests subprocess - // communications. - foreach ($hosts as $host) { - $worker = new Worker(Deployer::get()); - $exitCode = $worker->execute($task, $host); - if ($exitCode !== 0) { - $this->messenger->endTask($task, true); - return $exitCode; - } - } - return 0; - } - - $callback = function (string $output) { - $output = preg_replace('/\n$/', '', $output); - if (strlen($output) !== 0) { - $this->output->writeln($output); - } - }; - - /** @var Process[] $processes */ - $processes = []; - - $this->server->loop->futureTick(function () use (&$processes, $hosts, $task) { - foreach ($hosts as $host) { - $processes[] = $this->createProcess($host, $task); - } - - foreach ($processes as $process) { - $process->start(); - } - }); - - $this->server->loop->addPeriodicTimer(0.03, function ($timer) use (&$processes, $callback) { - $this->gatherOutput($processes, $callback); - if ($this->output->isDecorated() && !getenv('CI')) { - $this->output->write(spinner()); - } - if ($this->allFinished($processes)) { - $this->server->loop->stop(); - $this->server->loop->cancelTimer($timer); - } - }); - - $this->server->loop->run(); - - if ($this->output->isDecorated() && !getenv('CI')) { - $this->output->write(" \r"); // clear spinner - } - $this->gatherOutput($processes, $callback); - - if ($this->cumulativeExitCode($processes) !== 0) { - $this->messenger->endTask($task, true); - } - - return $this->cumulativeExitCode($processes); - } - - protected function createProcess(Host $host, Task $task): Process - { - $command = [ - $this->phpBin, DEPLOYER_BIN, - 'worker', '--port', $this->server->getPort(), - '--task', $task, - '--host', $host->getAlias(), - ]; - $command = array_merge($command, IOArguments::collect($this->input, $this->output)); - if ($task->isVerbose() && $this->output->getVerbosity() === OutputInterface::VERBOSITY_NORMAL) { - $command[] = '-v'; - } - if ($this->output->isDebug()) { - $this->output->writeln("[$host] " . join(' ', $command)); - } - return new Process($command); - } - - /** - * @param Process[] $processes - */ - protected function allFinished(array $processes): bool - { - foreach ($processes as $process) { - if (!$process->isTerminated()) { - return false; - } - } - return true; - } - - /** - * @param Process[] $processes - */ - protected function gatherOutput(array $processes, callable $callback): void - { - foreach ($processes as $process) { - $output = $process->getIncrementalOutput(); - if (strlen($output) !== 0) { - $callback($output); - } - - $errorOutput = $process->getIncrementalErrorOutput(); - if (strlen($errorOutput) !== 0) { - $callback($errorOutput); - } - } - } - - /** - * @param Process[] $processes - */ - protected function cumulativeExitCode(array $processes): int - { - foreach ($processes as $process) { - if ($process->getExitCode() > 0) { - return $process->getExitCode(); - } - } - return 0; - } -} diff --git a/src/Executor/Messenger.php b/src/Executor/Messenger.php deleted file mode 100644 index b5b3c0cd9..000000000 --- a/src/Executor/Messenger.php +++ /dev/null @@ -1,168 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Executor; - -use Deployer\Exception\Exception; -use Deployer\Exception\RunException; -use Deployer\Host\Host; -use Deployer\Logger\Logger; -use Deployer\Task\Task; -use Symfony\Component\Console\Input\Input; -use Symfony\Component\Console\Output\Output; -use Throwable; - -class Messenger -{ - /** - * @var Input - */ - private $input; - - /** - * @var Output - */ - private $output; - - /** - * @var Logger - */ - private $logger; - - /** - * @var int|double - */ - private $startTime; - - public function __construct(Input $input, Output $output, Logger $logger) - { - $this->input = $input; - $this->output = $output; - $this->logger = $logger; - } - - public function startTask(Task $task): void - { - $this->startTime = round(microtime(true) * 1000); - if (getenv('GITHUB_WORKFLOW')) { - $this->output->writeln("::group::task {$task->getName()}"); - } elseif (getenv('GITLAB_CI')) { - $sectionId = md5($task->getName()); - $start = round($this->startTime / 1000); - $this->output->writeln("\e[0Ksection_start:{$start}:{$sectionId}\r\e[0K{$task->getName()}"); - } else { - $this->output->writeln("task {$task->getName()}"); - } - $this->logger->log("task {$task->getName()}"); - } - - /* - * Print task was ok. - */ - public function endTask(Task $task, bool $error = false): void - { - if (empty($this->startTime)) { - $this->startTime = round(microtime(true) * 1000); - } - - $endTime = round(microtime(true) * 1000); - $millis = $endTime - $this->startTime; - $seconds = floor($millis / 1000); - $millis = $millis - $seconds * 1000; - $taskTime = ($seconds > 0 ? "{$seconds}s " : "") . "{$millis}ms"; - - if (getenv('GITHUB_WORKFLOW')) { - $this->output->writeln("::endgroup::"); - } elseif (getenv('GITLAB_CI')) { - $sectionId = md5($task->getName()); - $endTime = round($endTime / 1000); - $this->output->writeln("\e[0Ksection_end:{$endTime}:{$sectionId}\r\e[0K"); - } elseif ($this->output->isVeryVerbose()) { - $this->output->writeln("done {$task->getName()} $taskTime"); - } - if ($error) { - $this->output->writeln("\e[0K\e[31;1mERROR: Task {$task->getName()} failed!\e[0;m"); - return; - } - $this->logger->log("done {$task->getName()} $taskTime"); - - if (!empty($this->input->getOption('profile'))) { - $line = sprintf("%s\t%s\n", $task->getName(), $taskTime); - file_put_contents($this->input->getOption('profile'), $line, FILE_APPEND); - } - } - - public function endOnHost(Host $host): void - { - if ($this->output->isVeryVerbose()) { - $this->output->writeln("done on $host"); - } - } - - public function renderException(Throwable $exception, Host $host): void - { - if ($exception instanceof RunException) { - - $message = ""; - $message .= "[$host] error in {$exception->getTaskFilename()} on line {$exception->getTaskLineNumber()}:\n"; - if ($this->output->getVerbosity() === Output::VERBOSITY_NORMAL) { - $message .= "[$host] run {$exception->getCommand()}\n"; - foreach (explode("\n", $exception->getErrorOutput()) as $line) { - $line = trim($line); - if ($line !== "") { - $message .= "[$host] err $line\n"; - } - } - foreach (explode("\n", $exception->getOutput()) as $line) { - $line = trim($line); - if ($line !== "") { - $message .= "[$host] $line\n"; - } - } - } - $message .= "[$host] exit code {$exception->getExitCode()} ({$exception->getExitCodeText()})\n"; - $this->output->write($message); - - } else { - $message = ""; - $class = get_class($exception); - $file = basename($exception->getFile()); - $line = $exception->getLine(); - if ($exception instanceof Exception) { - $file = $exception->getTaskFilename(); - $line = $exception->getTaskLineNumber(); - } - $message .= "[$host] $class in $file on line $line:\n"; - $message .= "[$host]\n"; - foreach (explode("\n", $exception->getMessage()) as $line) { - $line = trim($line); - if ($line !== "") { - $message .= "[$host] $line\n"; - } - } - $message .= "[$host]\n"; - if ($this->output->isDebug()) { - foreach (explode("\n", $exception->getTraceAsString()) as $line) { - $line = trim($line); - if ($line !== "") { - $message .= "[$host] $line\n"; - } - } - } - $this->output->write($message); - } - - $this->logger->log($exception->__toString()); - - if ($exception->getPrevious()) { - $this->renderException($exception->getPrevious(), $host); - } - } -} diff --git a/src/Executor/Planner.php b/src/Executor/Planner.php deleted file mode 100644 index 801b65e43..000000000 --- a/src/Executor/Planner.php +++ /dev/null @@ -1,70 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Executor; - -use Deployer\Host\Host; -use Deployer\Task\Task; -use Symfony\Component\Console\Helper\Table; -use Symfony\Component\Console\Output\OutputInterface; - -class Planner -{ - /** - * @var Table - */ - private $table; - /** - * @var array - */ - private $template; - - /** - * Planner constructor. - * - * @param Host[] $hosts - */ - public function __construct(OutputInterface $output, array $hosts) - { - $headers = []; - $this->template = []; - foreach ($hosts as $host) { - $headers[] = $host->getTag(); - $this->template[] = $host->getAlias(); - } - $this->table = new Table($output); - $this->table->setHeaders($headers); - $this->table->setStyle('box'); - } - - /** - * @param Host[] $hosts - */ - public function commit(array $hosts, Task $task): void - { - $row = []; - foreach ($this->template as $alias) { - $on = "-"; - foreach ($hosts as $host) { - if ($alias === $host->getAlias()) { - $on = $task->getName(); - break; - } - } - $row[] = $on; - } - $this->table->addRow($row); - } - - public function render() - { - $this->table->render(); - } -} diff --git a/src/Executor/Server.php b/src/Executor/Server.php deleted file mode 100644 index c8006dda1..000000000 --- a/src/Executor/Server.php +++ /dev/null @@ -1,115 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Executor; - -use Deployer\Deployer; -use Deployer\Exception\Exception; -use Deployer\Task\Context; -use Psr\Http\Message\ServerRequestInterface; -use React; -use React\EventLoop\Loop; -use React\Http\HttpServer; -use React\Http\Message\Response; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Throwable; - -class Server -{ - /** - * @var OutputInterface - */ - private $output; - - /** - * @var Deployer - */ - private $deployer; - - /** - * @var React\EventLoop\LoopInterface - */ - public $loop; - - /** - * @var int - */ - private $port; - - public function __construct( - OutputInterface $output, - Deployer $deployer - ) { - $this->output = $output; - $this->deployer = $deployer; - } - - public function start() - { - $this->loop = Loop::get(); - $server = new HttpServer( - $this->loop, - new React\Http\Middleware\StreamingRequestMiddleware(), - new React\Http\Middleware\RequestBodyBufferMiddleware(16 * 1024 * 1024), // 16 MiB - function (ServerRequestInterface $request) { - try { - return $this->router($request); - } catch (Throwable $exception) { - Deployer::printException($this->output, $exception); - return new React\Http\Message\Response(500, ['Content-Type' => 'text/plain'], 'Master error: ' . $exception->getMessage()); - } - }, - ); - $socket = new React\Socket\Server(0, $this->loop); - $server->listen($socket); - $address = $socket->getAddress(); - $this->port = parse_url($address, PHP_URL_PORT); - } - - private function router(ServerRequestInterface $request): Response - { - $path = $request->getUri()->getPath(); - switch ($path) { - case '/load': - ['host' => $host] = json_decode((string) $request->getBody(), true); - - $host = $this->deployer->hosts->get($host); - $config = json_encode($host->config()->persist()); - - return new Response(200, ['Content-Type' => 'application/json'], $config); - - case '/save': - ['host' => $host, 'config' => $config] = json_decode((string) $request->getBody(), true); - - $host = $this->deployer->hosts->get($host); - $host->config()->update($config); - - return new Response(200, ['Content-Type' => 'application/json'], 'true'); - - case '/proxy': - ['host' => $host, 'func' => $func, 'arguments' => $arguments] = json_decode((string) $request->getBody(), true); - - Context::push(new Context($this->deployer->hosts->get($host))); - $answer = call_user_func($func, ...$arguments); - Context::pop(); - - return new Response(200, ['Content-Type' => 'application/json'], json_encode($answer)); - - default: - throw new Exception('Server path not found: ' . $request->getUri()->getPath()); - } - } - - public function getPort(): int - { - return $this->port; - } -} diff --git a/src/Executor/Worker.php b/src/Executor/Worker.php deleted file mode 100644 index 264ab2239..000000000 --- a/src/Executor/Worker.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Executor; - -use Deployer\Deployer; -use Deployer\Exception\Exception; -use Deployer\Exception\GracefulShutdownException; -use Deployer\Exception\RunException; -use Deployer\Host\Host; -use Deployer\Task\Context; -use Deployer\Task\Task; -use Throwable; - -class Worker -{ - /** - * @var Deployer - */ - private $deployer; - - public function __construct(Deployer $deployer) - { - $this->deployer = $deployer; - } - - public function execute(Task $task, Host $host): int - { - try { - Exception::setTaskSourceLocation($task->getSourceLocation()); - - $context = new Context($host); - $task->run($context); - - if ($task->getName() !== 'connect') { - $this->deployer->messenger->endOnHost($host); - } - return 0; - } catch (Throwable $e) { - $this->deployer->messenger->renderException($e, $host); - if ($e instanceof GracefulShutdownException) { - return GracefulShutdownException::EXIT_CODE; - } - if ($e instanceof RunException) { - return $e->getExitCode(); - } - return 255; - } - } -} diff --git a/src/Host/Host.php b/src/Host/Host.php deleted file mode 100644 index 56796e682..000000000 --- a/src/Host/Host.php +++ /dev/null @@ -1,315 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Host; - -use Deployer\Configuration\Configuration; -use Deployer\Deployer; -use Deployer\Exception\ConfigurationException; -use Deployer\Exception\Exception; -use Deployer\Task\Context; - -use function Deployer\Support\colorize_host; -use function Deployer\Support\parse_home_dir; - -class Host -{ - /** - * @var Configuration $config - */ - private $config; - - public function __construct(string $hostname) - { - $parent = null; - if (Deployer::get()) { - $parent = Deployer::get()->config; - } - $this->config = new Configuration($parent); - $this->set('#alias', $hostname); - $this->set('hostname', preg_replace('/\/.+$/', '', $hostname)); - } - - public function __toString(): string - { - return $this->getTag(); - } - - public function config(): Configuration - { - return $this->config; - } - - /** - * @param mixed $value - */ - public function set(string $name, $value): self - { - if ($name === 'alias') { - throw new ConfigurationException("Can not update alias of the host.\nThis will change only host own alias,\nbut not the key it is stored in HostCollection."); - } - if ($name === '#alias') { - $name = 'alias'; - } - $this->config->set($name, $value); - return $this; - } - - public function add(string $name, array $value): self - { - $this->config->add($name, $value); - return $this; - } - - public function has(string $name): bool - { - return $this->config->has($name); - } - - public function hasOwn(string $name): bool - { - return $this->config->hasOwn($name); - } - - /** - * @param mixed|null $default - * @return mixed|null - */ - public function get(string $name, $default = null) - { - return $this->config->get($name, $default); - } - - public function getAlias(): ?string - { - return $this->config->get('alias', null); - } - - public function setTag(string $tag): self - { - $this->config->set('tag', $tag); - return $this; - } - - public function getTag(): ?string - { - return $this->config->get('tag', colorize_host($this->getAlias())); - } - - public function setHostname(string $hostname): self - { - $this->config->set('hostname', $hostname); - return $this; - } - - public function getHostname(): ?string - { - return $this->config->get('hostname', null); - } - - public function setRemoteUser(string $user): self - { - $this->config->set('remote_user', $user); - return $this; - } - - public function getRemoteUser(): ?string - { - return $this->config->get('remote_user', null); - } - - /** - * @param string|int|null $port - * @return $this - */ - public function setPort($port): self - { - $this->config->set('port', $port); - return $this; - } - - /** - * @return string|int|null - */ - public function getPort() - { - return $this->config->get('port', null); - } - - public function setConfigFile(string $file): self - { - $this->config->set('config_file', $file); - return $this; - } - - public function getConfigFile(): ?string - { - return $this->config->get('config_file', null); - } - - public function setIdentityFile(string $file): self - { - $this->config->set('identity_file', $file); - return $this; - } - - public function getIdentityFile(): ?string - { - return $this->config->get('identity_file', null); - } - - public function setForwardAgent(bool $on): self - { - $this->config->set('forward_agent', $on); - return $this; - } - - public function getForwardAgent(): ?bool - { - return $this->config->get('forward_agent', null); - } - - public function setSshMultiplexing(bool $on): self - { - $this->config->set('ssh_multiplexing', $on); - return $this; - } - - public function getSshMultiplexing(): ?bool - { - return $this->config->get('ssh_multiplexing', null); - } - - public function setShell(string $command): self - { - $this->config->set('shell', $command); - return $this; - } - - public function getShell(): ?string - { - return $this->config->get('shell', null); - } - - public function setDeployPath(string $path): self - { - $this->config->set('deploy_path', $path); - return $this; - } - - public function getDeployPath(): ?string - { - return $this->config->get('deploy_path', null); - } - - public function setLabels(array $labels): self - { - $this->config->set('labels', $labels); - return $this; - } - - public function addLabels(array $labels): self - { - $existingLabels = $this->getLabels() ?? []; - $this->setLabels(array_replace_recursive($existingLabels, $labels)); - return $this; - } - - public function getLabels(): ?array - { - return $this->config->get('labels', null); - } - - public function setSshArguments(array $args): self - { - $this->config->set('ssh_arguments', $args); - return $this; - } - - public function getSshArguments(): ?array - { - return $this->config->get('ssh_arguments', null); - } - - public function setSshControlPath(string $path): self - { - $this->config->set('ssh_control_path', $path); - return $this; - } - - public function getSshControlPath(): string - { - return $this->config->get('ssh_control_path', $this->generateControlPath()); - } - - private function generateControlPath(): string - { - $C = $this->getHostname(); - if ($this->has('remote_user')) { - $C = $this->getRemoteUser() . '@' . $C; - } - if ($this->has('port')) { - $C .= ':' . $this->getPort(); - } - - // In case of CI environment, lets use shared memory. - if (getenv('CI') && is_writable('/dev/shm')) { - return "/dev/shm/$C"; - } - - return "~/.ssh/$C"; - } - - public function connectionString(): string - { - if ($this->get('remote_user', '') !== '') { - return $this->get('remote_user') . '@' . $this->get('hostname'); - } - return $this->get('hostname'); - } - - public function connectionOptionsString(): string - { - return implode(' ', array_map('escapeshellarg', $this->connectionOptionsArray())); - } - - /** - * @return string[] - */ - public function connectionOptionsArray(): array - { - $options = []; - if ($this->has('ssh_arguments')) { - foreach ($this->getSshArguments() as $arg) { - $options = array_merge($options, explode(' ', $arg)); - } - } - if ($this->has('port')) { - $options = array_merge($options, ['-p', $this->getPort()]); - } - if ($this->has('config_file')) { - $options = array_merge($options, ['-F', parse_home_dir($this->getConfigFile())]); - } - if ($this->has('identity_file')) { - $options = array_merge($options, ['-i', parse_home_dir($this->getIdentityFile())]); - } - if ($this->has('forward_agent') && $this->getForwardAgent()) { - $options = array_merge($options, ['-A']); - } - if ($this->has('ssh_multiplexing') && $this->getSshMultiplexing()) { - $options = array_merge($options, [ - '-o', 'ControlMaster=auto', - '-o', 'ControlPersist=60', - '-o', 'ControlPath=' . $this->getSshControlPath(), - ]); - } - return $options; - } -} diff --git a/src/Host/HostCollection.php b/src/Host/HostCollection.php deleted file mode 100644 index 37ad6ad4e..000000000 --- a/src/Host/HostCollection.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Host; - -use Deployer\Collection\Collection; - -/** - * @method Host get($name) - * @method Host[] getIterator() - */ -class HostCollection extends Collection -{ - protected function throwNotFound(string $name): void - { - throw new \InvalidArgumentException("Host \"$name\" not found."); - } -} diff --git a/src/Host/Localhost.php b/src/Host/Localhost.php deleted file mode 100644 index c758d7e2a..000000000 --- a/src/Host/Localhost.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Host; - -class Localhost extends Host -{ - public function __construct(string $hostname = 'localhost') - { - parent::__construct($hostname); - } -} diff --git a/src/Host/Range.php b/src/Host/Range.php deleted file mode 100644 index db502104d..000000000 --- a/src/Host/Range.php +++ /dev/null @@ -1,44 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Host; - -class Range -{ - public const PATTERN = '/\[(.+?)\]/'; - - public static function expand(array $hostnames): array - { - $expanded = []; - foreach ($hostnames as $hostname) { - if (preg_match(self::PATTERN, $hostname, $matches)) { - [$start, $end] = explode(':', $matches[1]); - $zeroBased = (bool) preg_match('/^0[1-9]/', $start); - - foreach (range($start, $end) as $i) { - $expanded[] = preg_replace(self::PATTERN, self::format((string) $i, $zeroBased), $hostname); - } - } else { - $expanded[] = $hostname; - } - } - - return $expanded; - } - - private static function format(string $i, bool $zeroBased): string - { - if ($zeroBased) { - return strlen($i) === 1 ? "0$i" : $i; - } else { - return $i; - } - } -} diff --git a/src/Importer/Importer.php b/src/Importer/Importer.php deleted file mode 100644 index 595cb1802..000000000 --- a/src/Importer/Importer.php +++ /dev/null @@ -1,267 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Importer; - -use Deployer\Deployer; -use Deployer\Exception\ConfigurationException; -use Deployer\Exception\Exception; -use JsonSchema\Constraints\Constraint; -use JsonSchema\Constraints\Factory; -use JsonSchema\SchemaStorage; -use JsonSchema\Validator; -use Symfony\Component\Yaml\Yaml; - -use function array_filter; -use function array_keys; -use function Deployer\after; -use function Deployer\before; -use function Deployer\cd; -use function Deployer\download; -use function Deployer\host; -use function Deployer\localhost; -use function Deployer\run; -use function Deployer\runLocally; -use function Deployer\set; -use function Deployer\Support\find_line_number; -use function Deployer\task; -use function Deployer\upload; -use function substr; - -use const ARRAY_FILTER_USE_KEY; - -class Importer -{ - /** - * @var string - */ - private static $recipeFilename; - /** - * @var string - */ - private static $recipeSource; - - /** - * @param string|string[] $paths - */ - public static function import($paths) - { - if (!is_array($paths)) { - $paths = [$paths]; - } - foreach ($paths as $path) { - if (preg_match('/\.php$/i', $path)) { - // Prevent variable leak into deploy.php file - call_user_func(function () use ($path) { - // Reorder autoload stack - $originStack = spl_autoload_functions(); - - require $path; - - $newStack = spl_autoload_functions(); - if ($originStack[0] !== $newStack[0]) { - foreach (array_reverse($originStack) as $loader) { - spl_autoload_unregister($loader); - spl_autoload_register($loader, true, true); - } - } - }); - } elseif (preg_match('/\.ya?ml$/i', $path)) { - self::$recipeFilename = basename($path); - self::$recipeSource = file_get_contents($path, true); - $root = array_filter(Yaml::parse(self::$recipeSource), static function (string $key) { - return substr($key, 0, 1) !== '.'; - }, ARRAY_FILTER_USE_KEY); - - $schema = 'file://' . __DIR__ . '/../schema.json'; - if (Deployer::isPharArchive()) { - $schema = __DIR__ . '/../schema.json'; - } - $yamlSchema = json_decode(file_get_contents($schema)); - $schemaStorage = new SchemaStorage(); - $schemaStorage->addSchema('file://schema', $yamlSchema); - $validator = new Validator(new Factory($schemaStorage)); - $validator->validate($root, $yamlSchema, Constraint::CHECK_MODE_TYPE_CAST); - if (!$validator->isValid()) { - $msg = "YAML " . self::$recipeFilename . " does not validate. Violations:\n"; - foreach ($validator->getErrors() as $error) { - $msg .= "[{$error['property']}] {$error['message']}\n"; - } - throw new ConfigurationException($msg); - } - - foreach (array_keys($root) as $key) { - static::$key($root[$key]); - } - } else { - throw new Exception("Unknown file format: $path\nOnly .php and .yaml supported."); - } - } - } - - protected static function hosts(array $hosts) - { - foreach ($hosts as $alias => $config) { - if ($config['local'] ?? false) { - $host = localhost($alias); - } else { - $host = host($alias); - } - if (is_array($config)) { - foreach ($config as $key => $value) { - $host->set($key, $value); - } - } - } - } - - protected static function config(array $config) - { - foreach ($config as $key => $value) { - set($key, $value); - } - } - - protected static function tasks(array $tasks) - { - $buildTask = function ($name, $steps) { - $body = function () {}; - $task = task($name, $body); - - foreach ($steps as $step) { - $buildStep = function ($step) use (&$body, $task) { - extract($step); - - if (isset($cd)) { - $prev = $body; - $body = function () use ($cd, $prev) { - $prev(); - cd($cd); - }; - } - - if (isset($run)) { - $has = 'run'; - $prev = $body; - $body = function () use ($run, $prev) { - $prev(); - try { - run($run); - } catch (Exception $e) { - $e->setTaskFilename(self::$recipeFilename); - $e->setTaskLineNumber(find_line_number(self::$recipeSource, $run)); - throw $e; - } - }; - } - - if (isset($run_locally)) { - if (isset($has)) { - throw new ConfigurationException("Task step can not have both $has and run_locally."); - } - $has = 'run_locally'; - $prev = $body; - $body = function () use ($run_locally, $prev) { - $prev(); - try { - runLocally($run_locally); - } catch (Exception $e) { - $e->setTaskFilename(self::$recipeFilename); - $e->setTaskLineNumber(find_line_number(self::$recipeSource, $run_locally)); - throw $e; - } - }; - } - - if (isset($upload)) { - if (isset($has)) { - throw new ConfigurationException("Task step can not have both $has and upload."); - } - $has = 'upload'; - $prev = $body; - $body = function () use ($upload, $prev) { - $prev(); - upload($upload['src'], $upload['dest']); - }; - } - - if (isset($download)) { - if (isset($has)) { - throw new ConfigurationException("Task step can not have both $has and download."); - } - $has = 'download'; - $prev = $body; - $body = function () use ($download, $prev) { - $prev(); - download($download['src'], $download['dest']); - }; - } - - $methods = [ - 'desc', - 'once', - 'hidden', - 'limit', - 'select', - ]; - foreach ($methods as $method) { - if (isset($$method)) { - $task->$method($$method); - } - } - }; - - $buildStep($step); - $task->setCallback($body); - } - }; - - foreach ($tasks as $name => $config) { - foreach ($config as $key => $value) { - if (!is_int($key) || !is_string($value)) { - goto not_a_group_task; - } - } - - // Create a group task. - task($name, $config); - continue; - - not_a_group_task: - $buildTask($name, $config); - } - } - - protected static function after(array $after) - { - foreach ($after as $key => $value) { - if (is_array($value)) { - foreach (array_reverse($value) as $v) { - after($key, $v); - } - } else { - after($key, $value); - } - } - } - - protected static function before(array $before) - { - foreach ($before as $key => $value) { - if (is_array($value)) { - foreach (array_reverse($value) as $v) { - before($key, $v); - } - } else { - before($key, $value); - } - } - } -} diff --git a/src/Logger/Handler/FileHandler.php b/src/Logger/Handler/FileHandler.php deleted file mode 100644 index e5eee6d37..000000000 --- a/src/Logger/Handler/FileHandler.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Logger\Handler; - -class FileHandler implements HandlerInterface -{ - /** - * @var string - */ - private $filePath; - - public function __construct(string $filePath) - { - $this->filePath = $filePath; - } - - public function log(string $message): void - { - file_put_contents($this->filePath, $message, FILE_APPEND); - } -} diff --git a/src/Logger/Handler/HandlerInterface.php b/src/Logger/Handler/HandlerInterface.php deleted file mode 100644 index 9de250e6b..000000000 --- a/src/Logger/Handler/HandlerInterface.php +++ /dev/null @@ -1,16 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Logger\Handler; - -interface HandlerInterface -{ - public function log(string $message): void; -} diff --git a/src/Logger/Handler/NullHandler.php b/src/Logger/Handler/NullHandler.php deleted file mode 100644 index 339a587e6..000000000 --- a/src/Logger/Handler/NullHandler.php +++ /dev/null @@ -1,16 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Logger\Handler; - -class NullHandler implements HandlerInterface -{ - public function log(string $message): void {} -} diff --git a/src/Logger/Logger.php b/src/Logger/Logger.php deleted file mode 100644 index 86567e9e0..000000000 --- a/src/Logger/Logger.php +++ /dev/null @@ -1,59 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Logger; - -use Deployer\Component\ProcessRunner\Printer; -use Deployer\Host\Host; -use Deployer\Logger\Handler\HandlerInterface; - -class Logger -{ - /** - * @var HandlerInterface - */ - private $handler; - - public function __construct(HandlerInterface $handler) - { - $this->handler = $handler; - } - - public function log(string $message): void - { - $this->handler->log("$message\n"); - } - - public function callback(Host $host): \Closure - { - return function ($type, $buffer) use ($host) { - $this->printBuffer($host, $type, $buffer); - }; - } - - public function printBuffer(Host $host, string $type, string $buffer): void - { - foreach (explode("\n", rtrim($buffer)) as $line) { - $this->writeln($host, $type, $line); - } - } - - public function writeln(Host $host, string $type, string $line): void - { - $line = Printer::filterOutput($line); - - // Omit empty lines - if (empty($line)) { - return; - } - - $this->log("[{$host->getAlias()}] $line"); - } -} diff --git a/src/Selector/Selector.php b/src/Selector/Selector.php deleted file mode 100644 index 275f9e38f..000000000 --- a/src/Selector/Selector.php +++ /dev/null @@ -1,126 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Selector; - -use Deployer\Host\Host; -use Deployer\Host\HostCollection; - -use function Deployer\Support\array_all; - -class Selector -{ - /** - * @var HostCollection - */ - private $hosts; - - public function __construct(HostCollection $hosts) - { - $this->hosts = $hosts; - } - - /** - * @return Host[] - */ - public function select(string $selectExpression) - { - $conditions = self::parse($selectExpression); - - $hosts = []; - foreach ($this->hosts as $host) { - if (self::apply($conditions, $host)) { - $hosts[] = $host; - } - } - - return $hosts; - } - - public static function apply(?array $conditions, Host $host): bool - { - if (empty($conditions)) { - return true; - } - - $labels = $host->get('labels', []); - $labels['alias'] = $host->getAlias(); - $labels['true'] = 'true'; - $isTrue = function ($value) { - return $value; - }; - - foreach ($conditions as $hmm) { - $ok = []; - foreach ($hmm as [$op, $var, $value]) { - if (is_array($value)) { - $orOk = []; - foreach ($value as $val) { - $orOk[] = self::compare($op, $labels[$var] ?? null, $val); - } - $ok[] = count(array_filter($orOk, $isTrue)) > 0; - } else { - $ok[] = self::compare($op, $labels[$var] ?? null, $value); - } - } - if (count($ok) > 0 && array_all($ok, $isTrue)) { - return true; - } - } - return false; - } - - /** - * @param string|string[] $a - */ - private static function compare(string $op, $a, ?string $b): bool - { - $matchFunction = function ($a, ?string $b) { - foreach ((array) $a as $item) { - if ($item === $b) { - return true; - } - } - - return false; - }; - - if ($op === '=') { - return $matchFunction($a, $b); - } - if ($op === '!=') { - return !$matchFunction($a, $b); - } - return false; - } - - public static function parse(string $expression): array - { - $all = []; - foreach (explode(',', $expression) as $sub) { - $conditions = []; - foreach (explode('&', $sub) as $part) { - $part = trim($part); - if ($part === 'all') { - $conditions[] = ['=', 'true', 'true']; - continue; - } - if (preg_match('/(?.+?)(?!?=)(?.+)/', $part, $match)) { - $values = array_map('trim', explode('|', trim($match['value']))); - $conditions[] = [$match['op'], trim($match['var']), $values]; - } else { - $conditions[] = ['=', 'alias', trim($part)]; - } - } - $all[] = $conditions; - } - return $all; - } -} diff --git a/src/Support/ObjectProxy.php b/src/Support/ObjectProxy.php deleted file mode 100644 index 856a5e2fe..000000000 --- a/src/Support/ObjectProxy.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Support; - -class ObjectProxy -{ - /** - * @var array - */ - private $objects; - - public function __construct(array $objects) - { - $this->objects = $objects; - } - - public function __call(string $name, array $arguments): self - { - foreach ($this->objects as $object) { - $object->$name(...$arguments); - } - return $this; - } -} diff --git a/src/Support/Reporter.php b/src/Support/Reporter.php deleted file mode 100644 index 1066d226e..000000000 --- a/src/Support/Reporter.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. - */ - -namespace Deployer\Support; - -use Deployer\Utility\Httpie; -use Symfony\Component\Process\PhpProcess; - -/** - * @codeCoverageIgnore - */ -class Reporter -{ - public static function report(array $stats): void - { - $version = DEPLOYER_VERSION; - $body = json_encode($stats); - $length = strlen($body); - $php = new PhpProcess(<<start(); - } -} diff --git a/src/Support/helpers.php b/src/Support/helpers.php deleted file mode 100644 index 1f07855c3..000000000 --- a/src/Support/helpers.php +++ /dev/null @@ -1,261 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Support; - -/** - * Flatten array - * - * @param array $array - * @return array - */ -function array_flatten(array $array) -{ - $flatten = []; - array_walk_recursive($array, function ($value) use (&$flatten) { - $flatten[] = $value; - }); - return $flatten; -} - -/** - * Recursively merge two config arrays with a specific behavior: - * - * 1. scalar values are overridden - * 2. array values are extended uniquely if all keys are numeric - * 3. all other array values are merged - * - * @param array $original - * @param array $override - * @return array - * @see http://stackoverflow.com/a/36366886/6812729 - */ -function array_merge_alternate(array $original, array $override) -{ - foreach ($override as $key => $value) { - if (isset($original[$key])) { - if (!is_array($original[$key])) { - if (is_numeric($key)) { - // Append scalar value - $original[] = $value; - } else { - // Override scalar value - $original[$key] = $value; - } - } elseif (array_keys($original[$key]) === range(0, count($original[$key]) - 1)) { - // Uniquely append to array with numeric keys - $original[$key] = array_unique(array_merge($original[$key], $value)); - } else { - // Merge all other arrays - $original[$key] = array_merge_alternate($original[$key], $value); - } - } else { - // Simply add new key/value - $original[$key] = $value; - } - } - - return $original; -} - -/** - * Determines if the given string contains the given value. - */ -function str_contains(string $haystack, string $needle): bool -{ - return strpos($haystack, $needle) !== false; -} - -/** - * Checks if string stars with given prefix. - */ -function starts_with(string $string, string $prefix): bool -{ - $len = strlen($prefix); - return (substr($string, 0, $len) === $prefix); -} - -/** - * This function used for create environment string. - */ -function env_stringify(array $array): string -{ - return implode(' ', array_map( - function ($key, $value) { - return sprintf("%s=%s", $key, escapeshellarg((string) $value)); - }, - array_keys($array), - $array, - )); -} - -/** - * Check if var is closure. - * @param mixed $var - */ -function is_closure($var): bool -{ - return is_object($var) && ($var instanceof \Closure); -} - -/** - * Check if all elements satisfy predicate. - */ -function array_all(array $array, callable $predicate): bool -{ - foreach ($array as $key => $value) { - if (!$predicate($value, $key)) { - return false; - } - } - return true; -} - -/** - * Cleanup CRLF new line endings. - */ -function normalize_line_endings(string $string): string -{ - return str_replace(["\r\n", "\r"], "\n", $string); -} - -/** - * Expand leading tilde (~) symbol in given path. - */ -function parse_home_dir(string $path): string -{ - if ('~' === $path || 0 === strpos($path, '~/')) { - if (isset($_SERVER['HOME'])) { - $home = $_SERVER['HOME']; - } elseif (isset($_SERVER['HOMEDRIVE'], $_SERVER['HOMEPATH'])) { - $home = $_SERVER['HOMEDRIVE'] . $_SERVER['HOMEPATH']; - } else { - return $path; - } - - return $home . substr($path, 1); - } - - return $path; -} - -function find_line_number(string $source, string $string): int -{ - $string = explode(PHP_EOL, $string)[0]; - $before = strstr($source, $string, true); - if (false !== $before) { - return count(explode(PHP_EOL, $before)); - } - return 1; -} - -function find_config_line(string $source, string $name): \Generator -{ - foreach (explode(PHP_EOL, $source) as $n => $line) { - if (preg_match("/\(['\"]{$name}['\"]/", $line)) { - yield [$n + 1, $line]; - } - if (preg_match("/\s{$name}:/", $line)) { - yield [$n + 1, $line]; - } - } -} - -function colorize_host(string $alias): string -{ - if (defined('NO_ANSI')) { - return $alias; - } - - if (in_array($alias, ['localhost', 'local'], true)) { - return $alias; - } - - if (getenv('COLORTERM') === 'truecolor') { - $hsv = function ($h, $s, $v) { - $r = $g = $b = $i = $f = $p = $q = $t = 0; - $i = floor($h * 6); - $f = $h * 6 - $i; - $p = $v * (1 - $s); - $q = $v * (1 - $f * $s); - $t = $v * (1 - (1 - $f) * $s); - switch ($i % 6) { - case 0: - $r = $v; - $g = $t; - $b = $p; - break; - case 1: - $r = $q; - $g = $v; - $b = $p; - break; - case 2: - $r = $p; - $g = $v; - $b = $t; - break; - case 3: - $r = $p; - $g = $q; - $b = $v; - break; - case 4: - $r = $t; - $g = $p; - $b = $v; - break; - case 5: - $r = $v; - $g = $p; - $b = $q; - break; - } - $r = round($r * 255); - $g = round($g * 255); - $b = round($b * 255); - return "\x1b[38;2;{$r};{$g};{$b}m"; - }; - $total = 100; - $colors = []; - for ($i = 0; $i < $total; $i++) { - $colors[] = $hsv($i / $total, .5, .9); - } - if ($alias === 'prod' || $alias === 'production') { - return "$colors[99]$alias\x1b[0m"; - } - if ($alias === 'beta') { - return "$colors[14]$alias\x1b[0m"; - } - $tag = $colors[abs(crc32($alias)) % count($colors)]; - return "$tag$alias\x1b[0m"; - } - - $colors = [ - 'fg=cyan;options=bold', - 'fg=green;options=bold', - 'fg=yellow;options=bold', - 'fg=cyan', - 'fg=blue', - 'fg=yellow', - 'fg=magenta', - 'fg=blue;options=bold', - 'fg=green', - 'fg=magenta;options=bold', - 'fg=red;options=bold', - ]; - $tag = $colors[abs(crc32($alias)) % count($colors)]; - return "<$tag>$alias"; -} - -function escape_shell_argument(string $argument): string -{ - return "'" . str_replace("'", "'\\''", $argument) . "'"; -} diff --git a/src/Task/Context.php b/src/Task/Context.php deleted file mode 100644 index e5d33ab31..000000000 --- a/src/Task/Context.php +++ /dev/null @@ -1,87 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Task; - -use Deployer\Configuration\Configuration; -use Deployer\Exception\Exception; -use Deployer\Host\Host; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class Context -{ - /** - * @var Host - */ - private $host; - - /** - * @var Context[] - */ - private static $contexts = []; - - public function __construct(Host $host) - { - $this->host = $host; - } - - public static function push(Context $context): void - { - self::$contexts[] = $context; - } - - public static function has(): bool - { - return !empty(self::$contexts); - } - - /** - * @return Context|false - * @throws Exception - */ - public static function get() - { - if (empty(self::$contexts)) { - throw new Exception("Context was requested but was not available."); - } - return end(self::$contexts); - } - - public static function pop(): ?Context - { - return array_pop(self::$contexts); - } - - /** - * Throws a Exception when not called within a task-context and therefore no Context is available. - * - * This method provides a useful error to the end-user to make him/her aware - * to use a function in the required task-context. - * - * @throws Exception - */ - public static function required(string $callerName): void - { - if (empty(self::$contexts)) { - throw new Exception("'$callerName' can only be used within a task."); - } - } - - public function getConfig(): Configuration - { - return $this->host->config(); - } - - public function getHost(): Host - { - return $this->host; - } -} diff --git a/src/Task/GroupTask.php b/src/Task/GroupTask.php deleted file mode 100644 index d98a9f751..000000000 --- a/src/Task/GroupTask.php +++ /dev/null @@ -1,54 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Task; - -use function Deployer\invoke; - -class GroupTask extends Task -{ - /** - * List of tasks. - * - * @var string[] - */ - private $group; - - /** - * @param string[] $group - */ - public function __construct(string $name, array $group) - { - parent::__construct($name); - $this->group = $group; - } - - public function run(Context $context): void - { - foreach ($this->group as $item) { - invoke($item); - } - } - - /** - * List of dependent tasks names - * - * @return string[] - */ - public function getGroup(): array - { - return $this->group; - } - - public function setGroup(array $group): void - { - $this->group = $group; - } -} diff --git a/src/Task/ScriptManager.php b/src/Task/ScriptManager.php deleted file mode 100644 index 29e6ef469..000000000 --- a/src/Task/ScriptManager.php +++ /dev/null @@ -1,126 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Task; - -use Deployer\Exception\Exception; - -use function Deployer\Support\array_flatten; - -class ScriptManager -{ - /** - * @var TaskCollection - */ - private $tasks; - /** - * @var bool - */ - private $hooksEnabled = true; - /** - * @var array - */ - private $visitedTasks = []; - - public function __construct(TaskCollection $tasks) - { - $this->tasks = $tasks; - } - - /** - * Return tasks to run. - * - * @return Task[] - */ - public function getTasks(string $name, ?string $startFrom = null, array &$skipped = []): array - { - $tasks = []; - $this->visitedTasks = []; - $allTasks = $this->doGetTasks($name); - - if ($startFrom === null) { - $tasks = $allTasks; - } else { - $skip = true; - foreach ($allTasks as $task) { - if ($skip) { - if ($task->getName() === $startFrom) { - $skip = false; - } else { - $skipped[] = $task->getName(); - continue; - } - } - $tasks[] = $task; - } - if (count($tasks) === 0) { - throw new Exception('All tasks skipped via --start-from option. Nothing to run.'); - } - } - - $enabledTasks = []; - foreach ($tasks as $task) { - if ($task->isEnabled()) { - $enabledTasks[] = $task; - } - } - - return $enabledTasks; - } - - /** - * @return Task[] - */ - public function doGetTasks(string $name): array - { - if (array_key_exists($name, $this->visitedTasks)) { - if ($this->visitedTasks[$name] >= 100) { - throw new Exception("Looks like a circular dependency with \"$name\" task."); - } - $this->visitedTasks[$name]++; - } else { - $this->visitedTasks[$name] = 1; - } - - $tasks = []; - $task = $this->tasks->get($name); - if ($this->hooksEnabled) { - $tasks = array_merge(array_map([$this, 'doGetTasks'], $task->getBefore()), $tasks); - } - if ($task instanceof GroupTask) { - foreach ($task->getGroup() as $taskName) { - $subTasks = $this->doGetTasks($taskName); - foreach ($subTasks as $subTask) { - $subTask->addSelector($task->getSelector()); - if ($task->isOnce()) { - $subTask->once(); - } - $tasks[] = $subTask; - } - } - } else { - $tasks[] = $task; - } - if ($this->hooksEnabled) { - $tasks = array_merge($tasks, array_map([$this, 'doGetTasks'], $task->getAfter())); - } - return array_flatten($tasks); - } - - public function getHooksEnabled(): bool - { - return $this->hooksEnabled; - } - - public function setHooksEnabled(bool $hooksEnabled): void - { - $this->hooksEnabled = $hooksEnabled; - } -} diff --git a/src/Task/Task.php b/src/Task/Task.php deleted file mode 100644 index e651c80f8..000000000 --- a/src/Task/Task.php +++ /dev/null @@ -1,275 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Task; - -use Deployer\Selector\Selector; - -class Task -{ - /** - * @var string - */ - private $name; - /** - * @var callable|null - */ - private $callback; - /** - * @var string - */ - private $description; - /** - * @var string - */ - private $sourceLocation = ''; - /** - * @var array - */ - private $before = []; - /** - * @var array - */ - private $after = []; - /** - * @var bool - */ - private $hidden = false; - /** - * @var bool - */ - private $once = false; - /** - * @var bool - */ - private $oncePerNode = false; - /** - * @var int|null - */ - private $limit = null; - /** - * @var array|null - */ - private $selector = null; - /** - * @var bool - */ - private $verbose = false; - /** - * @var bool - */ - private $enabled = true; - - /** - * @param callable():void $callback - */ - public function __construct(string $name, ?callable $callback = null) - { - $this->name = $name; - $this->callback = $callback; - } - - /** - * @param callable():void $callback - */ - public function setCallback(callable $callback): void - { - $this->callback = $callback; - } - - public function run(Context $context): void - { - Context::push($context); - - try { - call_user_func($this->callback); // call task - } finally { - if ($context->getConfig() !== null) { - $context->getConfig()->set('working_path', null); - } - - Context::pop(); - } - } - - public function getName(): string - { - return $this->name; - } - - public function __toString(): string - { - return $this->getName(); - } - - public function getDescription(): ?string - { - return $this->description; - } - - public function desc(string $description): self - { - $this->description = $description; - return $this; - } - - public function getSourceLocation(): string - { - return $this->sourceLocation; - } - - public function setSourceLocation(string $path): void - { - $this->sourceLocation = $path; - } - - public function saveSourceLocation(): void - { - if (function_exists('debug_backtrace')) { - $trace = debug_backtrace(); - $this->sourceLocation = $trace[1]['file']; - } - } - - /** - * Mark this task to run only once on one of hosts. - */ - public function once(bool $once = true): self - { - $this->once = $once; - return $this; - } - - public function isOnce(): bool - { - return $this->once; - } - - /** - * Mark task to only run once per node. - * Node is a group of hosts with same hostname or with same node label. - */ - public function oncePerNode(bool $once = true): self - { - $this->oncePerNode = $once; - return $this; - } - - public function isOncePerNode(): bool - { - return $this->oncePerNode; - } - - /** - * Mark task as hidden and not accessible from CLI. - */ - public function hidden(bool $hidden = true): self - { - $this->hidden = $hidden; - return $this; - } - - public function isHidden(): bool - { - return $this->hidden; - } - - /** - * Make $task being run before this task. - */ - public function addBefore(string $task): self - { - array_unshift($this->before, $task); - return $this; - } - - /** - * Make $task being run after this task - */ - public function addAfter(string $task): self - { - array_push($this->after, $task); - return $this; - } - - public function getBefore(): array - { - return $this->before; - } - - public function getAfter(): array - { - return $this->after; - } - - public function getLimit(): ?int - { - return $this->limit; - } - - public function limit(?int $limit): self - { - $this->limit = $limit; - return $this; - } - - public function select(string $selector): self - { - $this->selector = Selector::parse($selector); - return $this; - } - - /** - * @return array - */ - public function getSelector(): ?array - { - return $this->selector; - } - - public function addSelector(?array $newSelector): void - { - if ($newSelector !== null) { - if ($this->selector === null) { - $this->selector = $newSelector; - } else { - $this->selector = array_merge($this->selector, $newSelector); - } - } - } - - public function isVerbose(): bool - { - return $this->verbose; - } - - public function verbose(bool $verbose = true): self - { - $this->verbose = $verbose; - return $this; - } - - public function isEnabled(): bool - { - return $this->enabled; - } - - public function disable(): self - { - $this->enabled = false; - return $this; - } - - public function enable(): self - { - $this->enabled = true; - return $this; - } -} diff --git a/src/Task/TaskCollection.php b/src/Task/TaskCollection.php deleted file mode 100644 index aefe79cef..000000000 --- a/src/Task/TaskCollection.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Task; - -use Deployer\Collection\Collection; - -/** - * @method Task get($name) - * @method Task[] getIterator() - */ -class TaskCollection extends Collection -{ - protected function throwNotFound(string $name): void - { - throw new \InvalidArgumentException("Task `$name` not found."); - } - - public function add(Task $task): void - { - $this->set($task->getName(), $task); - } -} diff --git a/src/Utility/Httpie.php b/src/Utility/Httpie.php deleted file mode 100644 index 6d487437d..000000000 --- a/src/Utility/Httpie.php +++ /dev/null @@ -1,210 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Utility; - -use Deployer\Exception\HttpieException; - -class Httpie -{ - /** - * @var string - */ - private $method = 'GET'; - /** - * @var string - */ - private $url = ''; - /** - * @var array - */ - private $headers = []; - /** - * @var string - */ - private $body = ''; - /** - * @var array - */ - private $curlopts = []; - /** - * @var bool - */ - private $nothrow = false; - - public function __construct() - { - if (!extension_loaded('curl')) { - throw new \Exception( - "Please, install curl extension.\n" . - "https://php.net/curl.installation", - ); - } - } - - public static function get(string $url): Httpie - { - $http = new self(); - $http->method = 'GET'; - $http->url = $url; - return $http; - } - - public static function post(string $url): Httpie - { - $http = new self(); - $http->method = 'POST'; - $http->url = $url; - return $http; - } - - public static function patch(string $url): Httpie - { - $http = new self(); - $http->method = 'PATCH'; - $http->url = $url; - return $http; - } - - - public static function put(string $url): Httpie - { - $http = new self(); - $http->method = 'PUT'; - $http->url = $url; - return $http; - } - - public static function delete(string $url): Httpie - { - $http = new self(); - $http->method = 'DELETE'; - $http->url = $url; - return $http; - } - - public function query(array $params): Httpie - { - $http = clone $this; - $http->url .= '?' . http_build_query($params); - return $http; - } - - public function header(string $header, string $value): Httpie - { - $http = clone $this; - $http->headers[$header] = $value; - return $http; - } - - public function body(string $body): Httpie - { - $http = clone $this; - $http->body = $body; - $http->headers = array_merge($http->headers, [ - 'Content-Type' => 'application/json', - 'Content-Length' => strlen($http->body), - ]); - return $http; - } - - public function jsonBody(array $data): Httpie - { - $http = clone $this; - $http->body = json_encode($data, JSON_PRETTY_PRINT); - $http->headers = array_merge($http->headers, [ - 'Content-Type' => 'application/json', - 'Content-Length' => strlen($http->body), - ]); - return $http; - } - - public function formBody(array $data): Httpie - { - $http = clone $this; - $http->body = http_build_query($data); - $http->headers = array_merge($this->headers, [ - 'Content-type' => 'application/x-www-form-urlencoded', - 'Content-Length' => strlen($http->body), - ]); - return $http; - } - - /** - * @param mixed $value - */ - public function setopt(int $key, $value): Httpie - { - $http = clone $this; - $http->curlopts[$key] = $value; - return $http; - } - - public function nothrow(bool $on = true): Httpie - { - $http = clone $this; - $http->nothrow = $on; - return $http; - } - - public function send(?array &$info = null): string - { - if ($this->url === '') { - throw new \RuntimeException('URL must not be empty to Httpie::send()'); - } - $ch = curl_init($this->url); - curl_setopt($ch, CURLOPT_USERAGENT, 'Deployer ' . DEPLOYER_VERSION); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->method); - $headers = []; - foreach ($this->headers as $key => $value) { - $headers[] = "$key: $value"; - } - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - curl_setopt($ch, CURLOPT_POSTFIELDS, $this->body); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_MAXREDIRS, 10); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); - curl_setopt($ch, CURLOPT_TIMEOUT, 5); - foreach ($this->curlopts as $key => $value) { - curl_setopt($ch, $key, $value); - } - $result = curl_exec($ch); - $info = curl_getinfo($ch); - if ($result === false) { - if ($this->nothrow) { - $result = ''; - } else { - $error = curl_error($ch); - $errno = curl_errno($ch); - curl_close($ch); - throw new HttpieException($error, $errno); - } - } - curl_close($ch); - return $result; - } - - /** - * @return mixed - */ - public function getJson() - { - $result = $this->send(); - $response = json_decode($result, true); - if (json_last_error() !== JSON_ERROR_NONE) { - throw new HttpieException( - 'JSON Error: ' . json_last_error_msg() . '\n' . - 'Response: ' . $result, - ); - } - return $response; - } -} diff --git a/src/Utility/Rsync.php b/src/Utility/Rsync.php deleted file mode 100644 index e24538d38..000000000 --- a/src/Utility/Rsync.php +++ /dev/null @@ -1,160 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Utility; - -use Deployer\Component\ProcessRunner\Printer; -use Deployer\Component\Ssh\Client; -use Deployer\Exception\RunException; -use Deployer\Host\Host; -use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Process\Exception\ProcessFailedException; -use Symfony\Component\Process\Process; - -use function Deployer\writeln; - -class Rsync -{ - /** - * @var Printer - */ - private $pop; - /** - * @var OutputInterface - */ - private $output; - - public function __construct(Printer $pop, OutputInterface $output) - { - $this->pop = $pop; - $this->output = $output; - } - - /** - * Start rsync process. - * - * @param string|string[] $source - * @phpstan-param array{flags?: string, options?: array, timeout?: int|null, progress_bar?: bool, display_stats?: bool} $config - * @throws RunException - */ - public function call(Host $host, $source, string $destination, array $config = []): void - { - $defaults = [ - 'timeout' => null, - 'options' => [], - 'flags' => '-azP', - 'progress_bar' => true, - 'display_stats' => false, - ]; - $config = array_merge($defaults, $config); - - $options = $config['options']; - $flags = $config['flags']; - $displayStats = $config['display_stats'] || in_array('--stats', $options, true); - - if ($displayStats && !in_array('--stats', $options, true)) { - $options[] = '--stats'; - } - - $connectionOptions = $host->connectionOptionsString(); - if ($connectionOptions !== '') { - $options = array_merge($options, ['-e', "ssh $connectionOptions"]); - } - if ($host->has("become")) { - $options = array_merge($options, ['--rsync-path', "sudo -H -u {$host->get('become')} rsync"]); - } - if (!is_array($source)) { - $source = [$source]; - } - $command = array_values(array_filter( - array_merge(['rsync', $flags], $options, $source, [$destination]), - function (string $value) { - return $value !== ''; - }, - )); - - $commandString = $command[0]; - for ($i = 1; $i < count($command); $i++) { - $commandString .= ' ' . escapeshellarg($command[$i]); - } - if ($this->output->isVerbose()) { - $this->output->writeln("[$host] $commandString"); - } - - $progressBar = null; - if ($this->output->getVerbosity() === OutputInterface::VERBOSITY_NORMAL && $config['progress_bar']) { - $progressBar = new ProgressBar($this->output); - $progressBar->setBarCharacter(''); - $progressBar->setProgressCharacter('>'); - $progressBar->setEmptyBarCharacter('-'); - } - - $fullOutput = ''; - - $callback = function ($type, $buffer) use ($host, $progressBar, &$fullOutput) { - $fullOutput .= $buffer; - if ($progressBar) { - foreach (explode("\n", $buffer) as $line) { - if (preg_match('/(to-chk|to-check)=(\d+?)\/(\d+)/', $line, $match)) { - $max = intval($match[3]); - $step = $max - intval($match[2]); - $progressBar->setMaxSteps($max); - $progressBar->setFormat("[$host] %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%"); - $progressBar->setProgress($step); - } - } - return; - } - if ($this->output->isVerbose()) { - $this->pop->printBuffer($type, $host, $buffer); - } - }; - - $process = new Process($command); - $process->setTimeout($config['timeout']); - try { - $process->mustRun($callback); - - if ($displayStats) { - $stats = []; - - $statsStarted = false; - foreach (explode("\n", $fullOutput) as $line) { - if (strpos($line, 'Number of files') === 0) { - $statsStarted = true; - } - - if ($statsStarted) { - if (empty($line)) { - break; - } - $stats[] = $line; - } - } - - writeln("Rsync operation stats\n" . '' . implode("\n", $stats) . ''); - } - - } catch (ProcessFailedException $exception) { - throw new RunException( - $host, - $commandString, - $process->getExitCode(), - $process->getOutput(), - $process->getErrorOutput(), - ); - } finally { - if ($progressBar) { - $progressBar->clear(); - } - } - } -} diff --git a/src/functions.php b/src/functions.php deleted file mode 100644 index d432e93ef..000000000 --- a/src/functions.php +++ /dev/null @@ -1,982 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Deployer\Exception\Exception; -use Deployer\Exception\GracefulShutdownException; -use Deployer\Exception\RunException; -use Deployer\Exception\TimeoutException; -use Deployer\Exception\WillAskUser; -use Deployer\Host\Host; -use Deployer\Host\Localhost; -use Deployer\Host\Range; -use Deployer\Importer\Importer; -use Deployer\Support\ObjectProxy; -use Deployer\Task\Context; -use Deployer\Task\GroupTask; -use Deployer\Task\Task; -use Deployer\Utility\Httpie; -use Symfony\Component\Console\Helper\QuestionHelper; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Question\ChoiceQuestion; -use Symfony\Component\Console\Question\ConfirmationQuestion; -use Symfony\Component\Console\Question\Question; - -use function Deployer\Support\array_merge_alternate; -use function Deployer\Support\env_stringify; -use function Deployer\Support\escape_shell_argument; -use function Deployer\Support\is_closure; -use function Deployer\Support\str_contains; - -/** - * Defines a host or hosts. - * ```php - * host('example.org'); - * host('prod.example.org', 'staging.example.org'); - * ``` - * - * Inside task can be used to get `Host` instance of an alias. - * ```php - * task('test', function () { - * $port = host('example.org')->get('port'); - * }); - * ``` - * - * @return Host|ObjectProxy - */ -function host(string ...$hostname) -{ - $deployer = Deployer::get(); - if (count($hostname) === 1 && $deployer->hosts->has($hostname[0])) { - return $deployer->hosts->get($hostname[0]); - } - $aliases = Range::expand($hostname); - - foreach ($aliases as $alias) { - if ($deployer->hosts->has($alias)) { - $host = $deployer->hosts->get($alias); - throw new \InvalidArgumentException("Host \"$host\" already exists."); - } - } - - if (count($aliases) === 1) { - $host = new Host($aliases[0]); - $deployer->hosts->set($aliases[0], $host); - return $host; - } else { - $hosts = array_map(function ($hostname) use ($deployer): Host { - $host = new Host($hostname); - $deployer->hosts->set($hostname, $host); - return $host; - }, $aliases); - return new ObjectProxy($hosts); - } -} - -/** - * @return Localhost|ObjectProxy - */ -function localhost(string ...$hostnames) -{ - $deployer = Deployer::get(); - $hostnames = Range::expand($hostnames); - - if (count($hostnames) <= 1) { - $host = count($hostnames) === 1 ? new Localhost($hostnames[0]) : new Localhost(); - $deployer->hosts->set($host->getAlias(), $host); - return $host; - } else { - $hosts = array_map(function ($hostname) use ($deployer): Localhost { - $host = new Localhost($hostname); - $deployer->hosts->set($host->getAlias(), $host); - return $host; - }, $hostnames); - return new ObjectProxy($hosts); - } -} - -/** - * Returns current host. - */ -function currentHost(): Host -{ - return Context::get()->getHost(); -} - -/** - * Returns hosts based on provided selector. - * - * ```php - * on(select('stage=prod, role=db'), function (Host $host) { - * ... - * }); - * ``` - * - * @return Host[] - */ -function select(string $selector): array -{ - return Deployer::get()->selector->select($selector); -} - -/** - * Returns array of hosts selected by user via CLI. - * - * @return Host[] - */ -function selectedHosts(): array -{ - $hosts = []; - foreach (get('selected_hosts', []) as $alias) { - $hosts[] = Deployer::get()->hosts->get($alias); - } - return $hosts; -} - -/** - * Import other php or yaml recipes. - * - * ```php - * import('recipe/common.php'); - * ``` - * - * ```php - * import(__DIR__ . '/config/hosts.yaml'); - * ``` - * - * @throws Exception - */ -function import(string $file): void -{ - Importer::import($file); -} - -/** - * Set task description. - */ -function desc(?string $title = null): ?string -{ - static $store = null; - - if ($title === null) { - return $store; - } else { - return $store = $title; - } -} - -/** - * Define a new task and save to tasks list. - * - * Alternatively get a defined task. - * - * @param string $name Name of current task. - * @param callable():void|array|null $body Callable task, array of other tasks names or nothing to get a defined tasks - */ -function task(string $name, $body = null): Task -{ - $deployer = Deployer::get(); - - if (empty($body)) { - return $deployer->tasks->get($name); - } - - if (is_callable($body)) { - $task = new Task($name, $body); - } elseif (is_array($body)) { - $task = new GroupTask($name, $body); - } else { - throw new \InvalidArgumentException('Task body should be a function or an array.'); - } - - if ($deployer->tasks->has($name)) { - // If task already exists, try to replace. - $existingTask = $deployer->tasks->get($name); - if (get_class($existingTask) !== get_class($task)) { - // There is no "up" or "down"casting in PHP. - throw new \Exception('Tried to replace Task \'' . $name . '\' with a GroupTask or vice-versa. This is not supported. If you are sure you want to do that, remove the old task `Deployer::get()->tasks->remove()` and then re-add the task.'); - } - if ($existingTask instanceof GroupTask) { - $existingTask->setGroup($body); - } elseif ($existingTask instanceof Task) { - $existingTask->setCallback($body); - } - $task = $existingTask; - } else { - // If task does not exist, add it to the Collection. - $deployer->tasks->set($name, $task); - } - - $task->saveSourceLocation(); - - if (!empty(desc())) { - $task->desc(desc()); - desc(''); // Clear title. - } - - return $task; -} - -/** - * Call that task before specified task runs. - * - * @param string $task The task before $that should be run. - * @param string|callable():void $do The task to be run. - * - * @return Task|null - */ -function before(string $task, $do) -{ - if (is_closure($do)) { - $newTask = task("before:$task", $do); - before($task, "before:$task"); - return $newTask; - } - task($task)->addBefore($do); - - return null; -} - -/** - * Call that task after specified task runs. - * - * @param string $task The task after $that should be run. - * @param string|callable():void $do The task to be run. - * - * @return Task|null - */ -function after(string $task, $do) -{ - if (is_closure($do)) { - $newTask = task("after:$task", $do); - after($task, "after:$task"); - return $newTask; - } - task($task)->addAfter($do); - - return null; -} - -/** - * Setup which task run on failure of $task. - * When called multiple times for a task, previous fail() definitions will be overridden. - * - * @param string $task The task which need to fail so $that should be run. - * @param string|callable():void $do The task to be run. - * - * @return Task|null - */ -function fail(string $task, $do) -{ - if (is_callable($do)) { - $newTask = task("fail:$task", $do); - fail($task, "fail:$task"); - return $newTask; - } - $deployer = Deployer::get(); - $deployer->fail->set($task, $do); - - return null; -} - -/** - * Add users options. - * - * @param string $name The option name - * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts - * @param int|null $mode The option mode: One of the VALUE_* constants - * @param string $description A description text - * @param string|string[]|int|bool|null $default The default value (must be null for self::VALUE_NONE) - */ -function option(string $name, $shortcut = null, ?int $mode = null, string $description = '', $default = null): void -{ - Deployer::get()->inputDefinition->addOption( - new InputOption($name, $shortcut, $mode, $description, $default), - ); -} - -/** - * Change the current working directory. - */ -function cd(string $path): void -{ - set('working_path', parse($path)); -} - -/** - * Change the current user. - * - * Usage: - * ```php - * $restore = become('deployer'); - * - * // do something - * - * $restore(); // revert back to the previous user - * ``` - * - * @param string $user - * @return \Closure - * @throws Exception - */ -function become(string $user): \Closure -{ - $currentBecome = get('become'); - set('become', $user); - return function () use ($currentBecome) { - set('become', $currentBecome); - }; -} - -/** - * Execute a callback within a specific directory and revert back to the initial working directory. - * - * @return mixed|null Return value of the $callback function or null if callback doesn't return anything - * @throws Exception - */ -function within(string $path, callable $callback) -{ - $lastWorkingPath = get('working_path', ''); - try { - set('working_path', parse($path)); - return $callback(); - } finally { - set('working_path', $lastWorkingPath); - } -} - -/** - * Executes given command on remote host. - * - * Examples: - * - * ```php - * run('echo hello world'); - * run('cd {{deploy_path}} && git status'); - * run('password %secret%', secret: getenv('CI_SECRET')); - * run('curl medv.io', timeout: 5); - * ``` - * - * ```php - * $path = run('readlink {{deploy_path}}/current'); - * run("echo $path"); - * ``` - * - * @param string $command Command to run on remote host. - * @param array|null $options Array of options will override passed named arguments. - * @param int|null $timeout Sets the process timeout (max. runtime). The timeout in seconds (default: 300 sec; see {{default_timeout}}, `null` to disable). - * @param int|null $idle_timeout Sets the process idle timeout (max. time since last output) in seconds. - * @param string|null $secret Placeholder `%secret%` can be used in command. Placeholder will be replaced with this value and will not appear in any logs. - * @param array|null $env Array of environment variables: `run('echo $KEY', env: ['key' => 'value']);` - * @param bool|null $real_time_output Print command output in real-time. - * @param bool|null $no_throw Don't throw an exception of non-zero exit code. - * - * @throws Exception|RunException|TimeoutException - */ -function run(string $command, ?array $options = [], ?int $timeout = null, ?int $idle_timeout = null, ?string $secret = null, ?array $env = null, ?bool $real_time_output = false, ?bool $no_throw = false): string -{ - $namedArguments = []; - foreach (['timeout', 'idle_timeout', 'secret', 'env', 'real_time_output', 'no_throw'] as $arg) { - if ($$arg !== null) { - $namedArguments[$arg] = $$arg; - } - } - $options = array_merge($namedArguments, $options); - $run = function ($command, $options = []): string { - $host = currentHost(); - - $command = parse($command); - $workingPath = get('working_path', ''); - - if (!empty($workingPath)) { - $command = "cd $workingPath && ($command)"; - } - - $env = array_merge_alternate(get('env', []), $options['env'] ?? []); - if (!empty($env)) { - $env = env_stringify($env); - $command = "export $env; $command"; - } - - $dotenv = get('dotenv', false); - if (!empty($dotenv)) { - $command = ". $dotenv; $command"; - } - - if ($host instanceof Localhost) { - $process = Deployer::get()->processRunner; - $output = $process->run($host, $command, $options); - } else { - $client = Deployer::get()->sshClient; - $output = $client->run($host, $command, $options); - } - - return rtrim($output); - }; - - if (preg_match('/^sudo\b/', $command)) { - try { - return $run($command, $options); - } catch (RunException $exception) { - $askpass = get('sudo_askpass', '/tmp/dep_sudo_pass'); - $password = get('sudo_pass', false); - if ($password === false) { - writeln("run $command"); - $password = askHiddenResponse(" [sudo] password for {{remote_user}}: "); - } - $run("echo -e '#!/bin/sh\necho \"\$PASSWORD\"' > $askpass"); - $run("chmod a+x $askpass"); - $command = preg_replace('/^sudo\b/', 'sudo -A', $command); - $output = $run(" SUDO_ASKPASS=$askpass PASSWORD=%sudo_pass% $command", array_merge($options, ['sudo_pass' => escapeshellarg($password)])); - $run("rm $askpass"); - return $output; - } - } else { - return $run($command, $options); - } -} - - -/** - * Execute commands on a local machine. - * - * Examples: - * - * ```php - * $user = runLocally('git config user.name'); - * runLocally("echo $user"); - * ``` - * - * @param string $command Command to run on localhost. - * @param array|null $options Array of options will override passed named arguments. - * @param int|null $timeout Sets the process timeout (max. runtime). The timeout in seconds (default: 300 sec, `null` to disable). - * @param int|null $idle_timeout Sets the process idle timeout (max. time since last output) in seconds. - * @param string|null $secret Placeholder `%secret%` can be used in command. Placeholder will be replaced with this value and will not appear in any logs. - * @param array|null $env Array of environment variables: `runLocally('echo $KEY', env: ['key' => 'value']);` - * @param string|null $shell Shell to run in. Default is `bash -s`. - * - * @throws RunException - */ -function runLocally(string $command, ?array $options = [], ?int $timeout = null, ?int $idle_timeout = null, ?string $secret = null, ?array $env = null, ?string $shell = null): string -{ - $namedArguments = []; - foreach (['timeout', 'idle_timeout', 'secret', 'env', 'shell'] as $arg) { - if ($$arg !== null) { - $namedArguments[$arg] = $$arg; - } - } - $options = array_merge($namedArguments, $options); - - $process = Deployer::get()->processRunner; - $command = parse($command); - - $env = array_merge_alternate(get('env', []), $options['env'] ?? []); - if (!empty($env)) { - $env = env_stringify($env); - $command = "export $env; $command"; - } - - $output = $process->run(new Localhost(), $command, $options); - - return rtrim($output); -} - -/** - * Run test command. - * Example: - * - * ```php - * if (test('[ -d {{release_path}} ]')) { - * ... - * } - * ``` - * - */ -function test(string $command): bool -{ - $true = '+' . array_rand(array_flip(['accurate', 'appropriate', 'correct', 'legitimate', 'precise', 'right', 'true', 'yes', 'indeed'])); - return trim(run("if $command; then echo $true; fi")) === $true; -} - -/** - * Run test command locally. - * Example: - * - * testLocally('[ -d {{local_release_path}} ]') - * - */ -function testLocally(string $command): bool -{ - return runLocally("if $command; then echo +true; fi") === '+true'; -} - -/** - * Iterate other hosts, allowing to call run a func in callback. - * - * ```php - * on(select('stage=prod, role=db'), function ($host) { - * ... - * }); - * ``` - * - * ```php - * on(host('example.org'), function ($host) { - * ... - * }); - * ``` - * - * ```php - * on(Deployer::get()->hosts, function ($host) { - * ... - * }); - * ``` - * - * @param Host|Host[] $hosts - */ -function on($hosts, callable $callback): void -{ - if (!is_array($hosts) && !($hosts instanceof \Traversable)) { - $hosts = [$hosts]; - } - - foreach ($hosts as $host) { - if ($host instanceof Host) { - $host->config()->load(); - Context::push(new Context($host)); - try { - $callback($host); - $host->config()->save(); - } catch (GracefulShutdownException $e) { - Deployer::get()->messenger->renderException($e, $host); - } finally { - Context::pop(); - } - } else { - throw new \InvalidArgumentException("Function on can iterate only on Host instances."); - } - } -} - -/** - * Runs a task. - * ```php - * invoke('deploy:symlink'); - * ``` - * - * @throws Exception - */ -function invoke(string $taskName): void -{ - $task = Deployer::get()->tasks->get($taskName); - Deployer::get()->messenger->startTask($task); - $task->run(Context::get()); - Deployer::get()->messenger->endTask($task); -} - -/** - * Upload files or directories to host. - * - * > To upload the _contents_ of a directory, include a trailing slash (eg `upload('build/', '{{release_path}}/public');`). - * > Without the trailing slash, the build directory itself will be uploaded (resulting in `{{release_path}}/public/build`). - * - * The `$config` array supports the following keys: - * - * - `flags` for overriding the default `-azP` passed to the `rsync` command - * - `options` with additional flags passed directly to the `rsync` command - * - `timeout` for `Process::fromShellCommandline()` (`null` by default) - * - `progress_bar` to display upload/download progress - * - `display_stats` to display rsync set of statistics - * - * Note: due to the way php escapes command line arguments, list-notation for the rsync `--exclude={'file','anotherfile'}` option will not work. - * A workaround is to add a separate `--exclude=file` argument for each exclude to `options` (also, _do not_ wrap the filename/filter in quotes). - * An alternative might be to write the excludes to a temporary file (one per line) and use `--exclude-from=temporary_file` argument instead. - * - * @param string|string[] $source - * @param array $config - * @phpstan-param array{flags?: string, options?: array, timeout?: int|null, progress_bar?: bool, display_stats?: bool} $config - * - * @throws RunException - */ -function upload($source, string $destination, array $config = []): void -{ - $rsync = Deployer::get()->rsync; - $host = currentHost(); - $source = is_array($source) ? array_map('Deployer\parse', $source) : parse($source); - $destination = parse($destination); - - if ($host instanceof Localhost) { - $rsync->call($host, $source, $destination, $config); - } else { - $rsync->call($host, $source, "{$host->connectionString()}:$destination", $config); - } -} - -/** - * Download file or directory from host - * - * @param array $config - * - * @throws RunException - */ -function download(string $source, string $destination, array $config = []): void -{ - $rsync = Deployer::get()->rsync; - $host = currentHost(); - $source = parse($source); - $destination = parse($destination); - - if ($host instanceof Localhost) { - $rsync->call($host, $source, $destination, $config); - } else { - $rsync->call($host, "{$host->connectionString()}:$source", $destination, $config); - } -} - -/** - * Writes an info message. - */ -function info(string $message): void -{ - writeln("info " . parse($message)); -} - -/** - * Writes an warning message. - */ -function warning(string $message): void -{ - $message = "warning $message"; - - if (Context::has()) { - writeln($message); - } else { - Deployer::get()->output->writeln($message); - } -} - -/** - * Writes a message to the output and adds a newline at the end. - */ -function writeln(string $message, int $options = 0): void -{ - $host = currentHost(); - output()->writeln("[$host] " . parse($message), $options); -} - -/** - * Parse set values. - */ -function parse(string $value): string -{ - return Context::get()->getConfig()->parse($value); -} - -/** - * Setup configuration option. - * @param mixed $value - * @throws Exception - */ -function set(string $name, $value): void -{ - if (!Context::has()) { - Deployer::get()->config->set($name, $value); - } else { - Context::get()->getConfig()->set($name, $value); - } -} - -/** - * Merge new config params to existing config array. - * - * @param array $array - */ -function add(string $name, array $array): void -{ - if (!Context::has()) { - Deployer::get()->config->add($name, $array); - } else { - Context::get()->getConfig()->add($name, $array); - } -} - -/** - * Get configuration value. - * - * @param mixed|null $default - * - * @return mixed - */ -function get(string $name, $default = null) -{ - if (!Context::has()) { - return Deployer::get()->config->get($name, $default); - } else { - return Context::get()->getConfig()->get($name, $default); - } -} - -/** - * Check if there is such configuration option. - */ -function has(string $name): bool -{ - if (!Context::has()) { - return Deployer::get()->config->has($name); - } else { - return Context::get()->getConfig()->has($name); - } -} - -function ask(string $message, ?string $default = null, ?array $autocomplete = null): ?string -{ - if (defined('DEPLOYER_NO_ASK')) { - throw new WillAskUser($message); - } - Context::required(__FUNCTION__); - - if (output()->isQuiet()) { - return $default; - } - - if (Deployer::isWorker()) { - return Deployer::proxyCallToMaster(currentHost(), __FUNCTION__, ...func_get_args()); - } - - /** @var QuestionHelper */ - $helper = Deployer::get()->getHelper('question'); - - $tag = currentHost()->getTag(); - $message = parse($message); - $message = "[$tag] $message " . (($default === null) ? "" : "(default: $default) "); - - $question = new Question($message, $default); - if (!empty($autocomplete)) { - $question->setAutocompleterValues($autocomplete); - } - - return $helper->ask(input(), output(), $question); -} - -/** - * @param mixed $default - * @return mixed - * @throws Exception - */ -function askChoice(string $message, array $availableChoices, $default = null, bool $multiselect = false) -{ - if (defined('DEPLOYER_NO_ASK')) { - throw new WillAskUser($message); - } - Context::required(__FUNCTION__); - - if (empty($availableChoices)) { - throw new \InvalidArgumentException('Available choices should not be empty'); - } - - if ($default !== null && !array_key_exists($default, $availableChoices)) { - throw new \InvalidArgumentException('Default choice is not available'); - } - - if (output()->isQuiet()) { - if ($default === null) { - $default = key($availableChoices); - } - return [$default => $availableChoices[$default]]; - } - - if (Deployer::isWorker()) { - return Deployer::proxyCallToMaster(currentHost(), __FUNCTION__, ...func_get_args()); - } - - /** @var QuestionHelper */ - $helper = Deployer::get()->getHelper('question'); - - $tag = currentHost()->getTag(); - $message = parse($message); - $message = "[$tag] $message " . (($default === null) ? "" : "(default: $default) "); - - $question = new ChoiceQuestion($message, $availableChoices, $default); - $question->setMultiselect($multiselect); - - return $helper->ask(input(), output(), $question); -} - -function askConfirmation(string $message, bool $default = false): bool -{ - if (defined('DEPLOYER_NO_ASK')) { - throw new WillAskUser($message); - } - Context::required(__FUNCTION__); - - if (output()->isQuiet()) { - return $default; - } - - if (Deployer::isWorker()) { - return Deployer::proxyCallToMaster(currentHost(), __FUNCTION__, ...func_get_args()); - } - - /** @var QuestionHelper */ - $helper = Deployer::get()->getHelper('question'); - - $yesOrNo = $default ? 'Y/n' : 'y/N'; - $tag = currentHost()->getTag(); - $message = parse($message); - $message = "[$tag] $message [$yesOrNo] "; - - $question = new ConfirmationQuestion($message, $default); - - return $helper->ask(input(), output(), $question); -} - -function askHiddenResponse(string $message): string -{ - if (defined('DEPLOYER_NO_ASK')) { - throw new WillAskUser($message); - } - Context::required(__FUNCTION__); - - if (output()->isQuiet()) { - return ''; - } - - if (Deployer::isWorker()) { - return (string) Deployer::proxyCallToMaster(currentHost(), __FUNCTION__, ...func_get_args()); - } - - /** @var QuestionHelper */ - $helper = Deployer::get()->getHelper('question'); - - $tag = currentHost()->getTag(); - $message = parse($message); - $message = "[$tag] $message "; - - $question = new Question($message); - $question->setHidden(true); - $question->setHiddenFallback(false); - - return (string) $helper->ask(input(), output(), $question); -} - -function input(): InputInterface -{ - return Deployer::get()->input; -} - -function output(): OutputInterface -{ - return Deployer::get()->output; -} - -/** - * Check if command exists - * - * @throws RunException - */ -function commandExist(string $command): bool -{ - return test("hash $command 2>/dev/null"); -} - -/** - * @throws RunException - */ -function commandSupportsOption(string $command, string $option): bool -{ - $man = run("(man $command 2>&1 || $command -h 2>&1 || $command --help 2>&1) | grep -- $option || true"); - if (empty($man)) { - return false; - } - return str_contains($man, $option); -} - -/** - * @throws RunException - */ -function which(string $name): string -{ - $nameEscaped = escapeshellarg($name); - - // Try `command`, should cover all Bourne-like shells - // Try `which`, should cover most other cases - // Fallback to `type` command, if the rest fails - $path = run("command -v $nameEscaped || which $nameEscaped || type -p $nameEscaped"); - if (empty($path)) { - throw new \RuntimeException("Can't locate [$nameEscaped] - neither of [command|which|type] commands are available"); - } - - // Deal with issue when `type -p` outputs something like `type -ap` in some implementations - return trim(str_replace("$name is", "", $path)); - -} - -/** - * Returns remote environments variables as an array. - * ```php - * $remotePath = remoteEnv()['PATH']; - * run('echo $PATH', env: ['PATH' => "/home/user/bin:$remotePath"]); - * ``` - */ -function remoteEnv(): array -{ - $vars = []; - $data = run('env'); - foreach (explode("\n", $data) as $line) { - [$name, $value] = explode('=', $line, 2); - $vars[$name] = $value; - } - return $vars; -} - -/** - * Creates a new exception. - */ -function error(string $message): Exception -{ - return new Exception(parse($message)); -} - -/** - * Returns current timestamp in UTC timezone in ISO8601 format. - */ -function timestamp(): string -{ - return (new \DateTime('now', new \DateTimeZone('UTC')))->format(\DateTime::ISO8601); -} - -/** - * Example usage: - * ```php - * $result = fetch('{{domain}}', info: $info); - * var_dump($info['http_code'], $result); - * ``` - */ -function fetch(string $url, string $method = 'get', array $headers = [], ?string $body = null, ?array &$info = null, bool $nothrow = false): string -{ - $url = parse($url); - if (strtolower($method) === 'get') { - $http = Httpie::get($url); - } elseif (strtolower($method) === 'post') { - $http = Httpie::post($url); - } else { - throw new \InvalidArgumentException("Unknown method \"$method\"."); - } - $http = $http->nothrow($nothrow); - foreach ($headers as $key => $value) { - $http = $http->header($key, $value); - } - if ($body !== null) { - $http = $http->body($body); - } - return $http->send($info); -} diff --git a/src/schema.json b/src/schema.json deleted file mode 100644 index 4f656fcbb..000000000 --- a/src/schema.json +++ /dev/null @@ -1,140 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://deployer.org/schema.json#", - "type": "object", - "additionalProperties": false, - "properties": { - "version": { - "type": "string" - }, - "import": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "config": { - "type": "object" - }, - "hosts": { - "type": "object", - "patternProperties": { - "^": { - "oneOf": [ - { - "type": "object", - "properties": { - "local": { - "type": "boolean" - } - } - }, - { - "type": "null" - } - ] - } - } - }, - "tasks": { - "type": "object", - "patternProperties": { - "^": { - "oneOf": [ - { - "type": "array", - "items": { - "type": "object", - "properties": { - "cd": { - "type": "string" - }, - "run": { - "type": "string" - }, - "run_locally": { - "type": "string" - }, - "upload": { - "type": "object", - "required": [ - "src", - "dest" - ], - "properties": { - "src": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "dest": { - "type": "string" - } - } - }, - "download": { - "type": "object", - "required": [ - "src", - "dest" - ], - "properties": { - "src": { - "type": "string" - }, - "dest": { - "type": "string" - } - } - }, - "desc": { - "type": "string" - }, - "once": { - "type": "boolean" - }, - "hidden": { - "type": "boolean" - }, - "limit": { - "type": "number" - }, - "select": { - "type": "string" - } - } - } - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - } - } - }, - "before": { - "type": "object" - }, - "after": { - "type": "object" - } - } -} diff --git a/tests/bootstrap.php b/tests/bootstrap.php deleted file mode 100644 index b5191cef6..000000000 --- a/tests/bootstrap.php +++ /dev/null @@ -1,41 +0,0 @@ -&1`; -`cd $repository && git add .`; -`cd $repository && git config user.name 'Anton Medvedev'`; -`cd $repository && git config user.email 'anton.medv@example.com'`; -`cd $repository && git commit -m 'first commit'`; diff --git a/tests/fixtures/project/uploaded.html b/tests/fixtures/project/uploaded.html deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/fixtures/repository/.env b/tests/fixtures/repository/.env deleted file mode 100644 index ead49fb51..000000000 --- a/tests/fixtures/repository/.env +++ /dev/null @@ -1 +0,0 @@ -ENV=prod diff --git a/tests/fixtures/repository/README.md b/tests/fixtures/repository/README.md deleted file mode 100644 index 32d99c612..000000000 --- a/tests/fixtures/repository/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Example repository - - diff --git a/tests/fixtures/repository/composer.json b/tests/fixtures/repository/composer.json deleted file mode 100644 index 4d13e3c6e..000000000 --- a/tests/fixtures/repository/composer.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "ಠ_ಠ", - "require": { - "php": "^7.3" - } -} diff --git a/tests/fixtures/repository/uploads/poem.txt b/tests/fixtures/repository/uploads/poem.txt deleted file mode 100644 index e5c64ea00..000000000 --- a/tests/fixtures/repository/uploads/poem.txt +++ /dev/null @@ -1,12 +0,0 @@ -Night, street, lamp, drugstore, -A dull and meaningless light. -Go on and live another quarter century - -Nothing will change. There's no way out. - -You'll die, then start from the beginning, -It will repeat, just like before: -Night, icy ripples on a canal, -Drugstore, street, lamp. - - A. A. Blok - 10 October 1912 diff --git a/tests/joy/HostDefaultConfigTest.php b/tests/joy/HostDefaultConfigTest.php deleted file mode 100644 index 302b1522f..000000000 --- a/tests/joy/HostDefaultConfigTest.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace joy; - -class HostDefaultConfigTest extends JoyTest -{ - protected function recipe(): string - { - return <<<'PHP' - getPort(); - writeln(empty($port) ? 'empty' : "port:$port"); - }); - PHP; - } - - public function testOnFunc() - { - $this->dep('test'); - $display = $this->tester->getDisplay(); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertStringContainsString('empty', $display); - } -} diff --git a/tests/joy/JoyTest.php b/tests/joy/JoyTest.php deleted file mode 100644 index d9ef5d0c3..000000000 --- a/tests/joy/JoyTest.php +++ /dev/null @@ -1,77 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace joy; - -use Deployer\Deployer; -use PHPUnit\Framework\TestCase; -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Tester\ApplicationTester; - -use const __TEMP_DIR__; - -abstract class JoyTest extends TestCase -{ - /** - * @var ApplicationTester - */ - protected $tester; - - /** - * @var Deployer - */ - protected $deployer; - - public static function setUpBeforeClass(): void - { - self::cleanUp(); - mkdir(__TEMP_DIR__); - } - - public static function tearDownAfterClass(): void - { - self::cleanUp(); - } - - protected static function cleanUp() - { - if (is_dir(__TEMP_DIR__)) { - exec('rm -rf ' . __TEMP_DIR__); - } - } - - protected function init(string $recipe) - { - $console = new Application(); - $console->setAutoExit(false); - $this->tester = new ApplicationTester($console); - - $this->deployer = new Deployer($console); - $this->deployer->importer->import($recipe); - $this->deployer->init(); - $this->deployer->config->set('deploy_path', __TEMP_DIR__ . '/{{hostname}}'); - } - - protected function dep(string $task, array $args = []): int - { - $recipe = __TEMP_DIR__ . '/' . get_called_class() . '.php'; - file_put_contents($recipe, $this->recipe()); - $this->init($recipe); - return $this->tester->run(array_merge([ - $task, - 'selector' => 'all', - '--file' => $recipe, - '--limit' => 1, - ], $args), [ - 'verbosity' => OutputInterface::VERBOSITY_VERBOSE, - 'interactive' => false, - ]); - } - - abstract protected function recipe(): string; -} diff --git a/tests/joy/OnFuncTest.php b/tests/joy/OnFuncTest.php deleted file mode 100644 index 1fc6142e3..000000000 --- a/tests/joy/OnFuncTest.php +++ /dev/null @@ -1,49 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace joy; - -class OnFuncTest extends JoyTest -{ - protected function recipe(): string - { - return <<<'PHP' - once(); - PHP; - } - - public function testOnFunc() - { - putenv('DEPLOYER_LOCAL_WORKER=false'); - $this->dep('test'); - putenv('DEPLOYER_LOCAL_WORKER=true'); - - $display = $this->tester->getDisplay(); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertStringContainsString('[prod] foo = prod', $display); - self::assertStringContainsString('[beta] foo = beta', $display); - } -} diff --git a/tests/legacy/AbstractTest.php b/tests/legacy/AbstractTest.php deleted file mode 100644 index 803b93108..000000000 --- a/tests/legacy/AbstractTest.php +++ /dev/null @@ -1,73 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Output\Output; -use Symfony\Component\Console\Tester\ApplicationTester; - -/** - * @deprecated Use JoyTest instead. - */ -abstract class AbstractTest extends TestCase -{ - /** - * @var ApplicationTester - */ - protected $tester; - - /** - * @var Deployer - */ - protected $deployer; - - public static function setUpBeforeClass(): void - { - self::cleanUp(); - mkdir(__TEMP_DIR__); - } - - public static function tearDownAfterClass(): void - { - self::cleanUp(); - } - - protected static function cleanUp() - { - if (is_dir(__TEMP_DIR__)) { - exec('rm -rf ' . __TEMP_DIR__); - } - } - - protected function init(string $recipe) - { - $console = new Application(); - $console->setAutoExit(false); - $this->tester = new ApplicationTester($console); - - $this->deployer = new Deployer($console); - $this->deployer->importer->import($recipe); - $this->deployer->init(); - $this->deployer->config->set('deploy_path', __TEMP_DIR__ . '/{{hostname}}'); - } - - protected function dep(string $recipe, string $task) - { - $this->init($recipe); - $this->tester->run([ - $task, - 'selector' => 'all', - '-f' => $recipe, - '-l' => 1, - ], [ - 'verbosity' => Output::VERBOSITY_VERBOSE, - 'interactive' => false, - ]); - } -} diff --git a/tests/legacy/CurrentPathTest.php b/tests/legacy/CurrentPathTest.php deleted file mode 100644 index 55259c08e..000000000 --- a/tests/legacy/CurrentPathTest.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Symfony\Component\Console\Output\Output; - -class CurrentPathTest extends AbstractTest -{ - public const RECIPE = __DIR__ . '/recipe/deploy.php'; - - public function testDeployWithDifferentCurrentPath() - { - $currentPath = __TEMP_DIR__ . '/prod/public_html'; - - $this->init(self::RECIPE); - $this->tester->run([ - 'deploy', - 'selector' => 'prod', - '-f' => self::RECIPE, - '-o' => ['current_path=' . $currentPath], - ], [ - 'verbosity' => Output::VERBOSITY_VERBOSE, - ]); - - $display = $this->tester->getDisplay(); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertFileExists($currentPath . '/README.md'); - self::assertFileExists($currentPath . '/config/test.yaml'); - } -} diff --git a/tests/legacy/DeployTest.php b/tests/legacy/DeployTest.php deleted file mode 100644 index 33bed7e5d..000000000 --- a/tests/legacy/DeployTest.php +++ /dev/null @@ -1,144 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Symfony\Component\Console\Output\Output; - -class DeployTest extends AbstractTest -{ - public const RECIPE = __DIR__ . '/recipe/deploy.php'; - - public function testDeploy() - { - $display = $this->dep(self::RECIPE, 'deploy'); - - $display = $this->tester->getDisplay(); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - - foreach ($this->deployer->hosts as $host) { - $deployPath = $host->get('deploy_path'); - - self::assertDirectoryExists($deployPath . '/.dep'); - self::assertDirectoryExists($deployPath . '/releases'); - self::assertDirectoryExists($deployPath . '/shared'); - self::assertDirectoryExists($deployPath . '/current'); - self::assertDirectoryExists($deployPath . '/current/'); - self::assertFileExists($deployPath . '/current/README.md'); - self::assertDirectoryExists($deployPath . '/current/storage/logs'); - self::assertDirectoryExists($deployPath . '/current/storage/db'); - self::assertDirectoryExists($deployPath . '/shared/storage/logs'); - self::assertDirectoryExists($deployPath . '/shared/storage/db'); - self::assertFileExists($deployPath . '/shared/uploads/poem.txt'); - self::assertFileExists($deployPath . '/shared/.env'); - self::assertFileExists($deployPath . '/current/config/test.yaml'); - self::assertFileExists($deployPath . '/shared/config/test.yaml'); - self::assertEquals(1, intval(exec("cd $deployPath && ls -1 releases | wc -l"))); - } - } - - public function testDeploySelectHosts() - { - $this->init(self::RECIPE); - $this->tester->setInputs(['0,1']); - $this->tester->run(['deploy', '-f' => self::RECIPE, '-l' => 1], [ - 'verbosity' => Output::VERBOSITY_NORMAL, - 'interactive' => true, - ]); - self::assertEquals(0, $this->tester->getStatusCode(), $this->tester->getDisplay()); - } - - public function testKeepReleases() - { - for ($i = 0; $i < 3; $i++) { - $this->dep(self::RECIPE, 'deploy'); - self::assertEquals(0, $this->tester->getStatusCode(), $this->tester->getDisplay()); - } - - for ($i = 0; $i < 6; $i++) { - $this->dep(self::RECIPE, 'deploy:fail'); - self::assertEquals(1, $this->tester->getStatusCode(), $this->tester->getDisplay()); - } - - for ($i = 0; $i < 3; $i++) { - $this->dep(self::RECIPE, 'deploy'); - self::assertEquals(0, $this->tester->getStatusCode(), $this->tester->getDisplay()); - } - - foreach ($this->deployer->hosts as $host) { - $deployPath = $host->get('deploy_path'); - - self::assertEquals(3, intval(exec("cd $deployPath && ls -1 releases | wc -l"))); - } - } - - /** - * @depends testKeepReleases - */ - public function testRollback() - { - $this->dep(self::RECIPE, 'rollback'); - - self::assertEquals(0, $this->tester->getStatusCode(), $this->tester->getDisplay()); - - foreach ($this->deployer->hosts as $host) { - $deployPath = $host->get('deploy_path'); - - self::assertEquals(3, intval(exec("cd $deployPath && ls -1 releases | wc -l"))); - } - } - - public function testFail() - { - $this->dep(self::RECIPE, 'deploy:fail'); - - $display = $this->tester->getDisplay(); - self::assertEquals(1, $this->tester->getStatusCode(), $display); - - foreach ($this->deployer->hosts as $host) { - $deployPath = $host->get('deploy_path'); - - self::assertEquals('ok', exec("cd $deployPath && [ -f .dep/deploy.lock ] || echo ok"), 'fail hooks deploy:unlock did not run'); - } - } - - /** - * @depends testFail - */ - public function testCleanup() - { - $this->dep(self::RECIPE, 'deploy:cleanup'); - - self::assertEquals(0, $this->tester->getStatusCode(), $this->tester->getDisplay()); - - foreach ($this->deployer->hosts as $host) { - $deployPath = $host->get('deploy_path'); - - self::assertFileDoesNotExist($deployPath . '/release'); - } - } - - public function testIsUnlockedExitsWithOneWhenDeployIsLocked() - { - $this->dep(self::RECIPE, 'deploy:lock'); - $this->dep(self::RECIPE, 'deploy:is_locked'); - $display = $this->tester->getDisplay(); - - self::assertStringContainsString('Deploy is locked by ', $display); - self::assertSame(1, $this->tester->getStatusCode()); - } - - public function testIsUnlockedExitsWithZeroWhenDeployIsNotLocked() - { - $this->dep(self::RECIPE, 'deploy:unlock'); - $this->dep(self::RECIPE, 'deploy:is_locked'); - $display = $this->tester->getDisplay(); - - self::assertStringContainsString('Deploy is unlocked.', $display); - self::assertSame(0, $this->tester->getStatusCode()); - } -} diff --git a/tests/legacy/EnvTest.php b/tests/legacy/EnvTest.php deleted file mode 100644 index 797577d6d..000000000 --- a/tests/legacy/EnvTest.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -class EnvTest extends AbstractTest -{ - public const RECIPE = __DIR__ . '/recipe/env.php'; - - public function testOnce() - { - $this->dep(self::RECIPE, 'test'); - - $display = $this->tester->getDisplay(); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertStringContainsString('global=global', $display); - self::assertStringContainsString('local=local', $display); - self::assertStringContainsString('dotenv=Hello, world!', $display); - self::assertStringContainsString('dotenv=local', $display); - } -} diff --git a/tests/legacy/NamedArgumentsTest.php b/tests/legacy/NamedArgumentsTest.php deleted file mode 100644 index 7b19a0d96..000000000 --- a/tests/legacy/NamedArgumentsTest.php +++ /dev/null @@ -1,56 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Symfony\Component\Console\Output\Output; - -// TODO: Wait until Deployer 7.1 with only php8 supports. -//class NamedArgumentsTest extends AbstractTest -//{ -// const RECIPE = __DIR__ . '/recipe/named_arguments.php'; -// -// public function testRunWithNamedArguments() -// { -// $this->init(self::RECIPE); -// $this->tester->run(['named_arguments', '-f' => self::RECIPE], ['verbosity' => Output::VERBOSITY_VERBOSE]); -// -// $display = $this->tester->getDisplay(); -// self::assertEquals(0, $this->tester->getStatusCode(), $display); -// self::assertStringContainsString('Hello, world!', $display); -// } -// -// public function testRunWithOptions() -// { -// $this->init(self::RECIPE); -// $this->tester->run(['options', '-f' => self::RECIPE], ['verbosity' => Output::VERBOSITY_VERBOSE]); -// -// $display = $this->tester->getDisplay(); -// self::assertEquals(0, $this->tester->getStatusCode(), $display); -// self::assertStringContainsString('Hello, Anton!', $display); -// } -// -// public function testRunWithOptionsWithNamedArguments() -// { -// $this->init(self::RECIPE); -// $this->tester->run(['options_with_named_arguments', '-f' => self::RECIPE], ['verbosity' => Output::VERBOSITY_VERBOSE]); -// -// $display = $this->tester->getDisplay(); -// self::assertEquals(0, $this->tester->getStatusCode(), $display); -// self::assertStringContainsString('Hello, override!', $display); -// } -// -// public function testRunLocallyWithNamedArguments() -// { -// $this->init(self::RECIPE); -// $this->tester->run(['run_locally_named_arguments', '-f' => self::RECIPE], ['verbosity' => Output::VERBOSITY_VERBOSE]); -// -// $display = $this->tester->getDisplay(); -// self::assertEquals(0, $this->tester->getStatusCode(), $display); -// self::assertStringContainsString('Hello, world!', $display); -// } -//} diff --git a/tests/legacy/OncePerNodeTest.php b/tests/legacy/OncePerNodeTest.php deleted file mode 100644 index 1e78d3393..000000000 --- a/tests/legacy/OncePerNodeTest.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -class OncePerNodeTest extends AbstractTest -{ - public const RECIPE = __DIR__ . '/recipe/once_per_node.php'; - - public function testOnce() - { - $this->dep(self::RECIPE, 'test_once_per_node'); - - $display = $this->tester->getDisplay(); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertStringContainsString('alias: group_a_1 hostname: localhost', $display); - self::assertStringNotContainsString('alias: group_a_2 hostname: localhost', $display); - self::assertStringContainsString('alias: group_b_1 hostname: group_b_1', $display); - self::assertStringNotContainsString('alias: group_b_2 hostname: group_b_2', $display); - } -} diff --git a/tests/legacy/OnceTest.php b/tests/legacy/OnceTest.php deleted file mode 100644 index f50f539ea..000000000 --- a/tests/legacy/OnceTest.php +++ /dev/null @@ -1,22 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -class OnceTest extends AbstractTest -{ - public const RECIPE = __DIR__ . '/recipe/once.php'; - - public function testOnce() - { - $this->dep(self::RECIPE, 'test_once'); - - $display = $this->tester->getDisplay(); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertTrue(substr_count($display, 'SHOULD BE ONCE') == 1, $display); - } -} diff --git a/tests/legacy/ParallelTest.php b/tests/legacy/ParallelTest.php deleted file mode 100644 index 8938ef8f8..000000000 --- a/tests/legacy/ParallelTest.php +++ /dev/null @@ -1,114 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Symfony\Component\Console\Output\Output; - -class ParallelTest extends AbstractTest -{ - public const RECIPE = __DIR__ . '/recipe/parallel.php'; - - public static function setUpBeforeClass(): void - { - parent::setUpBeforeClass(); - putenv('DEPLOYER_LOCAL_WORKER=false'); // Allow to start workers. Don't forget to disable it later. - } - - public static function tearDownAfterClass(): void - { - putenv('DEPLOYER_LOCAL_WORKER=true'); - parent::tearDownAfterClass(); - } - - public function testWorker() - { - $this->init(self::RECIPE); - $this->tester->run([ - 'echo', - '-f' => self::RECIPE, - 'selector' => 'all', - ], [ - 'verbosity' => Output::VERBOSITY_NORMAL, - ]); - self::assertEquals(0, $this->tester->getStatusCode(), $this->tester->getDisplay()); - } - - public function testServer() - { - $this->init(self::RECIPE); - $this->tester->setInputs(['prod', 'Black bear']); - $this->tester->run([ - 'ask', - '-f' => self::RECIPE, - ], [ - 'verbosity' => Output::VERBOSITY_NORMAL, - 'interactive' => true, - ]); - $display = $this->tester->getDisplay(); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertStringContainsString('[prod] Question: What kind of bear is best?', $display); - self::assertStringContainsString('[prod] Black bear', $display); - } - - public function testOption() - { - $this->init(self::RECIPE); - $this->tester->run( - [ - 'echo', - 'selector' => 'all', - '-o' => ['greet=Hello'], - '-f' => self::RECIPE, - //'-l' => 1, - ], - [ - 'verbosity' => Output::VERBOSITY_DEBUG, - 'interactive' => false, - ], - ); - - $display = $this->tester->getDisplay(); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertStringContainsString('[prod] Hello, prod!', $display); - self::assertStringContainsString('[beta] Hello, beta!', $display); - } - - public function testCachedHostConfig() - { - $this->init(self::RECIPE); - $this->tester->run([ - 'cache_config_test', - '-f' => self::RECIPE, - 'selector' => 'all', - ], [ - 'verbosity' => Output::VERBOSITY_NORMAL, - ]); - - $display = $this->tester->getDisplay(); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertTrue(substr_count($display, 'worker on prod') == 1, $display); - self::assertTrue(substr_count($display, 'worker on beta') == 1, $display); - } - - public function testHostConfigFromCallback() - { - $this->init(self::RECIPE); - $this->tester->run([ - 'host_config_from_callback', - '-f' => self::RECIPE, - 'selector' => 'all', - ], [ - 'verbosity' => Output::VERBOSITY_NORMAL, - ]); - - $display = $this->tester->getDisplay(); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertTrue(substr_count($display, '[prod] config value is from global') == 1, $display); - self::assertTrue(substr_count($display, '[beta] config value is from callback') == 1, $display); - } -} diff --git a/tests/legacy/SelectTest.php b/tests/legacy/SelectTest.php deleted file mode 100644 index f1ba9485d..000000000 --- a/tests/legacy/SelectTest.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Symfony\Component\Console\Output\Output; - -class SelectTest extends AbstractTest -{ - public const RECIPE = __DIR__ . '/recipe/select.php'; - - public function testSelect() - { - $this->init(self::RECIPE); - $this->tester->run([ - 'test', - '-f' => self::RECIPE, - 'selector' => 'prod', - ], [ - 'verbosity' => Output::VERBOSITY_DEBUG, - ]); - - $display = $this->tester->getDisplay(); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertStringNotContainsString('executing on prod', $display); - self::assertStringContainsString('executing on beta', $display); - self::assertStringContainsString('executing on dev', $display); - } -} diff --git a/tests/legacy/UpdateCodeTest.php b/tests/legacy/UpdateCodeTest.php deleted file mode 100644 index 7798c4d26..000000000 --- a/tests/legacy/UpdateCodeTest.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Symfony\Component\Console\Output\Output; - -class UpdateCodeTest extends AbstractTest -{ - public const RECIPE = __DIR__ . '/recipe/update_code.php'; - - public function testDeployWithDifferentUpdateCodeTask() - { - $this->init(self::RECIPE); - $this->tester->run([ - 'deploy', - 'selector' => 'prod', - '-f' => self::RECIPE, - ], [ - 'verbosity' => Output::VERBOSITY_VERBOSE, - ]); - - $display = $this->tester->getDisplay(); - $deployPath = $this->deployer->hosts->get('prod')->getDeployPath(); - - self::assertEquals(0, $this->tester->getStatusCode(), $display); - self::assertFileExists($deployPath . '/current/uploaded.html'); - } -} diff --git a/tests/legacy/YamlTest.php b/tests/legacy/YamlTest.php deleted file mode 100644 index d1895453a..000000000 --- a/tests/legacy/YamlTest.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Symfony\Component\Console\Output\Output; - -class YamlTest extends AbstractTest -{ - public const RECIPE = __DIR__ . '/recipe/deploy.yaml'; - - public function testDeploy() - { - $this->init(self::RECIPE); - $this->deployer->config->set('repository', __REPOSITORY__); - $this->tester->run([ - 'deploy', - 'selector' => 'all', - '-f' => self::RECIPE, - ], [ - 'verbosity' => Output::VERBOSITY_VERBOSE, - 'interactive' => false, - ]); - - $display = $this->tester->getDisplay(); - self::assertEquals(0, $this->tester->getStatusCode(), $display); - - foreach ($this->deployer->hosts as $host) { - $deployPath = $host->get('deploy_path'); - - self::assertDirectoryExists($deployPath . '/.dep'); - self::assertDirectoryExists($deployPath . '/releases'); - self::assertDirectoryExists($deployPath . '/shared'); - self::assertDirectoryExists($deployPath . '/current'); - self::assertDirectoryExists($deployPath . '/current/'); - self::assertFileExists($deployPath . '/current/README.md'); - self::assertDirectoryExists($deployPath . '/current/storage/logs'); - self::assertDirectoryExists($deployPath . '/current/storage/db'); - self::assertDirectoryExists($deployPath . '/shared/storage/logs'); - self::assertDirectoryExists($deployPath . '/shared/storage/db'); - self::assertFileExists($deployPath . '/shared/uploads/poem.txt'); - self::assertFileExists($deployPath . '/shared/.env'); - self::assertFileExists($deployPath . '/current/config/test.yaml'); - self::assertFileExists($deployPath . '/shared/config/test.yaml'); - self::assertEquals(1, intval(`cd $deployPath && ls -1 releases | wc -l`)); - } - } -} diff --git a/tests/legacy/recipe/deploy.php b/tests/legacy/recipe/deploy.php deleted file mode 100644 index 170056097..000000000 --- a/tests/legacy/recipe/deploy.php +++ /dev/null @@ -1,47 +0,0 @@ -&1'); -}); - -task('deploy:fail', [ - 'deploy:prepare', - 'fail', - 'deploy:publish', -]); - -task('fail', function () { - run('false'); -}); - -fail('deploy:fail', 'deploy:unlock'); diff --git a/tests/legacy/recipe/deploy.yaml b/tests/legacy/recipe/deploy.yaml deleted file mode 100644 index cddacf5de..000000000 --- a/tests/legacy/recipe/deploy.yaml +++ /dev/null @@ -1,27 +0,0 @@ -import: recipe/common.php - -config: - application: deployer - shared_dirs: - - uploads - - storage/logs/ - - storage/db - shared_files: - - .env - - config/test.yaml - keep_releases: 3 - http_user: false - -hosts: - prod: - local: true - -tasks: - deploy: - - deploy:prepare - - deploy:vendors - - deploy:publish - - deploy:vendors: - - cd: '{{release_path}}' - - run: echo {{bin/composer}} {{composer_options}} 2>&1 diff --git a/tests/legacy/recipe/env.php b/tests/legacy/recipe/env.php deleted file mode 100644 index 09da6f9c7..000000000 --- a/tests/legacy/recipe/env.php +++ /dev/null @@ -1,22 +0,0 @@ - 'global', -]); - -task('test', function () { - info('global=' . run('echo $VAR')); - info('local=' . run('echo $VAR', ['env' => ['VAR' => 'local']])); - info('dotenv=' . run('echo $KEY')); - info('dotenv=' . run('echo $KEY', ['env' => ['KEY' => 'local']])); -}); - -before('test', function () { - run('mkdir -p {{deploy_path}}'); - run('echo KEY="\'Hello, world!\'" > {{deploy_path}}/.env'); - set('dotenv', '{{deploy_path}}/.env'); -}); diff --git a/tests/legacy/recipe/named_arguments.php b/tests/legacy/recipe/named_arguments.php deleted file mode 100644 index 204412185..000000000 --- a/tests/legacy/recipe/named_arguments.php +++ /dev/null @@ -1,22 +0,0 @@ - 'world']); -}); - -task('options', function () { - run('echo "Hello, $name!"', ['env' => ['name' => 'Anton']]); -}); - -task('options_with_named_arguments', function () { - // The `options:` arg has higher priority than named arguments. - run('echo "Hello, $name!"', ['env' => ['name' => 'override']], env: ['name' => 'world']); -}); - -task('run_locally_named_arguments', function () { - runLocally('echo "Hello, $name!"', env: ['name' => 'world']); -}); diff --git a/tests/legacy/recipe/once.php b/tests/legacy/recipe/once.php deleted file mode 100644 index 84f8bbe24..000000000 --- a/tests/legacy/recipe/once.php +++ /dev/null @@ -1,10 +0,0 @@ -once(); diff --git a/tests/legacy/recipe/once_per_node.php b/tests/legacy/recipe/once_per_node.php deleted file mode 100644 index d41c66e19..000000000 --- a/tests/legacy/recipe/once_per_node.php +++ /dev/null @@ -1,16 +0,0 @@ -setHostname('localhost'); -localhost('group_a_2') - ->setHostname('localhost'); -localhost('group_b_1') - ->setLabels(['node' => 'anna']); -localhost('group_b_2') - ->setLabels(['node' => 'anna']); - -task('test_once_per_node', function () { - writeln('alias: {{alias}} hostname: {{hostname}}'); -})->oncePerNode(); diff --git a/tests/legacy/recipe/parallel.php b/tests/legacy/recipe/parallel.php deleted file mode 100644 index 3bb94b864..000000000 --- a/tests/legacy/recipe/parallel.php +++ /dev/null @@ -1,48 +0,0 @@ -set('host_level_callback_config', function () { - return 'from callback'; - }); - -// testServer: - -task('ask', function () { - $answer = ask('Question: What kind of bear is best?'); - writeln($answer); -}); - -// testWorker, testOption: - -set('greet', '_'); - -task('echo', function () { - $alias = currentHost()->getAlias(); - run("echo {{greet}}, $alias!"); -}); - -// testCachedHostConfig: - -set('upper_host', function () { - writeln('running ' . (Deployer::isWorker() ? 'worker' : 'master') . ' on ' . currentHost()->getAlias()); - return strtoupper(currentHost()->getAlias()); -}); - -task('cache_config_test', function () { - writeln('echo 1: {{upper_host}}'); -}); - -after('cache_config_test', function () { - writeln('echo 2: {{upper_host}}'); -}); - -// testHostConfigFromCallback: - -set('host_level_callback_config', 'from global'); - -task('host_config_from_callback', function () { - writeln('config value is {{host_level_callback_config}}'); -}); diff --git a/tests/legacy/recipe/select.php b/tests/legacy/recipe/select.php deleted file mode 100644 index 8951edbfe..000000000 --- a/tests/legacy/recipe/select.php +++ /dev/null @@ -1,13 +0,0 @@ -setLabels(['env' => 'prod']); -localhost('beta')->setLabels(['env' => 'dev']); -localhost('dev')->setLabels(['env' => 'dev']); - -task('test', function () { - on(select('env=dev'), function () { - info('executing on {{alias}}'); - }); -}); diff --git a/tests/legacy/recipe/update_code.php b/tests/legacy/recipe/update_code.php deleted file mode 100644 index 637f1e83c..000000000 --- a/tests/legacy/recipe/update_code.php +++ /dev/null @@ -1,9 +0,0 @@ -\" between 100|125|200|100000 and 0 is always true\\.$#" - count: 1 - path: ../src/Command/BlackjackCommand.php - - - - message: "#^Else branch is unreachable because previous condition is always true\\.$#" - count: 1 - path: ../src/Command/BlackjackCommand.php - - - - message: "#^If condition is always false\\.$#" - count: 1 - path: ../src/Command/BlackjackCommand.php - - - - message: "#^Comparison operation \"\\>\" between 0 and 0 is always false\\.$#" - count: 1 - path: ../src/Command/BlackjackCommand.php - - - - message: "#^Unsafe usage of new static\\(\\)\\.$#" - count: 2 - path: ../src/Component/PharUpdate/Exception/Exception.php - - - - message: "#^If condition is always true\\.$#" - count: 1 - path: ../src/Host/Host.php - - - - message: "#^Unreachable statement \\- code above always terminates\\.$#" - count: 1 - path: ../src/Importer/Importer.php diff --git a/tests/src/Collection/CollectionTest.php b/tests/src/Collection/CollectionTest.php deleted file mode 100644 index 7d7da392b..000000000 --- a/tests/src/Collection/CollectionTest.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Collection; - -use Deployer\Host\HostCollection; -use Deployer\Task\TaskCollection; -use PHPUnit\Framework\TestCase; - -class CollectionTest extends TestCase -{ - public static function collections() - { - return [ - [new Collection()], - [new TaskCollection()], - [new HostCollection()], - ]; - } - - /** - * @dataProvider collections - */ - public function testCollection($collection) - { - $this->assertInstanceOf(Collection::class, $collection); - - $object = new \stdClass(); - $collection->set('object', $object); - - $this->assertTrue($collection->has('object')); - $this->assertEquals($object, $collection->get('object')); - - $this->assertEquals(['object' => $object], $collection->select(function ($value, $key) use ($object) { - return $value === $object && $key === 'object'; - })); - } - - /** - * @dataProvider collections - * @depends testCollection - */ - public function testException($collection) - { - $this->expectException(\InvalidArgumentException::class); - $collection->get('unexpected'); - } -} diff --git a/tests/src/Command/BlackjackCommandTest.php b/tests/src/Command/BlackjackCommandTest.php deleted file mode 100644 index c4f941ed8..000000000 --- a/tests/src/Command/BlackjackCommandTest.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Component\Pimple; - -use Deployer\Component\Pimple\Exception\FrozenServiceException; -use Deployer\Component\Pimple\Exception\InvalidServiceIdentifierException; -use Deployer\Component\Pimple\Exception\UnknownIdentifierException; -use InvalidArgumentException; -use PHPUnit\Framework\TestCase; -use ReflectionProperty; -use RuntimeException; - -use function extension_loaded; - -class PimpleTest extends TestCase -{ - public function testWithString() - { - $pimple = new Container(); - $pimple['param'] = 'value'; - - $this->assertEquals('value', $pimple['param']); - } - - public function testWithClosure() - { - $pimple = new Container(); - $pimple['service'] = function () { - return new Service(); - }; - - $this->assertInstanceOf(Service::class, $pimple['service']); - } - - public function testServicesShouldBeDifferent() - { - $pimple = new Container(); - $pimple['service'] = $pimple->factory(function () { - return new Service(); - }); - - $serviceOne = $pimple['service']; - $this->assertInstanceOf(Service::class, $serviceOne); - - $serviceTwo = $pimple['service']; - $this->assertInstanceOf(Service::class, $serviceTwo); - - $this->assertNotSame($serviceOne, $serviceTwo); - } - - public function testShouldPassContainerAsParameter() - { - $pimple = new Container(); - $pimple['service'] = function () { - return new Service(); - }; - $pimple['container'] = function ($container) { - return $container; - }; - - $this->assertNotSame($pimple, $pimple['service']); - $this->assertSame($pimple, $pimple['container']); - } - - public function testIsset() - { - $pimple = new Container(); - $pimple['param'] = 'value'; - $pimple['service'] = function () { - return new Service(); - }; - - $pimple['null'] = null; - - $this->assertTrue(isset($pimple['param'])); - $this->assertTrue(isset($pimple['service'])); - $this->assertTrue(isset($pimple['null'])); - $this->assertFalse(isset($pimple['non_existent'])); - } - - public function testConstructorInjection() - { - $params = ['param' => 'value']; - $pimple = new Container($params); - - $this->assertSame($params['param'], $pimple['param']); - } - - public function testOffsetGetValidatesKeyIsPresent() - { - $this->expectException(UnknownIdentifierException::class); - $this->expectExceptionMessage('Identifier "foo" is not defined.'); - - $pimple = new Container(); - echo $pimple['foo']; - } - - /** - * @group legacy - */ - public function testLegacyOffsetGetValidatesKeyIsPresent() - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Identifier "foo" is not defined.'); - - $pimple = new Container(); - echo $pimple['foo']; - } - - public function testOffsetGetHonorsNullValues() - { - $pimple = new Container(); - $pimple['foo'] = null; - $this->assertNull($pimple['foo']); - } - - public function testUnset() - { - $pimple = new Container(); - $pimple['param'] = 'value'; - $pimple['service'] = function () { - return new Service(); - }; - - unset($pimple['param'], $pimple['service']); - $this->assertFalse(isset($pimple['param'])); - $this->assertFalse(isset($pimple['service'])); - } - - /** - * @dataProvider serviceDefinitionProvider - */ - public function testShare($service) - { - $pimple = new Container(); - $pimple['shared_service'] = $service; - - $serviceOne = $pimple['shared_service']; - $this->assertInstanceOf(Service::class, $serviceOne); - - $serviceTwo = $pimple['shared_service']; - $this->assertInstanceOf(Service::class, $serviceTwo); - - $this->assertSame($serviceOne, $serviceTwo); - } - - /** - * @dataProvider serviceDefinitionProvider - */ - public function testProtect($service) - { - $pimple = new Container(); - $pimple['protected'] = $pimple->protect($service); - - $this->assertSame($service, $pimple['protected']); - } - - public function testGlobalFunctionNameAsParameterValue() - { - $pimple = new Container(); - $pimple['global_function'] = 'strlen'; - $this->assertSame('strlen', $pimple['global_function']); - } - - public function testRaw() - { - $pimple = new Container(); - $pimple['service'] = $definition = $pimple->factory(function () { - return 'foo'; - }); - $this->assertSame($definition, $pimple->raw('service')); - } - - public function testRawHonorsNullValues() - { - $pimple = new Container(); - $pimple['foo'] = null; - $this->assertNull($pimple->raw('foo')); - } - - public function testRawValidatesKeyIsPresent() - { - $this->expectException(UnknownIdentifierException::class); - $this->expectExceptionMessage('Identifier "foo" is not defined.'); - - $pimple = new Container(); - $pimple->raw('foo'); - } - - /** - * @group legacy - */ - public function testLegacyRawValidatesKeyIsPresent() - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Identifier "foo" is not defined.'); - - $pimple = new Container(); - $pimple->raw('foo'); - } - - /** - * @dataProvider serviceDefinitionProvider - */ - public function testExtend($service) - { - $pimple = new Container(); - $pimple['shared_service'] = function () { - return new Service(); - }; - $pimple['factory_service'] = $pimple->factory(function () { - return new Service(); - }); - - $pimple->extend('shared_service', $service); - $serviceOne = $pimple['shared_service']; - $this->assertInstanceOf(Service::class, $serviceOne); - $serviceTwo = $pimple['shared_service']; - $this->assertInstanceOf(Service::class, $serviceTwo); - $this->assertSame($serviceOne, $serviceTwo); - $this->assertSame($serviceOne->value, $serviceTwo->value); - - $pimple->extend('factory_service', $service); - $serviceOne = $pimple['factory_service']; - $this->assertInstanceOf(Service::class, $serviceOne); - $serviceTwo = $pimple['factory_service']; - $this->assertInstanceOf(Service::class, $serviceTwo); - $this->assertNotSame($serviceOne, $serviceTwo); - $this->assertNotSame($serviceOne->value, $serviceTwo->value); - } - - public function testExtendDoesNotLeakWithFactories() - { - if (extension_loaded('pimple')) { - $this->markTestSkipped('Pimple extension does not support this test'); - } - $pimple = new Container(); - - $pimple['foo'] = $pimple->factory(function () { - return; - }); - $pimple['foo'] = $pimple->extend('foo', function ($foo, $pimple) { - return; - }); - unset($pimple['foo']); - - $p = new ReflectionProperty($pimple, 'values'); - $p->setAccessible(true); - $this->assertEmpty($p->getValue($pimple)); - - $p = new ReflectionProperty($pimple, 'factories'); - $p->setAccessible(true); - $this->assertCount(0, $p->getValue($pimple)); - } - - public function testExtendValidatesKeyIsPresent() - { - $this->expectException(UnknownIdentifierException::class); - $this->expectExceptionMessage('Identifier "foo" is not defined.'); - - $pimple = new Container(); - $pimple->extend('foo', function () {}); - } - - /** - * @group legacy - */ - public function testLegacyExtendValidatesKeyIsPresent() - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Identifier "foo" is not defined.'); - - $pimple = new Container(); - $pimple->extend('foo', function () {}); - } - - public function testKeys() - { - $pimple = new Container(); - $pimple['foo'] = 123; - $pimple['bar'] = 123; - - $this->assertEquals(['foo', 'bar'], $pimple->keys()); - } - - /** @test */ - public function settingAnInvokableObjectShouldTreatItAsFactory() - { - $pimple = new Container(); - $pimple['invokable'] = new Invokable(); - - $this->assertInstanceOf(Service::class, $pimple['invokable']); - } - - /** @test */ - public function settingNonInvokableObjectShouldTreatItAsParameter() - { - $pimple = new Container(); - $pimple['non_invokable'] = new NonInvokable(); - - $this->assertInstanceOf(NonInvokable::class, $pimple['non_invokable']); - } - - /** - * @dataProvider badServiceDefinitionProvider - */ - public function testFactoryFailsForInvalidServiceDefinitions($service) - { - $this->expectException(\TypeError::class); - $pimple = new Container(); - $pimple->factory($service); - } - - /** - * @group legacy - * @dataProvider badServiceDefinitionProvider - */ - public function testLegacyFactoryFailsForInvalidServiceDefinitions($service) - { - $this->expectException(\TypeError::class); - $pimple = new Container(); - $pimple->factory($service); - } - - /** - * @dataProvider badServiceDefinitionProvider - */ - public function testProtectFailsForInvalidServiceDefinitions($service) - { - $this->expectException(\TypeError::class); - $pimple = new Container(); - $pimple->protect($service); - } - - /** - * @group legacy - * @dataProvider badServiceDefinitionProvider - */ - public function testLegacyProtectFailsForInvalidServiceDefinitions($service) - { - $this->expectException(\TypeError::class); - $pimple = new Container(); - $pimple->protect($service); - } - - /** - * @dataProvider badServiceDefinitionProvider - */ - public function testExtendFailsForKeysNotContainingServiceDefinitions($service) - { - $this->expectException(InvalidServiceIdentifierException::class); - $this->expectExceptionMessage('Identifier "foo" does not contain an object definition.'); - - $pimple = new Container(); - $pimple['foo'] = $service; - $pimple->extend('foo', function () {}); - } - - /** - * @group legacy - * @dataProvider badServiceDefinitionProvider - */ - public function testLegacyExtendFailsForKeysNotContainingServiceDefinitions($service) - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Identifier "foo" does not contain an object definition.'); - - $pimple = new Container(); - $pimple['foo'] = $service; - $pimple->extend('foo', function () {}); - } - - /** - * @group legacy - * @expectedDeprecation How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure "foo" should be protected? - */ - public function testExtendingProtectedClosureDeprecation() - { - $pimple = new Container(); - $pimple['foo'] = $pimple->protect(function () { - return 'bar'; - }); - - $pimple->extend('foo', function ($value) { - return $value . '-baz'; - }); - - $this->assertSame('bar-baz', $pimple['foo']); - } - - /** - * @dataProvider badServiceDefinitionProvider - */ - public function testExtendFailsForInvalidServiceDefinitions($service) - { - $this->expectException(\TypeError::class); - $pimple = new Container(); - $pimple['foo'] = function () {}; - $pimple->extend('foo', $service); - } - - /** - * @group legacy - * @dataProvider badServiceDefinitionProvider - */ - public function testLegacyExtendFailsForInvalidServiceDefinitions($service) - { - $this->expectException(\TypeError::class); - $pimple = new Container(); - $pimple['foo'] = function () {}; - $pimple->extend('foo', $service); - } - - public function testExtendFailsIfFrozenServiceIsNonInvokable() - { - $this->expectException(FrozenServiceException::class); - $this->expectExceptionMessage('Cannot override frozen service "foo".'); - - $pimple = new Container(); - $pimple['foo'] = function () { - return new NonInvokable(); - }; - $foo = $pimple['foo']; - - $pimple->extend('foo', function () {}); - } - - public function testExtendFailsIfFrozenServiceIsInvokable() - { - $this->expectException(FrozenServiceException::class); - $this->expectExceptionMessage('Cannot override frozen service "foo".'); - - $pimple = new Container(); - $pimple['foo'] = function () { - return new Invokable(); - }; - $foo = $pimple['foo']; - - $pimple->extend('foo', function () {}); - } - - /** - * Provider for invalid service definitions. - */ - public static function badServiceDefinitionProvider() - { - return [ - [123], - [new NonInvokable()], - ]; - } - - /** - * Provider for service definitions. - */ - public static function serviceDefinitionProvider() - { - return [ - [function ($value) { - $service = new Service(); - $service->value = $value; - - return $service; - }], - [new Invokable()], - ]; - } - - public function testDefiningNewServiceAfterFreeze() - { - $pimple = new Container(); - $pimple['foo'] = function () { - return 'foo'; - }; - $foo = $pimple['foo']; - - $pimple['bar'] = function () { - return 'bar'; - }; - $this->assertSame('bar', $pimple['bar']); - } - - public function testOverridingServiceAfterFreeze() - { - $this->expectException(FrozenServiceException::class); - $this->expectExceptionMessage('Cannot override frozen service "foo".'); - - $pimple = new Container(); - $pimple['foo'] = function () { - return 'foo'; - }; - $foo = $pimple['foo']; - - $pimple['foo'] = function () { - return 'bar'; - }; - } - - /** - * @group legacy - */ - public function testLegacyOverridingServiceAfterFreeze() - { - $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('Cannot override frozen service "foo".'); - - $pimple = new Container(); - $pimple['foo'] = function () { - return 'foo'; - }; - $foo = $pimple['foo']; - - $pimple['foo'] = function () { - return 'bar'; - }; - } - - public function testRemovingServiceAfterFreeze() - { - $pimple = new Container(); - $pimple['foo'] = function () { - return 'foo'; - }; - $foo = $pimple['foo']; - - unset($pimple['foo']); - $pimple['foo'] = function () { - return 'bar'; - }; - $this->assertSame('bar', $pimple['foo']); - } - - public function testExtendingService() - { - $pimple = new Container(); - $pimple['foo'] = function () { - return 'foo'; - }; - $pimple['foo'] = $pimple->extend('foo', function ($foo, $app) { - return "$foo.bar"; - }); - $pimple['foo'] = $pimple->extend('foo', function ($foo, $app) { - return "$foo.baz"; - }); - $this->assertSame('foo.bar.baz', $pimple['foo']); - } - - public function testExtendingServiceAfterOtherServiceFreeze() - { - $pimple = new Container(); - $pimple['foo'] = function () { - return 'foo'; - }; - $pimple['bar'] = function () { - return 'bar'; - }; - $foo = $pimple['foo']; - - $pimple['bar'] = $pimple->extend('bar', function ($bar, $app) { - return "$bar.baz"; - }); - $this->assertSame('bar.baz', $pimple['bar']); - } -} - -class Invokable -{ - public function __invoke($value = null) - { - $service = new Service(); - $service->value = $value; - - return $service; - } -} - -class NonInvokable -{ - public function __call($a, $b) {} -} - -class Service -{ - public $value; -} diff --git a/tests/src/Component/Ssh/IOArgumentsTest.php b/tests/src/Component/Ssh/IOArgumentsTest.php deleted file mode 100644 index 61d039e61..000000000 --- a/tests/src/Component/Ssh/IOArgumentsTest.php +++ /dev/null @@ -1,34 +0,0 @@ -set('foo', 'a'); - $config['bar'] = 'b'; - - self::assertEquals('a b', $config->parse('{{foo}} {{bar}}')); - } - - public function testUnset() - { - $config = new Configuration(); - $config->set('opt', true); - unset($config['opt']); - self::assertFalse(isset($config['opt'])); - } - - public function testGet() - { - $config = new Configuration(); - $config->set('opt', true); - $config->set('fn', function () { - return 'func'; - }); - - self::assertTrue(isset($config['opt'])); - self::assertEquals(true, $config['opt']); - self::assertEquals('func', $config['fn']); - } - - public function testGetDefault() - { - $config = new Configuration(); - $config->set('name', 'alpha'); - - self::assertEquals('/alpha', $config->get('path', '/{{name}}')); - } - - public function testGetException() - { - $this->expectException(ConfigurationException::class); - - $config = new Configuration(); - $config->set('name', 'alpha'); - - self::assertEquals('/alpha', $config->get('path')); - } - - public function testGetParent() - { - $parent = new Configuration(); - $config = new Configuration($parent); - - $parent->set('opt', 'value'); - self::assertEquals('value', $parent['opt']); - self::assertEquals('value', $config['opt']); - - $parent->set('opt', 'newValue'); - self::assertEquals('newValue', $parent['opt']); - self::assertEquals('value', $config['opt']); - - $config->set('opt', 'hostValue'); - self::assertEquals('newValue', $parent['opt']); - self::assertEquals('hostValue', $config['opt']); - self::assertEquals('okay', $config->get('miss', 'okay')); - } - - public function testGetParentParent() - { - $global = new Configuration(); - $parent = new Configuration($global); - $config = new Configuration($parent); - - $global->set('global', 'value from {{path}}'); - $parent->set('path', 'parent'); - - self::assertEquals('value from parent', $config->get('global')); - } - - public function testGetParentWhatDependsOnChild() - { - $parent = new Configuration(); - $alpha = new Configuration($parent); - $beta = new Configuration($parent); - - $parent->set('deploy_path', 'path/{{name}}'); - $alpha->set('name', 'alpha'); - $beta->set('name', 'beta'); - - self::assertEquals('path/alpha', $alpha->get('deploy_path')); - self::assertEquals('path/beta', $beta->get('deploy_path')); - } - - public function testGetFromCallback() - { - $config = new Configuration(); - $config->set('func', function () { - return 'param'; - }); - self::assertEquals('param', $config['func']); - } - - public function testAdd() - { - $config = new Configuration(); - $config->set('opt', ['foo', 'bar']); - $config->add('opt', ['baz']); - self::assertEquals(['foo', 'bar', 'baz'], $config['opt']); - } - - public function testAddEmpty() - { - $config = new Configuration(); - $config->add('opt', ['baz']); - self::assertEquals(['baz'], $config['opt']); - } - - public function testAddDefaultToNotArray() - { - $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage('Config option "config" isn\'t array.'); - - $config = new Configuration(); - $config->set('config', 'option'); - $config->add('config', ['three']); - } - - public function testAddToParent() - { - $parent = new Configuration(); - $alpha = new Configuration($parent); - - $parent->set('files', ['a', 'b']); - $alpha->add('files', ['c']); - - self::assertEquals(['a', 'b', 'c'], $alpha->get('files')); - } - - public function testAddToParentCallback() - { - $parent = new Configuration(); - $alpha = new Configuration($parent); - - $parent->set('files', function () { - return ['a', 'b']; - }); - $alpha->add('files', ['c']); - - self::assertEquals(['a', 'b', 'c'], $alpha->get('files')); - } - - public function testPersist() - { - $parent = new Configuration(); - $alpha = new Configuration($parent); - - $parent->set('global', 'do not include'); - $alpha->set('whoami', function () { - $this->fail('should not be called'); - }); - $alpha->set('name', 'alpha'); - - self::assertEquals(['name' => 'alpha'], $alpha->persist()); - } -} diff --git a/tests/src/DeployerTest.php b/tests/src/DeployerTest.php deleted file mode 100644 index e3b4d4da4..000000000 --- a/tests/src/DeployerTest.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class DeployerTest extends TestCase -{ - private $deployer; - - protected function setUp(): void - { - $console = new Application(); - $input = $this->createMock(InputInterface::class); - $output = $this->createMock(OutputInterface::class); - $this->deployer = new Deployer($console, $input, $output); - } - - protected function tearDown(): void - { - unset($this->deployer); - } - - public function testInstance() - { - $this->assertEquals($this->deployer, Deployer::get()); - } -} diff --git a/tests/src/FunctionsTest.php b/tests/src/FunctionsTest.php deleted file mode 100644 index 4d1a06cab..000000000 --- a/tests/src/FunctionsTest.php +++ /dev/null @@ -1,182 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer; - -use Deployer\Configuration\Configuration; -use Deployer\Host\Host; -use Deployer\Host\Localhost; -use Deployer\Task\Context; -use Deployer\Task\GroupTask; -use Deployer\Task\Task; -use PHPUnit\Framework\TestCase; -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Input\Input; -use Symfony\Component\Console\Output\Output; - -use function Deployer\localhost; - -class FunctionsTest extends TestCase -{ - /** - * @var Deployer - */ - private $deployer; - - protected function setUp(): void - { - $console = new Application(); - - $input = $this->createMock(Input::class); - $output = $this->createMock(Output::class); - $host = new Localhost(); - - $this->deployer = new Deployer($console); - $this->deployer['input'] = $input; - $this->deployer['output'] = $output; - Context::push(new Context($host)); - } - - protected function tearDown(): void - { - Context::pop(); - unset($this->deployer); - $this->deployer = null; - } - - public function testHost() - { - host('domain.com'); - self::assertInstanceOf(Host::class, $this->deployer->hosts->get('domain.com')); - - host('a1.domain.com', 'a2.domain.com')->set('roles', 'app'); - self::assertInstanceOf(Host::class, $this->deployer->hosts->get('a1.domain.com')); - self::assertInstanceOf(Host::class, $this->deployer->hosts->get('a2.domain.com')); - - host('db[1:2].domain.com')->set('roles', 'db'); - self::assertInstanceOf(Host::class, $this->deployer->hosts->get('db1.domain.com')); - self::assertInstanceOf(Host::class, $this->deployer->hosts->get('db2.domain.com')); - } - - public function testLocalhost() - { - localhost('domain.com'); - self::assertInstanceOf(Localhost::class, $this->deployer->hosts->get('domain.com')); - } - - public function testTask() - { - task('task', function () {}); - - $task = $this->deployer->tasks->get('task'); - self::assertInstanceOf(Task::class, $task); - - $task = task('task'); - self::assertInstanceOf(Task::class, $task); - - task('group', ['task']); - $task = $this->deployer->tasks->get('group'); - self::assertInstanceOf(GroupTask::class, $task); - } - - public function testBefore() - { - task('main', function () {}); - task('before', function () {}); - before('main', 'before'); - before('before', function () {}); - - $names = $this->taskToNames($this->deployer->scriptManager->getTasks('main')); - self::assertEquals(['before:before', 'before', 'main'], $names); - } - - public function testAfter() - { - task('main', function () {}); - task('after', function () {}); - after('main', 'after'); - after('after', function () {}); - - $names = $this->taskToNames($this->deployer->scriptManager->getTasks('main')); - self::assertEquals(['main', 'after', 'after:after'], $names); - } - - public function testRunLocally() - { - $output = runLocally('echo "hello"'); - self::assertEquals('hello', $output); - } - - public function testRunLocallyWithOptions() - { - Context::get()->getConfig()->set('env', ['DEPLOYER_ENV' => 'default', 'DEPLOYER_ENV_TMP' => 'default']); - - $output = runLocally('echo $DEPLOYER_ENV'); - self::assertEquals('default', $output); - $output = runLocally('echo $DEPLOYER_ENV_TMP'); - self::assertEquals('default', $output); - - $output = runLocally('echo $DEPLOYER_ENV', ['env' => ['DEPLOYER_ENV_TMP' => 'overwritten']]); - self::assertEquals('default', $output); - $output = runLocally('echo $DEPLOYER_ENV_TMP', ['env' => ['DEPLOYER_ENV_TMP' => 'overwritten']]); - self::assertEquals('overwritten', $output); - } - - public function testWithinSetsWorkingPaths() - { - Context::get()->getConfig()->set('working_path', '/foo'); - - within('/bar', function () { - $withinWorkingPath = Context::get()->getConfig()->get('working_path'); - self::assertEquals('/bar', $withinWorkingPath); - }); - - $originalWorkingPath = Context::get()->getConfig()->get('working_path'); - self::assertEquals('/foo', $originalWorkingPath); - } - - public function testWithinRestoresWorkingPathInCaseOfException() - { - Context::get()->getConfig()->set('working_path', '/foo'); - - try { - within('/bar', function () { - throw new \Exception('Dummy exception'); - }); - } catch (\Exception $exception) { - // noop - } - - $originalWorkingPath = Context::get()->getConfig()->get('working_path'); - self::assertEquals('/foo', $originalWorkingPath); - } - - public function testWithinReturningValue() - { - $output = within('/foo', function () { - return 'bar'; - }); - - self::assertEquals('bar', $output); - } - - public function testWithinWithVoidFunction() - { - $output = within('/foo', function () { - // noop - }); - - self::assertNull($output); - } - - private function taskToNames($tasks) - { - return array_map(function (Task $task) { - return $task->getName(); - }, $tasks); - } -} diff --git a/tests/src/Host/ConfigurationTest.php b/tests/src/Host/ConfigurationTest.php deleted file mode 100644 index ae5a6d82e..000000000 --- a/tests/src/Host/ConfigurationTest.php +++ /dev/null @@ -1,87 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Host; - -use Deployer\Configuration\Configuration; -use Deployer\Exception\ConfigurationException; -use PHPUnit\Framework\TestCase; - -class ConfigurationTest extends TestCase -{ - public function testConfiguration() - { - $config = new Configuration(); - $config->set('int', 42); - $config->set('string', 'value'); - $config->set('array', [1, 'two']); - $config->set('hyphen-ated', 'hyphen'); - $config->set('parse', 'is {{int}}'); - $config->set('parse-hyphen', 'has {{hyphen-ated}}'); - $config->set('callback', function () { - return 'callback'; - }); - $this->assertEquals(42, $config->get('int')); - $this->assertEquals('value', $config->get('string')); - $this->assertEquals([1, 'two'], $config->get('array')); - $this->assertEquals('default', $config->get('no', 'default')); - $this->assertEquals(null, $config->get('no', null)); - $this->assertEquals('callback', $config->get('callback')); - $this->assertEquals('is 42', $config->get('parse')); - $this->assertEquals('has hyphen', $config->get('parse-hyphen')); - - $config->set('int', 11); - $this->assertEquals('is 11', $config->get('parse')); - - $this->expectException('RuntimeException'); - $config->get('so'); - } - - public function testAddParams() - { - $config = new Configuration(); - $config->set('config', [ - 'one', - 'two' => 2, - 'nested' => [], - ]); - $config->add('config', [ - 'two' => 20, - 'nested' => [ - 'first', - ], - ]); - $config->add('config', [ - 'nested' => [ - 'second', - ], - ]); - $config->add('config', [ - 'extra', - ]); - - $expected = [ - 'one', - 'two' => 20, - 'nested' => [ - 'first', - 'second', - ], - 'extra', - ]; - $this->assertEquals($expected, $config->get('config')); - } - - public function testAddParamsToNotArray() - { - $this->expectException(ConfigurationException::class); - - $config = new Configuration(); - $config->set('config', 'option'); - $config->add('config', ['three']); - } -} diff --git a/tests/src/Host/HostTest.php b/tests/src/Host/HostTest.php deleted file mode 100644 index d1f66234c..000000000 --- a/tests/src/Host/HostTest.php +++ /dev/null @@ -1,86 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Host; - -use Deployer\Configuration\Configuration; -use PHPUnit\Framework\TestCase; - -class HostTest extends TestCase -{ - public function testHost() - { - $host = new Host('host'); - $host - ->setHostname('hostname') - ->setRemoteUser('remote_user') - ->setPort(22) - ->setConfigFile('~/.ssh/config') - ->setIdentityFile('~/.ssh/id_rsa') - ->setForwardAgent(true) - ->setSshMultiplexing(true); - - self::assertEquals('host', $host->getAlias()); - self::assertStringContainsString('host', $host->getTag()); - self::assertEquals('hostname', $host->getHostname()); - self::assertEquals('remote_user', $host->getRemoteUser()); - self::assertEquals(22, $host->getPort()); - self::assertEquals('~/.ssh/config', $host->getConfigFile()); - self::assertEquals('~/.ssh/id_rsa', $host->getIdentityFile()); - self::assertEquals(true, $host->getForwardAgent()); - self::assertEquals(true, $host->getSshMultiplexing()); - } - - public function testConfigurationAccessor() - { - $host = new Host('host'); - $host - ->set('roles', ['db', 'app']) - ->set('key', 'value') - ->set('array', [1]) - ->add('array', [2]); - - self::assertEquals(['db', 'app'], $host->get('roles')); - self::assertEquals('value', $host->get('key')); - self::assertEquals([1, 2], $host->get('array')); - } - - public function testHostAlias() - { - $host = new Host('host/alias'); - self::assertEquals('host/alias', $host->getAlias()); - self::assertEquals('host', $host->getHostname()); - } - - public function testHostWithParams() - { - $host = new Host('host'); - $value = 'new_value'; - $host - ->set('env', $value) - ->set('identity_file', '{{env}}'); - - self::assertEquals($value, $host->getIdentityFile()); - } - - public function testHostWithUserFromConfig() - { - $parent = new Configuration(); - $parent->set("deploy_user", function () { - return "test_user"; - }); - - $host = new Host('host'); - $host->config()->bind($parent); - $host - ->setHostname('host') - ->setRemoteUser('{{deploy_user}}') - ->setPort(22); - - self::assertEquals('test_user@host', $host->connectionString()); - } -} diff --git a/tests/src/Host/RangeTest.php b/tests/src/Host/RangeTest.php deleted file mode 100644 index 15cb9c0a4..000000000 --- a/tests/src/Host/RangeTest.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Host; - -use PHPUnit\Framework\TestCase; - -class RangeTest extends TestCase -{ - public function testExpand() - { - self::assertEquals(['h1', 'h2', 'h3'], Range::expand(['h[1:3]'])); - self::assertEquals(['h1', 'h2', 'ha'], Range::expand(['h[1:2]', 'ha'])); - self::assertEquals(['h0', 'h1'], Range::expand(['h[0:1]'])); - self::assertEquals(['h1'], Range::expand(['h[1:1]'])); - self::assertEquals(['ha', 'hb', 'hc', 'hd'], Range::expand(['h[a:d]'])); - - $hostnames = Range::expand(['h[01:20]']); - self::assertContains('h01', $hostnames); - self::assertContains('h10', $hostnames); - self::assertContains('h20', $hostnames); - - self::assertCount(100, Range::expand(['h[1:100]'])); - self::assertCount(26, Range::expand(['h[a:z]'])); - } -} diff --git a/tests/src/Importer/ImporterTest.php b/tests/src/Importer/ImporterTest.php deleted file mode 100644 index 890471411..000000000 --- a/tests/src/Importer/ImporterTest.php +++ /dev/null @@ -1,82 +0,0 @@ -previousInput = $deployer->input; - $this->previousOutput = $deployer->output; - } - - public function tearDown(): void - { - Deployer::get()->input = $this->previousInput; - Deployer::get()->output = $this->previousOutput; - } - - public function testCanOneOverrideStaticMethod(): void - { - $extendedImporter = new class extends Importer { - public static $config = []; - - protected static function config(array $config) - { - static::$config = $config; - } - }; - - $data = << 'bar'], $extendedImporter::$config); - } - - public function testImporterIgnoresYamlHiddenKeys(): void - { - $data = <<hosts->has('production')); - self::assertTrue(Deployer::get()->hosts->has('acceptance')); - self::assertTrue(Deployer::get()->hosts->has('production.beta')); - self::assertEquals('acceptance', Deployer::get()->hosts->get('acceptance')->getLabels()['stage']); - self::assertEquals('production', Deployer::get()->hosts->get('production')->getLabels()['stage']); - self::assertEquals('foo', Deployer::get()->hosts->get('acceptance')->getRemoteUser()); - self::assertEquals('bar', Deployer::get()->hosts->get('production')->getRemoteUser()); - } -} diff --git a/tests/src/Selector/SelectorTest.php b/tests/src/Selector/SelectorTest.php deleted file mode 100644 index d8dc61a99..000000000 --- a/tests/src/Selector/SelectorTest.php +++ /dev/null @@ -1,32 +0,0 @@ -set('labels', ['stage' => 'prod']); - $front = (new Host('prod.domain.com/front'))->set('labels', ['stage' => 'prod', 'tier' => 'frontend']); - $beta = (new Host('beta.domain.com'))->set('labels', ['stage' => 'beta']); - $dev = (new Host('dev'))->set('labels', ['stage' => 'dev']); - $multi = (new Host('multi'))->set('labels', ['stage' => ['prod', 'beta']]); - $allHosts = [$prod, $front, $beta, $dev, $multi]; - - $hosts = new HostCollection(); - foreach ($allHosts as $host) { - $hosts->set($host->getAlias(), $host); - } - $selector = new Selector($hosts); - self::assertEquals($allHosts, $selector->select('all')); - self::assertEquals([$prod, $front, $multi], $selector->select('stage=prod')); - self::assertEquals([$front], $selector->select('stage=prod & tier=frontend')); - self::assertEquals([$front, $beta, $multi], $selector->select('prod.domain.com/front, stage=beta')); - self::assertEquals([$prod, $beta, $dev, $multi], $selector->select('all & tier != frontend')); - self::assertEquals([$prod, $front, $dev], $selector->select('stage != beta')); - } -} diff --git a/tests/src/Support/HelpersTest.php b/tests/src/Support/HelpersTest.php deleted file mode 100644 index dea76b150..000000000 --- a/tests/src/Support/HelpersTest.php +++ /dev/null @@ -1,67 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Support; - -use PHPUnit\Framework\TestCase; - -class HelpersTest extends TestCase -{ - public function testArrayFlatten() - { - self::assertEquals(['a', 'b', 'c'], array_flatten(['a', ['b', 'key' => ['c']]])); - } - - public function testArrayMergeAlternate() - { - $config = [ - 'one', - 'two' => 2, - 'nested' => [], - ]; - - $config = array_merge_alternate($config, [ - 'two' => 20, - 'nested' => [ - 'first', - ], - ]); - - $config = array_merge_alternate($config, [ - 'nested' => [ - 'second', - ], - ]); - - $config = array_merge_alternate($config, [ - 'extra', - ]); - - self::assertEquals([ - 'one', - 'two' => 20, - 'nested' => [ - 'first', - 'second', - ], - 'extra', - ], $config); - } - - public function testParseHomeDir() - { - $this->assertStringStartsWith('/', parse_home_dir('~/path')); - $this->assertStringStartsWith('/', parse_home_dir('~')); - $this->assertStringStartsWith('~', parse_home_dir('~path')); - $this->assertStringEndsWith('~', parse_home_dir('path~')); - } - - public function testEscapeShellArgument() - { - $this->assertEquals('\'{"foobar":"Lorem ipsum\'\\\'\'s dolor"}\'', escape_shell_argument(json_encode(['foobar' => 'Lorem ipsum\'s dolor']))); - } -} diff --git a/tests/src/Support/ObjectProxyTest.php b/tests/src/Support/ObjectProxyTest.php deleted file mode 100644 index aa613ef2e..000000000 --- a/tests/src/Support/ObjectProxyTest.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Support; - -use PHPUnit\Framework\TestCase; - -class ObjectProxyTest extends TestCase -{ - public function testObjectProxy() - { - $mock = self::getMockBuilder('stdClass') - ->addMethods(['foo']) - ->getMock(); - $mock - ->expects(self::once()) - ->method('foo') - ->with('a', 'b'); - - $proxy = new ObjectProxy([$mock]); - $proxy->foo('a', 'b'); - } -} diff --git a/tests/src/Task/ContextTest.php b/tests/src/Task/ContextTest.php deleted file mode 100644 index 131b01db4..000000000 --- a/tests/src/Task/ContextTest.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Task; - -use Deployer\Configuration\Configuration; -use Deployer\Host\Host; -use PHPUnit\Framework\TestCase; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class ContextTest extends TestCase -{ - public function testContext() - { - $host = $this->getMockBuilder(Host::class)->disableOriginalConstructor()->getMock(); - $host - ->expects($this->once()) - ->method('config') - ->willReturn($this->createMock(Configuration::class)); - - $context = new Context($host); - - $this->assertInstanceOf(Host::class, $context->getHost()); - $this->assertInstanceOf(Configuration::class, $context->getConfig()); - - Context::push($context); - - $this->assertEquals($context, Context::get()); - $this->assertEquals($context, Context::pop()); - } -} diff --git a/tests/src/Task/ScriptManagerTest.php b/tests/src/Task/ScriptManagerTest.php deleted file mode 100644 index c6b7cf90a..000000000 --- a/tests/src/Task/ScriptManagerTest.php +++ /dev/null @@ -1,103 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Task; - -use PHPUnit\Framework\TestCase; - -class ScriptManagerTest extends TestCase -{ - public function testGetTasks() - { - $notify = new Task('notify'); - $info = new GroupTask('info', ['notify']); - $deploy = new GroupTask('deploy', ['deploy:setup', 'deploy:release']); - $deploy->addBefore($info); - $setup = new Task('deploy:setup'); - $release = new Task('deploy:release'); - - $taskCollection = new TaskCollection(); - $taskCollection->set($notify->getName(), $notify); - $taskCollection->set($info->getName(), $info); - $taskCollection->set($deploy->getName(), $deploy); - $taskCollection->set($setup->getName(), $setup); - $taskCollection->set($release->getName(), $release); - - $scriptManager = new ScriptManager($taskCollection); - self::assertEquals([$notify, $setup, $release], $scriptManager->getTasks('deploy')); - } - - public function testOnce() - { - $a = new Task('a'); - $b = new Task('b'); - $b->once(); - $group = new GroupTask('group', ['a', 'b']); - - $taskCollection = new TaskCollection(); - $taskCollection->add($a); - $taskCollection->add($b); - $taskCollection->add($group); - - $scriptManager = new ScriptManager($taskCollection); - self::assertEquals([$a, $b], $scriptManager->getTasks('group')); - self::assertFalse($a->isOnce()); - self::assertTrue($b->isOnce()); - - $group->once(); - self::assertEquals([$a, $b], $scriptManager->getTasks('group')); - self::assertTrue($a->isOnce()); - self::assertTrue($b->isOnce()); - } - - public function testSelectsCombine() - { - $a = new Task('a'); - $b = new Task('b'); - $c = new Task('c'); - $b->select('stage=beta'); - $c->select('stage=alpha|beta & role=db'); - $group = new GroupTask('group', ['a', 'b', 'c']); - - $taskCollection = new TaskCollection(); - $taskCollection->add($a); - $taskCollection->add($b); - $taskCollection->add($c); - $taskCollection->add($group); - - $scriptManager = new ScriptManager($taskCollection); - self::assertEquals([$a, $b, $c], $scriptManager->getTasks('group')); - self::assertNull($a->getSelector()); - self::assertEquals([[['=', 'stage', ['beta']]]], $b->getSelector()); - self::assertEquals([[['=', 'stage', ['alpha', 'beta']],['=', 'role', ['db']]]], $c->getSelector()); - - $group->select('role=prod'); - self::assertEquals([$a, $b, $c], $scriptManager->getTasks('group')); - self::assertEquals([[['=', 'role', ['prod']]]], $a->getSelector()); - self::assertEquals([[['=', 'stage', ['beta']]],[['=', 'role', ['prod']]]], $b->getSelector()); - self::assertEquals([[['=', 'stage', ['alpha', 'beta']],['=', 'role', ['db']]],[['=', 'role', ['prod']]]], $c->getSelector()); - } - - public function testThrowsExceptionIfTaskCollectionEmpty() - { - self::expectException(\InvalidArgumentException::class); - - $scriptManager = new ScriptManager(new TaskCollection()); - $scriptManager->getTasks(''); - } - - public function testThrowsExceptionIfTaskDontExists() - { - self::expectException(\InvalidArgumentException::class); - - $taskCollection = new TaskCollection(); - $taskCollection->set('testTask', new Task('testTask')); - - $scriptManager = new ScriptManager($taskCollection); - $scriptManager->getTasks('testTask2'); - } -} diff --git a/tests/src/Task/TaskTest.php b/tests/src/Task/TaskTest.php deleted file mode 100644 index df8d47a52..000000000 --- a/tests/src/Task/TaskTest.php +++ /dev/null @@ -1,115 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Deployer\Task; - -use Deployer\Host\Host; -use PHPUnit\Framework\TestCase; - -use function Deployer\invoke; -use function Deployer\task; - -class TaskTest extends TestCase -{ - protected function tearDown(): void - { - StubTask::$runned = 0; - } - - public function testTask() - { - $mock = self::getMockBuilder('stdClass') - ->addMethods(['callback']) - ->getMock(); - $mock - ->expects(self::exactly(1)) - ->method('callback'); - - $task = new Task('task_name', function () use ($mock) { - $mock->callback(); - }); - - $context = self::getMockBuilder(Context::class) - ->disableOriginalConstructor() - ->getMock(); - $task->run($context); - - self::assertEquals('task_name', $task->getName()); - - $task->desc('Task description.'); - self::assertEquals('Task description.', $task->getDescription()); - - $task->hidden(); - self::assertTrue($task->isHidden()); - - $task->once(); - self::assertTrue($task->isOnce()); - - $task->oncePerNode(); - self::assertTrue($task->isOncePerNode()); - } - - public function testInit() - { - $context = self::getMockBuilder(Context::class)->disableOriginalConstructor()->getMock(); - - // Test create task with [$object, 'method'] - $mock1 = self::getMockBuilder('stdClass') - ->addMethods(['callback']) - ->getMock(); - $mock1 - ->expects(self::once()) - ->method('callback'); - $task1 = new Task('task1', [$mock1, 'callback']); - $task1->run($context); - - // Test create task with anonymous functions - $mock2 = self::getMockBuilder('stdClass') - ->addMethods(['callback']) - ->getMock(); - $mock2 - ->expects(self::once()) - ->method('callback'); - $task2 = new Task('task2', function () use ($mock2) { - $mock2->callback(); - }); - $task2->run($context); - - self::assertEquals(0, StubTask::$runned); - $task3 = new Task('task3', new StubTask()); - $task3->run($context); - self::assertEquals(1, StubTask::$runned); - } - - public function testGroupInvoke(): void - { - $spy = new StubTask(); - - task('foo', $spy); - task('bar', $spy); - task('group', ['foo', 'bar']); - - (new Task('group:invoke', function () { - invoke('group'); - }))->run(new Context(new Host('localhost'))); - - $this->assertSame(2, StubTask::$runned); - } -} - -/** - * Stub class for task callable by __invoke() - */ -class StubTask -{ - public static $runned = 0; - - public function __invoke() - { - self::$runned++; - } -} diff --git a/vendor/autoload.php b/vendor/autoload.php deleted file mode 100644 index c9f659bd4..000000000 --- a/vendor/autoload.php +++ /dev/null @@ -1,7 +0,0 @@ - - * 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 -{ - // PSR-4 - private $prefixLengthsPsr4 = array(); - private $prefixDirsPsr4 = array(); - private $fallbackDirsPsr4 = array(); - - // PSR-0 - private $prefixesPsr0 = array(); - private $fallbackDirsPsr0 = array(); - - private $useIncludePath = false; - private $classMap = array(); - private $classMapAuthoritative = false; - private $missingClasses = array(); - private $apcuPrefix; - - public function getPrefixes() - { - if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); - } - - return array(); - } - - public function getPrefixesPsr4() - { - return $this->prefixDirsPsr4; - } - - public function getFallbackDirs() - { - return $this->fallbackDirsPsr0; - } - - public function getFallbackDirsPsr4() - { - return $this->fallbackDirsPsr4; - } - - public function getClassMap() - { - return $this->classMap; - } - - /** - * @param array $classMap Class to filename map - */ - 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 array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories - */ - public function add($prefix, $paths, $prepend = false) - { - if (!$prefix) { - if ($prepend) { - $this->fallbackDirsPsr0 = array_merge( - (array) $paths, - $this->fallbackDirsPsr0 - ); - } else { - $this->fallbackDirsPsr0 = array_merge( - $this->fallbackDirsPsr0, - (array) $paths - ); - } - - return; - } - - $first = $prefix[0]; - if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; - - return; - } - if ($prepend) { - $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, - $this->prefixesPsr0[$first][$prefix] - ); - } else { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $this->prefixesPsr0[$first][$prefix], - (array) $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 array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories - * - * @throws \InvalidArgumentException - */ - public function addPsr4($prefix, $paths, $prepend = false) - { - if (!$prefix) { - // Register directories for the root namespace. - if ($prepend) { - $this->fallbackDirsPsr4 = array_merge( - (array) $paths, - $this->fallbackDirsPsr4 - ); - } else { - $this->fallbackDirsPsr4 = array_merge( - $this->fallbackDirsPsr4, - (array) $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] = (array) $paths; - } elseif ($prepend) { - // Prepend directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, - $this->prefixDirsPsr4[$prefix] - ); - } else { - // Append directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $this->prefixDirsPsr4[$prefix], - (array) $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 array|string $paths The PSR-0 base directories - */ - 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 array|string $paths The PSR-4 base directories - * - * @throws \InvalidArgumentException - */ - 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 - */ - 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 - */ - 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 - */ - 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 - */ - public function register($prepend = false) - { - spl_autoload_register(array($this, 'loadClass'), true, $prepend); - } - - /** - * Unregisters this instance as an autoloader. - */ - public function unregister() - { - spl_autoload_unregister(array($this, 'loadClass')); - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise - */ - public function loadClass($class) - { - if ($file = $this->findFile($class)) { - includeFile($file); - - return true; - } - } - - /** - * 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; - } - - 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; - } -} - -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -function includeFile($file) -{ - include $file; -} diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php deleted file mode 100644 index 6ffa4b9b7..000000000 --- a/vendor/composer/InstalledVersions.php +++ /dev/null @@ -1,476 +0,0 @@ - - array ( - 'pretty_version' => 'v7.1.2', - 'version' => '7.1.2.0', - 'aliases' => - array ( - ), - 'reference' => '6b354c2e89198e64a0244fb96cc5604312027800', - 'name' => 'deployer/deployer', - ), - 'versions' => - array ( - 'deployer/deployer' => - array ( - 'pretty_version' => 'v7.1.2', - 'version' => '7.1.2.0', - 'aliases' => - array ( - ), - 'reference' => '6b354c2e89198e64a0244fb96cc5604312027800', - ), - 'evenement/evenement' => - array ( - 'pretty_version' => 'v3.0.1', - 'version' => '3.0.1.0', - 'aliases' => - array ( - ), - 'reference' => '531bfb9d15f8aa57454f5f0285b18bec903b8fb7', - ), - 'fig/http-message-util' => - array ( - 'pretty_version' => '1.1.5', - 'version' => '1.1.5.0', - 'aliases' => - array ( - ), - 'reference' => '9d94dc0154230ac39e5bf89398b324a86f63f765', - ), - 'justinrainbow/json-schema' => - array ( - 'pretty_version' => '5.2.11', - 'version' => '5.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '2ab6744b7296ded80f8cc4f9509abbff393399aa', - ), - 'psr/container' => - array ( - 'pretty_version' => '1.1.1', - 'version' => '1.1.1.0', - 'aliases' => - array ( - ), - 'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf', - ), - 'psr/http-message' => - array ( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'aliases' => - array ( - ), - 'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363', - ), - 'psr/http-message-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0', - ), - ), - 'psr/log-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0|2.0', - ), - ), - 'react/cache' => - array ( - 'pretty_version' => 'v1.1.1', - 'version' => '1.1.1.0', - 'aliases' => - array ( - ), - 'reference' => '4bf736a2cccec7298bdf745db77585966fc2ca7e', - ), - 'react/dns' => - array ( - 'pretty_version' => 'v1.9.0', - 'version' => '1.9.0.0', - 'aliases' => - array ( - ), - 'reference' => '6d38296756fa644e6cb1bfe95eff0f9a4ed6edcb', - ), - 'react/event-loop' => - array ( - 'pretty_version' => 'v1.2.0', - 'version' => '1.2.0.0', - 'aliases' => - array ( - ), - 'reference' => 'be6dee480fc4692cec0504e65eb486e3be1aa6f2', - ), - 'react/http' => - array ( - 'pretty_version' => 'v1.6.0', - 'version' => '1.6.0.0', - 'aliases' => - array ( - ), - 'reference' => '59961cc4a5b14481728f07c591546be18fa3a5c7', - ), - 'react/promise' => - array ( - 'pretty_version' => 'v2.9.0', - 'version' => '2.9.0.0', - 'aliases' => - array ( - ), - 'reference' => '234f8fd1023c9158e2314fa9d7d0e6a83db42910', - ), - 'react/promise-stream' => - array ( - 'pretty_version' => 'v1.3.0', - 'version' => '1.3.0.0', - 'aliases' => - array ( - ), - 'reference' => '3ebd94fe0d8edbf44937948af28d02d5437e9949', - ), - 'react/promise-timer' => - array ( - 'pretty_version' => 'v1.8.0', - 'version' => '1.8.0.0', - 'aliases' => - array ( - ), - 'reference' => '0bbbcc79589e5bfdddba68a287f1cb805581a479', - ), - 'react/socket' => - array ( - 'pretty_version' => 'v1.11.0', - 'version' => '1.11.0.0', - 'aliases' => - array ( - ), - 'reference' => 'f474156aaab4f09041144fa8b57c7d70aed32a1c', - ), - 'react/stream' => - array ( - 'pretty_version' => 'v1.2.0', - 'version' => '1.2.0.0', - 'aliases' => - array ( - ), - 'reference' => '7a423506ee1903e89f1e08ec5f0ed430ff784ae9', - ), - 'ringcentral/psr7' => - array ( - 'pretty_version' => '1.3.0', - 'version' => '1.3.0.0', - 'aliases' => - array ( - ), - 'reference' => '360faaec4b563958b673fb52bbe94e37f14bc686', - ), - 'symfony/console' => - array ( - 'pretty_version' => 'v5.4.17', - 'version' => '5.4.17.0', - 'aliases' => - array ( - ), - 'reference' => '58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f', - ), - 'symfony/deprecation-contracts' => - array ( - 'pretty_version' => 'v2.5.0', - 'version' => '2.5.0.0', - 'aliases' => - array ( - ), - 'reference' => '6f981ee24cf69ee7ce9736146d1c57c2780598a8', - ), - 'symfony/polyfill-ctype' => - array ( - 'pretty_version' => 'v1.25.0', - 'version' => '1.25.0.0', - 'aliases' => - array ( - ), - 'reference' => '30885182c981ab175d4d034db0f6f469898070ab', - ), - 'symfony/polyfill-intl-grapheme' => - array ( - 'pretty_version' => 'v1.25.0', - 'version' => '1.25.0.0', - 'aliases' => - array ( - ), - 'reference' => '81b86b50cf841a64252b439e738e97f4a34e2783', - ), - 'symfony/polyfill-intl-normalizer' => - array ( - 'pretty_version' => 'v1.25.0', - 'version' => '1.25.0.0', - 'aliases' => - array ( - ), - 'reference' => '8590a5f561694770bdcd3f9b5c69dde6945028e8', - ), - 'symfony/polyfill-mbstring' => - array ( - 'pretty_version' => 'v1.25.0', - 'version' => '1.25.0.0', - 'aliases' => - array ( - ), - 'reference' => '0abb51d2f102e00a4eefcf46ba7fec406d245825', - ), - 'symfony/polyfill-php73' => - array ( - 'pretty_version' => 'v1.25.0', - 'version' => '1.25.0.0', - 'aliases' => - array ( - ), - 'reference' => 'cc5db0e22b3cb4111010e48785a97f670b350ca5', - ), - 'symfony/polyfill-php80' => - array ( - 'pretty_version' => 'v1.25.0', - 'version' => '1.25.0.0', - 'aliases' => - array ( - ), - 'reference' => '4407588e0d3f1f52efb65fbe92babe41f37fe50c', - ), - 'symfony/process' => - array ( - 'pretty_version' => 'v5.4.5', - 'version' => '5.4.5.0', - 'aliases' => - array ( - ), - 'reference' => '95440409896f90a5f85db07a32b517ecec17fa4c', - ), - 'symfony/service-contracts' => - array ( - 'pretty_version' => 'v2.5.0', - 'version' => '2.5.0.0', - 'aliases' => - array ( - ), - 'reference' => '1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc', - ), - 'symfony/string' => - array ( - 'pretty_version' => 'v5.4.3', - 'version' => '5.4.3.0', - 'aliases' => - array ( - ), - 'reference' => '92043b7d8383e48104e411bc9434b260dbeb5a10', - ), - 'symfony/yaml' => - array ( - 'pretty_version' => 'v5.4.3', - 'version' => '5.4.3.0', - 'aliases' => - array ( - ), - 'reference' => 'e80f87d2c9495966768310fc531b487ce64237a2', - ), - ), -); - - - - - - - -public static function getInstalledPackages() -{ -return array_keys(self::$installed['versions']); -} - - - - - - - - - -public static function isInstalled($packageName) -{ -return isset(self::$installed['versions'][$packageName]); -} - - - - - - - - - - - - - - -public static function satisfies(VersionParser $parser, $packageName, $constraint) -{ -$constraint = $parser->parseConstraints($constraint); -$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); - -return $provided->matches($constraint); -} - - - - - - - - - - -public static function getVersionRanges($packageName) -{ -if (!isset(self::$installed['versions'][$packageName])) { -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); -} - -$ranges = array(); -if (isset(self::$installed['versions'][$packageName]['pretty_version'])) { -$ranges[] = self::$installed['versions'][$packageName]['pretty_version']; -} -if (array_key_exists('aliases', self::$installed['versions'][$packageName])) { -$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']); -} -if (array_key_exists('replaced', self::$installed['versions'][$packageName])) { -$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']); -} -if (array_key_exists('provided', self::$installed['versions'][$packageName])) { -$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']); -} - -return implode(' || ', $ranges); -} - - - - - -public static function getVersion($packageName) -{ -if (!isset(self::$installed['versions'][$packageName])) { -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); -} - -if (!isset(self::$installed['versions'][$packageName]['version'])) { -return null; -} - -return self::$installed['versions'][$packageName]['version']; -} - - - - - -public static function getPrettyVersion($packageName) -{ -if (!isset(self::$installed['versions'][$packageName])) { -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); -} - -if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) { -return null; -} - -return self::$installed['versions'][$packageName]['pretty_version']; -} - - - - - -public static function getReference($packageName) -{ -if (!isset(self::$installed['versions'][$packageName])) { -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); -} - -if (!isset(self::$installed['versions'][$packageName]['reference'])) { -return null; -} - -return self::$installed['versions'][$packageName]['reference']; -} - - - - - -public static function getRootPackage() -{ -return self::$installed['root']; -} - - - - - - - -public static function getRawData() -{ -return self::$installed; -} - - - - - - - - - - - - - - - - - - - -public static function reload($data) -{ -self::$installed = $data; -} -} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php deleted file mode 100644 index 4ac4a79a0..000000000 --- a/vendor/composer/autoload_classmap.php +++ /dev/null @@ -1,451 +0,0 @@ - $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', - 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', - 'Deployer\\Collection\\Collection' => $baseDir . '/src/Collection/Collection.php', - 'Deployer\\Command\\BlackjackCommand' => $baseDir . '/src/Command/BlackjackCommand.php', - 'Deployer\\Command\\CommandCommon' => $baseDir . '/src/Command/CommandCommon.php', - 'Deployer\\Command\\ConfigCommand' => $baseDir . '/src/Command/ConfigCommand.php', - 'Deployer\\Command\\CustomOption' => $baseDir . '/src/Command/CustomOption.php', - 'Deployer\\Command\\InitCommand' => $baseDir . '/src/Command/InitCommand.php', - 'Deployer\\Command\\MainCommand' => $baseDir . '/src/Command/MainCommand.php', - 'Deployer\\Command\\RunCommand' => $baseDir . '/src/Command/RunCommand.php', - 'Deployer\\Command\\SelectCommand' => $baseDir . '/src/Command/SelectCommand.php', - 'Deployer\\Command\\SshCommand' => $baseDir . '/src/Command/SshCommand.php', - 'Deployer\\Command\\TreeCommand' => $baseDir . '/src/Command/TreeCommand.php', - 'Deployer\\Command\\WorkerCommand' => $baseDir . '/src/Command/WorkerCommand.php', - 'Deployer\\Component\\PharUpdate\\Console\\Command' => $baseDir . '/src/Component/PharUpdate/Console/Command.php', - 'Deployer\\Component\\PharUpdate\\Console\\Helper' => $baseDir . '/src/Component/PharUpdate/Console/Helper.php', - 'Deployer\\Component\\PharUpdate\\Exception\\Exception' => $baseDir . '/src/Component/PharUpdate/Exception/Exception.php', - 'Deployer\\Component\\PharUpdate\\Exception\\ExceptionInterface' => $baseDir . '/src/Component/PharUpdate/Exception/ExceptionInterface.php', - 'Deployer\\Component\\PharUpdate\\Exception\\FileException' => $baseDir . '/src/Component/PharUpdate/Exception/FileException.php', - 'Deployer\\Component\\PharUpdate\\Exception\\InvalidArgumentException' => $baseDir . '/src/Component/PharUpdate/Exception/InvalidArgumentException.php', - 'Deployer\\Component\\PharUpdate\\Exception\\LogicException' => $baseDir . '/src/Component/PharUpdate/Exception/LogicException.php', - 'Deployer\\Component\\PharUpdate\\Manager' => $baseDir . '/src/Component/PharUpdate/Manager.php', - 'Deployer\\Component\\PharUpdate\\Manifest' => $baseDir . '/src/Component/PharUpdate/Manifest.php', - 'Deployer\\Component\\PharUpdate\\Update' => $baseDir . '/src/Component/PharUpdate/Update.php', - 'Deployer\\Component\\PharUpdate\\Version\\Builder' => $baseDir . '/src/Component/PharUpdate/Version/Builder.php', - 'Deployer\\Component\\PharUpdate\\Version\\Comparator' => $baseDir . '/src/Component/PharUpdate/Version/Comparator.php', - 'Deployer\\Component\\PharUpdate\\Version\\Dumper' => $baseDir . '/src/Component/PharUpdate/Version/Dumper.php', - 'Deployer\\Component\\PharUpdate\\Version\\Exception\\InvalidIdentifierException' => $baseDir . '/src/Component/PharUpdate/Version/Exception/InvalidIdentifierException.php', - 'Deployer\\Component\\PharUpdate\\Version\\Exception\\InvalidNumberException' => $baseDir . '/src/Component/PharUpdate/Version/Exception/InvalidNumberException.php', - 'Deployer\\Component\\PharUpdate\\Version\\Exception\\InvalidStringRepresentationException' => $baseDir . '/src/Component/PharUpdate/Version/Exception/InvalidStringRepresentationException.php', - 'Deployer\\Component\\PharUpdate\\Version\\Exception\\VersionException' => $baseDir . '/src/Component/PharUpdate/Version/Exception/VersionException.php', - 'Deployer\\Component\\PharUpdate\\Version\\Parser' => $baseDir . '/src/Component/PharUpdate/Version/Parser.php', - 'Deployer\\Component\\PharUpdate\\Version\\Validator' => $baseDir . '/src/Component/PharUpdate/Version/Validator.php', - 'Deployer\\Component\\PharUpdate\\Version\\Version' => $baseDir . '/src/Component/PharUpdate/Version/Version.php', - 'Deployer\\Component\\Pimple\\Container' => $baseDir . '/src/Component/Pimple/Container.php', - 'Deployer\\Component\\Pimple\\Exception\\ExpectedInvokableException' => $baseDir . '/src/Component/Pimple/Exception/ExpectedInvokableException.php', - 'Deployer\\Component\\Pimple\\Exception\\FrozenServiceException' => $baseDir . '/src/Component/Pimple/Exception/FrozenServiceException.php', - 'Deployer\\Component\\Pimple\\Exception\\InvalidServiceIdentifierException' => $baseDir . '/src/Component/Pimple/Exception/InvalidServiceIdentifierException.php', - 'Deployer\\Component\\Pimple\\Exception\\UnknownIdentifierException' => $baseDir . '/src/Component/Pimple/Exception/UnknownIdentifierException.php', - 'Deployer\\Component\\ProcessRunner\\Printer' => $baseDir . '/src/Component/ProcessRunner/Printer.php', - 'Deployer\\Component\\ProcessRunner\\ProcessRunner' => $baseDir . '/src/Component/ProcessRunner/ProcessRunner.php', - 'Deployer\\Component\\Ssh\\Client' => $baseDir . '/src/Component/Ssh/Client.php', - 'Deployer\\Component\\Ssh\\IOArguments' => $baseDir . '/src/Component/Ssh/IOArguments.php', - 'Deployer\\Configuration\\Configuration' => $baseDir . '/src/Configuration/Configuration.php', - 'Deployer\\Deployer' => $baseDir . '/src/Deployer.php', - 'Deployer\\Documentation\\ApiGen' => $baseDir . '/src/Documentation/ApiGen.php', - 'Deployer\\Documentation\\DocConfig' => $baseDir . '/src/Documentation/DocConfig.php', - 'Deployer\\Documentation\\DocGen' => $baseDir . '/src/Documentation/DocGen.php', - 'Deployer\\Documentation\\DocRecipe' => $baseDir . '/src/Documentation/DocRecipe.php', - 'Deployer\\Documentation\\DocTask' => $baseDir . '/src/Documentation/DocTask.php', - 'Deployer\\Exception\\ConfigurationException' => $baseDir . '/src/Exception/ConfigurationException.php', - 'Deployer\\Exception\\Exception' => $baseDir . '/src/Exception/Exception.php', - 'Deployer\\Exception\\GracefulShutdownException' => $baseDir . '/src/Exception/GracefulShutdownException.php', - 'Deployer\\Exception\\HttpieException' => $baseDir . '/src/Exception/HttpieException.php', - 'Deployer\\Exception\\RunException' => $baseDir . '/src/Exception/RunException.php', - 'Deployer\\Exception\\TimeoutException' => $baseDir . '/src/Exception/TimeoutException.php', - 'Deployer\\Exception\\WillAskUser' => $baseDir . '/src/Exception/WillAskUser.php', - 'Deployer\\Executor\\Master' => $baseDir . '/src/Executor/Master.php', - 'Deployer\\Executor\\Messenger' => $baseDir . '/src/Executor/Messenger.php', - 'Deployer\\Executor\\Planner' => $baseDir . '/src/Executor/Planner.php', - 'Deployer\\Executor\\Server' => $baseDir . '/src/Executor/Server.php', - 'Deployer\\Executor\\Worker' => $baseDir . '/src/Executor/Worker.php', - 'Deployer\\Host\\Host' => $baseDir . '/src/Host/Host.php', - 'Deployer\\Host\\HostCollection' => $baseDir . '/src/Host/HostCollection.php', - 'Deployer\\Host\\Localhost' => $baseDir . '/src/Host/Localhost.php', - 'Deployer\\Host\\Range' => $baseDir . '/src/Host/Range.php', - 'Deployer\\Importer\\Importer' => $baseDir . '/src/Importer/Importer.php', - 'Deployer\\Logger\\Handler\\FileHandler' => $baseDir . '/src/Logger/Handler/FileHandler.php', - 'Deployer\\Logger\\Handler\\HandlerInterface' => $baseDir . '/src/Logger/Handler/HandlerInterface.php', - 'Deployer\\Logger\\Handler\\NullHandler' => $baseDir . '/src/Logger/Handler/NullHandler.php', - 'Deployer\\Logger\\Logger' => $baseDir . '/src/Logger/Logger.php', - 'Deployer\\Selector\\Selector' => $baseDir . '/src/Selector/Selector.php', - 'Deployer\\Support\\ObjectProxy' => $baseDir . '/src/Support/ObjectProxy.php', - 'Deployer\\Support\\Reporter' => $baseDir . '/src/Support/Reporter.php', - 'Deployer\\Task\\Context' => $baseDir . '/src/Task/Context.php', - 'Deployer\\Task\\GroupTask' => $baseDir . '/src/Task/GroupTask.php', - 'Deployer\\Task\\ScriptManager' => $baseDir . '/src/Task/ScriptManager.php', - 'Deployer\\Task\\Task' => $baseDir . '/src/Task/Task.php', - 'Deployer\\Task\\TaskCollection' => $baseDir . '/src/Task/TaskCollection.php', - 'Deployer\\Utility\\Httpie' => $baseDir . '/src/Utility/Httpie.php', - 'Deployer\\Utility\\Rsync' => $baseDir . '/src/Utility/Rsync.php', - 'Evenement\\EventEmitter' => $vendorDir . '/evenement/evenement/src/Evenement/EventEmitter.php', - 'Evenement\\EventEmitterInterface' => $vendorDir . '/evenement/evenement/src/Evenement/EventEmitterInterface.php', - 'Evenement\\EventEmitterTrait' => $vendorDir . '/evenement/evenement/src/Evenement/EventEmitterTrait.php', - 'Fig\\Http\\Message\\RequestMethodInterface' => $vendorDir . '/fig/http-message-util/src/RequestMethodInterface.php', - 'Fig\\Http\\Message\\StatusCodeInterface' => $vendorDir . '/fig/http-message-util/src/StatusCodeInterface.php', - 'JsonException' => $vendorDir . '/symfony/polyfill-php73/Resources/stubs/JsonException.php', - 'JsonSchema\\Constraints\\BaseConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php', - 'JsonSchema\\Constraints\\CollectionConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php', - 'JsonSchema\\Constraints\\Constraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php', - 'JsonSchema\\Constraints\\ConstraintInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php', - 'JsonSchema\\Constraints\\EnumConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php', - 'JsonSchema\\Constraints\\Factory' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php', - 'JsonSchema\\Constraints\\FormatConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php', - 'JsonSchema\\Constraints\\NumberConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php', - 'JsonSchema\\Constraints\\ObjectConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php', - 'JsonSchema\\Constraints\\SchemaConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php', - 'JsonSchema\\Constraints\\StringConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php', - 'JsonSchema\\Constraints\\TypeCheck\\LooseTypeCheck' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/LooseTypeCheck.php', - 'JsonSchema\\Constraints\\TypeCheck\\StrictTypeCheck' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/StrictTypeCheck.php', - 'JsonSchema\\Constraints\\TypeCheck\\TypeCheckInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/TypeCheckInterface.php', - 'JsonSchema\\Constraints\\TypeConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php', - 'JsonSchema\\Constraints\\UndefinedConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php', - 'JsonSchema\\Entity\\JsonPointer' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Entity/JsonPointer.php', - 'JsonSchema\\Exception\\ExceptionInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/ExceptionInterface.php', - 'JsonSchema\\Exception\\InvalidArgumentException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.php', - 'JsonSchema\\Exception\\InvalidConfigException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidConfigException.php', - 'JsonSchema\\Exception\\InvalidSchemaException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaException.php', - 'JsonSchema\\Exception\\InvalidSchemaMediaTypeException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.php', - 'JsonSchema\\Exception\\InvalidSourceUriException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.php', - 'JsonSchema\\Exception\\JsonDecodingException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php', - 'JsonSchema\\Exception\\ResourceNotFoundException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.php', - 'JsonSchema\\Exception\\RuntimeException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/RuntimeException.php', - 'JsonSchema\\Exception\\UnresolvableJsonPointerException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/UnresolvableJsonPointerException.php', - 'JsonSchema\\Exception\\UriResolverException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.php', - 'JsonSchema\\Exception\\ValidationException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/ValidationException.php', - 'JsonSchema\\Iterator\\ObjectIterator' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Iterator/ObjectIterator.php', - 'JsonSchema\\Rfc3339' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Rfc3339.php', - 'JsonSchema\\SchemaStorage' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/SchemaStorage.php', - 'JsonSchema\\SchemaStorageInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/SchemaStorageInterface.php', - 'JsonSchema\\UriResolverInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/UriResolverInterface.php', - 'JsonSchema\\UriRetrieverInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/UriRetrieverInterface.php', - 'JsonSchema\\Uri\\Retrievers\\AbstractRetriever' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.php', - 'JsonSchema\\Uri\\Retrievers\\Curl' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php', - 'JsonSchema\\Uri\\Retrievers\\FileGetContents' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php', - 'JsonSchema\\Uri\\Retrievers\\PredefinedArray' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php', - 'JsonSchema\\Uri\\Retrievers\\UriRetrieverInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php', - 'JsonSchema\\Uri\\UriResolver' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php', - 'JsonSchema\\Uri\\UriRetriever' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php', - 'JsonSchema\\Validator' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Validator.php', - 'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', - 'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', - 'Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php', - 'Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php', - 'Psr\\Container\\NotFoundExceptionInterface' => $vendorDir . '/psr/container/src/NotFoundExceptionInterface.php', - 'Psr\\Http\\Message\\MessageInterface' => $vendorDir . '/psr/http-message/src/MessageInterface.php', - 'Psr\\Http\\Message\\RequestInterface' => $vendorDir . '/psr/http-message/src/RequestInterface.php', - 'Psr\\Http\\Message\\ResponseInterface' => $vendorDir . '/psr/http-message/src/ResponseInterface.php', - 'Psr\\Http\\Message\\ServerRequestInterface' => $vendorDir . '/psr/http-message/src/ServerRequestInterface.php', - 'Psr\\Http\\Message\\StreamInterface' => $vendorDir . '/psr/http-message/src/StreamInterface.php', - 'Psr\\Http\\Message\\UploadedFileInterface' => $vendorDir . '/psr/http-message/src/UploadedFileInterface.php', - 'Psr\\Http\\Message\\UriInterface' => $vendorDir . '/psr/http-message/src/UriInterface.php', - 'React\\Cache\\ArrayCache' => $vendorDir . '/react/cache/src/ArrayCache.php', - 'React\\Cache\\CacheInterface' => $vendorDir . '/react/cache/src/CacheInterface.php', - 'React\\Dns\\BadServerException' => $vendorDir . '/react/dns/src/BadServerException.php', - 'React\\Dns\\Config\\Config' => $vendorDir . '/react/dns/src/Config/Config.php', - 'React\\Dns\\Config\\HostsFile' => $vendorDir . '/react/dns/src/Config/HostsFile.php', - 'React\\Dns\\Model\\Message' => $vendorDir . '/react/dns/src/Model/Message.php', - 'React\\Dns\\Model\\Record' => $vendorDir . '/react/dns/src/Model/Record.php', - 'React\\Dns\\Protocol\\BinaryDumper' => $vendorDir . '/react/dns/src/Protocol/BinaryDumper.php', - 'React\\Dns\\Protocol\\Parser' => $vendorDir . '/react/dns/src/Protocol/Parser.php', - 'React\\Dns\\Query\\CachingExecutor' => $vendorDir . '/react/dns/src/Query/CachingExecutor.php', - 'React\\Dns\\Query\\CancellationException' => $vendorDir . '/react/dns/src/Query/CancellationException.php', - 'React\\Dns\\Query\\CoopExecutor' => $vendorDir . '/react/dns/src/Query/CoopExecutor.php', - 'React\\Dns\\Query\\ExecutorInterface' => $vendorDir . '/react/dns/src/Query/ExecutorInterface.php', - 'React\\Dns\\Query\\FallbackExecutor' => $vendorDir . '/react/dns/src/Query/FallbackExecutor.php', - 'React\\Dns\\Query\\HostsFileExecutor' => $vendorDir . '/react/dns/src/Query/HostsFileExecutor.php', - 'React\\Dns\\Query\\Query' => $vendorDir . '/react/dns/src/Query/Query.php', - 'React\\Dns\\Query\\RetryExecutor' => $vendorDir . '/react/dns/src/Query/RetryExecutor.php', - 'React\\Dns\\Query\\SelectiveTransportExecutor' => $vendorDir . '/react/dns/src/Query/SelectiveTransportExecutor.php', - 'React\\Dns\\Query\\TcpTransportExecutor' => $vendorDir . '/react/dns/src/Query/TcpTransportExecutor.php', - 'React\\Dns\\Query\\TimeoutException' => $vendorDir . '/react/dns/src/Query/TimeoutException.php', - 'React\\Dns\\Query\\TimeoutExecutor' => $vendorDir . '/react/dns/src/Query/TimeoutExecutor.php', - 'React\\Dns\\Query\\UdpTransportExecutor' => $vendorDir . '/react/dns/src/Query/UdpTransportExecutor.php', - 'React\\Dns\\RecordNotFoundException' => $vendorDir . '/react/dns/src/RecordNotFoundException.php', - 'React\\Dns\\Resolver\\Factory' => $vendorDir . '/react/dns/src/Resolver/Factory.php', - 'React\\Dns\\Resolver\\Resolver' => $vendorDir . '/react/dns/src/Resolver/Resolver.php', - 'React\\Dns\\Resolver\\ResolverInterface' => $vendorDir . '/react/dns/src/Resolver/ResolverInterface.php', - 'React\\EventLoop\\ExtEvLoop' => $vendorDir . '/react/event-loop/src/ExtEvLoop.php', - 'React\\EventLoop\\ExtEventLoop' => $vendorDir . '/react/event-loop/src/ExtEventLoop.php', - 'React\\EventLoop\\ExtLibevLoop' => $vendorDir . '/react/event-loop/src/ExtLibevLoop.php', - 'React\\EventLoop\\ExtLibeventLoop' => $vendorDir . '/react/event-loop/src/ExtLibeventLoop.php', - 'React\\EventLoop\\ExtUvLoop' => $vendorDir . '/react/event-loop/src/ExtUvLoop.php', - 'React\\EventLoop\\Factory' => $vendorDir . '/react/event-loop/src/Factory.php', - 'React\\EventLoop\\Loop' => $vendorDir . '/react/event-loop/src/Loop.php', - 'React\\EventLoop\\LoopInterface' => $vendorDir . '/react/event-loop/src/LoopInterface.php', - 'React\\EventLoop\\SignalsHandler' => $vendorDir . '/react/event-loop/src/SignalsHandler.php', - 'React\\EventLoop\\StreamSelectLoop' => $vendorDir . '/react/event-loop/src/StreamSelectLoop.php', - 'React\\EventLoop\\Tick\\FutureTickQueue' => $vendorDir . '/react/event-loop/src/Tick/FutureTickQueue.php', - 'React\\EventLoop\\TimerInterface' => $vendorDir . '/react/event-loop/src/TimerInterface.php', - 'React\\EventLoop\\Timer\\Timer' => $vendorDir . '/react/event-loop/src/Timer/Timer.php', - 'React\\EventLoop\\Timer\\Timers' => $vendorDir . '/react/event-loop/src/Timer/Timers.php', - 'React\\Http\\Browser' => $vendorDir . '/react/http/src/Browser.php', - 'React\\Http\\Client\\Client' => $vendorDir . '/react/http/src/Client/Client.php', - 'React\\Http\\Client\\Request' => $vendorDir . '/react/http/src/Client/Request.php', - 'React\\Http\\Client\\RequestData' => $vendorDir . '/react/http/src/Client/RequestData.php', - 'React\\Http\\HttpServer' => $vendorDir . '/react/http/src/HttpServer.php', - 'React\\Http\\Io\\BufferedBody' => $vendorDir . '/react/http/src/Io/BufferedBody.php', - 'React\\Http\\Io\\ChunkedDecoder' => $vendorDir . '/react/http/src/Io/ChunkedDecoder.php', - 'React\\Http\\Io\\ChunkedEncoder' => $vendorDir . '/react/http/src/Io/ChunkedEncoder.php', - 'React\\Http\\Io\\CloseProtectionStream' => $vendorDir . '/react/http/src/Io/CloseProtectionStream.php', - 'React\\Http\\Io\\EmptyBodyStream' => $vendorDir . '/react/http/src/Io/EmptyBodyStream.php', - 'React\\Http\\Io\\HttpBodyStream' => $vendorDir . '/react/http/src/Io/HttpBodyStream.php', - 'React\\Http\\Io\\IniUtil' => $vendorDir . '/react/http/src/Io/IniUtil.php', - 'React\\Http\\Io\\LengthLimitedStream' => $vendorDir . '/react/http/src/Io/LengthLimitedStream.php', - 'React\\Http\\Io\\MiddlewareRunner' => $vendorDir . '/react/http/src/Io/MiddlewareRunner.php', - 'React\\Http\\Io\\MultipartParser' => $vendorDir . '/react/http/src/Io/MultipartParser.php', - 'React\\Http\\Io\\PauseBufferStream' => $vendorDir . '/react/http/src/Io/PauseBufferStream.php', - 'React\\Http\\Io\\ReadableBodyStream' => $vendorDir . '/react/http/src/Io/ReadableBodyStream.php', - 'React\\Http\\Io\\RequestHeaderParser' => $vendorDir . '/react/http/src/Io/RequestHeaderParser.php', - 'React\\Http\\Io\\Sender' => $vendorDir . '/react/http/src/Io/Sender.php', - 'React\\Http\\Io\\StreamingServer' => $vendorDir . '/react/http/src/Io/StreamingServer.php', - 'React\\Http\\Io\\Transaction' => $vendorDir . '/react/http/src/Io/Transaction.php', - 'React\\Http\\Io\\UploadedFile' => $vendorDir . '/react/http/src/Io/UploadedFile.php', - 'React\\Http\\Message\\Response' => $vendorDir . '/react/http/src/Message/Response.php', - 'React\\Http\\Message\\ResponseException' => $vendorDir . '/react/http/src/Message/ResponseException.php', - 'React\\Http\\Message\\ServerRequest' => $vendorDir . '/react/http/src/Message/ServerRequest.php', - 'React\\Http\\Middleware\\LimitConcurrentRequestsMiddleware' => $vendorDir . '/react/http/src/Middleware/LimitConcurrentRequestsMiddleware.php', - 'React\\Http\\Middleware\\RequestBodyBufferMiddleware' => $vendorDir . '/react/http/src/Middleware/RequestBodyBufferMiddleware.php', - 'React\\Http\\Middleware\\RequestBodyParserMiddleware' => $vendorDir . '/react/http/src/Middleware/RequestBodyParserMiddleware.php', - 'React\\Http\\Middleware\\StreamingRequestMiddleware' => $vendorDir . '/react/http/src/Middleware/StreamingRequestMiddleware.php', - 'React\\Http\\Server' => $vendorDir . '/react/http/src/Server.php', - 'React\\Promise\\CancellablePromiseInterface' => $vendorDir . '/react/promise/src/CancellablePromiseInterface.php', - 'React\\Promise\\CancellationQueue' => $vendorDir . '/react/promise/src/CancellationQueue.php', - 'React\\Promise\\Deferred' => $vendorDir . '/react/promise/src/Deferred.php', - 'React\\Promise\\Exception\\LengthException' => $vendorDir . '/react/promise/src/Exception/LengthException.php', - 'React\\Promise\\ExtendedPromiseInterface' => $vendorDir . '/react/promise/src/ExtendedPromiseInterface.php', - 'React\\Promise\\FulfilledPromise' => $vendorDir . '/react/promise/src/FulfilledPromise.php', - 'React\\Promise\\LazyPromise' => $vendorDir . '/react/promise/src/LazyPromise.php', - 'React\\Promise\\Promise' => $vendorDir . '/react/promise/src/Promise.php', - 'React\\Promise\\PromiseInterface' => $vendorDir . '/react/promise/src/PromiseInterface.php', - 'React\\Promise\\PromisorInterface' => $vendorDir . '/react/promise/src/PromisorInterface.php', - 'React\\Promise\\RejectedPromise' => $vendorDir . '/react/promise/src/RejectedPromise.php', - 'React\\Promise\\Stream\\UnwrapReadableStream' => $vendorDir . '/react/promise-stream/src/UnwrapReadableStream.php', - 'React\\Promise\\Stream\\UnwrapWritableStream' => $vendorDir . '/react/promise-stream/src/UnwrapWritableStream.php', - 'React\\Promise\\Timer\\TimeoutException' => $vendorDir . '/react/promise-timer/src/TimeoutException.php', - 'React\\Promise\\UnhandledRejectionException' => $vendorDir . '/react/promise/src/UnhandledRejectionException.php', - 'React\\Socket\\Connection' => $vendorDir . '/react/socket/src/Connection.php', - 'React\\Socket\\ConnectionInterface' => $vendorDir . '/react/socket/src/ConnectionInterface.php', - 'React\\Socket\\Connector' => $vendorDir . '/react/socket/src/Connector.php', - 'React\\Socket\\ConnectorInterface' => $vendorDir . '/react/socket/src/ConnectorInterface.php', - 'React\\Socket\\DnsConnector' => $vendorDir . '/react/socket/src/DnsConnector.php', - 'React\\Socket\\FdServer' => $vendorDir . '/react/socket/src/FdServer.php', - 'React\\Socket\\FixedUriConnector' => $vendorDir . '/react/socket/src/FixedUriConnector.php', - 'React\\Socket\\HappyEyeBallsConnectionBuilder' => $vendorDir . '/react/socket/src/HappyEyeBallsConnectionBuilder.php', - 'React\\Socket\\HappyEyeBallsConnector' => $vendorDir . '/react/socket/src/HappyEyeBallsConnector.php', - 'React\\Socket\\LimitingServer' => $vendorDir . '/react/socket/src/LimitingServer.php', - 'React\\Socket\\SecureConnector' => $vendorDir . '/react/socket/src/SecureConnector.php', - 'React\\Socket\\SecureServer' => $vendorDir . '/react/socket/src/SecureServer.php', - 'React\\Socket\\Server' => $vendorDir . '/react/socket/src/Server.php', - 'React\\Socket\\ServerInterface' => $vendorDir . '/react/socket/src/ServerInterface.php', - 'React\\Socket\\SocketServer' => $vendorDir . '/react/socket/src/SocketServer.php', - 'React\\Socket\\StreamEncryption' => $vendorDir . '/react/socket/src/StreamEncryption.php', - 'React\\Socket\\TcpConnector' => $vendorDir . '/react/socket/src/TcpConnector.php', - 'React\\Socket\\TcpServer' => $vendorDir . '/react/socket/src/TcpServer.php', - 'React\\Socket\\TimeoutConnector' => $vendorDir . '/react/socket/src/TimeoutConnector.php', - 'React\\Socket\\UnixConnector' => $vendorDir . '/react/socket/src/UnixConnector.php', - 'React\\Socket\\UnixServer' => $vendorDir . '/react/socket/src/UnixServer.php', - 'React\\Stream\\CompositeStream' => $vendorDir . '/react/stream/src/CompositeStream.php', - 'React\\Stream\\DuplexResourceStream' => $vendorDir . '/react/stream/src/DuplexResourceStream.php', - 'React\\Stream\\DuplexStreamInterface' => $vendorDir . '/react/stream/src/DuplexStreamInterface.php', - 'React\\Stream\\ReadableResourceStream' => $vendorDir . '/react/stream/src/ReadableResourceStream.php', - 'React\\Stream\\ReadableStreamInterface' => $vendorDir . '/react/stream/src/ReadableStreamInterface.php', - 'React\\Stream\\ThroughStream' => $vendorDir . '/react/stream/src/ThroughStream.php', - 'React\\Stream\\Util' => $vendorDir . '/react/stream/src/Util.php', - 'React\\Stream\\WritableResourceStream' => $vendorDir . '/react/stream/src/WritableResourceStream.php', - 'React\\Stream\\WritableStreamInterface' => $vendorDir . '/react/stream/src/WritableStreamInterface.php', - 'RingCentral\\Psr7\\AppendStream' => $vendorDir . '/ringcentral/psr7/src/AppendStream.php', - 'RingCentral\\Psr7\\BufferStream' => $vendorDir . '/ringcentral/psr7/src/BufferStream.php', - 'RingCentral\\Psr7\\CachingStream' => $vendorDir . '/ringcentral/psr7/src/CachingStream.php', - 'RingCentral\\Psr7\\DroppingStream' => $vendorDir . '/ringcentral/psr7/src/DroppingStream.php', - 'RingCentral\\Psr7\\FnStream' => $vendorDir . '/ringcentral/psr7/src/FnStream.php', - 'RingCentral\\Psr7\\InflateStream' => $vendorDir . '/ringcentral/psr7/src/InflateStream.php', - 'RingCentral\\Psr7\\LazyOpenStream' => $vendorDir . '/ringcentral/psr7/src/LazyOpenStream.php', - 'RingCentral\\Psr7\\LimitStream' => $vendorDir . '/ringcentral/psr7/src/LimitStream.php', - 'RingCentral\\Psr7\\MessageTrait' => $vendorDir . '/ringcentral/psr7/src/MessageTrait.php', - 'RingCentral\\Psr7\\MultipartStream' => $vendorDir . '/ringcentral/psr7/src/MultipartStream.php', - 'RingCentral\\Psr7\\NoSeekStream' => $vendorDir . '/ringcentral/psr7/src/NoSeekStream.php', - 'RingCentral\\Psr7\\PumpStream' => $vendorDir . '/ringcentral/psr7/src/PumpStream.php', - 'RingCentral\\Psr7\\Request' => $vendorDir . '/ringcentral/psr7/src/Request.php', - 'RingCentral\\Psr7\\Response' => $vendorDir . '/ringcentral/psr7/src/Response.php', - 'RingCentral\\Psr7\\ServerRequest' => $vendorDir . '/ringcentral/psr7/src/ServerRequest.php', - 'RingCentral\\Psr7\\Stream' => $vendorDir . '/ringcentral/psr7/src/Stream.php', - 'RingCentral\\Psr7\\StreamDecoratorTrait' => $vendorDir . '/ringcentral/psr7/src/StreamDecoratorTrait.php', - 'RingCentral\\Psr7\\StreamWrapper' => $vendorDir . '/ringcentral/psr7/src/StreamWrapper.php', - 'RingCentral\\Psr7\\Uri' => $vendorDir . '/ringcentral/psr7/src/Uri.php', - 'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', - 'Symfony\\Component\\Console\\Application' => $vendorDir . '/symfony/console/Application.php', - 'Symfony\\Component\\Console\\Attribute\\AsCommand' => $vendorDir . '/symfony/console/Attribute/AsCommand.php', - 'Symfony\\Component\\Console\\CI\\GithubActionReporter' => $vendorDir . '/symfony/console/CI/GithubActionReporter.php', - 'Symfony\\Component\\Console\\Color' => $vendorDir . '/symfony/console/Color.php', - 'Symfony\\Component\\Console\\CommandLoader\\CommandLoaderInterface' => $vendorDir . '/symfony/console/CommandLoader/CommandLoaderInterface.php', - 'Symfony\\Component\\Console\\CommandLoader\\ContainerCommandLoader' => $vendorDir . '/symfony/console/CommandLoader/ContainerCommandLoader.php', - 'Symfony\\Component\\Console\\CommandLoader\\FactoryCommandLoader' => $vendorDir . '/symfony/console/CommandLoader/FactoryCommandLoader.php', - 'Symfony\\Component\\Console\\Command\\Command' => $vendorDir . '/symfony/console/Command/Command.php', - 'Symfony\\Component\\Console\\Command\\CompleteCommand' => $vendorDir . '/symfony/console/Command/CompleteCommand.php', - 'Symfony\\Component\\Console\\Command\\DumpCompletionCommand' => $vendorDir . '/symfony/console/Command/DumpCompletionCommand.php', - 'Symfony\\Component\\Console\\Command\\HelpCommand' => $vendorDir . '/symfony/console/Command/HelpCommand.php', - 'Symfony\\Component\\Console\\Command\\LazyCommand' => $vendorDir . '/symfony/console/Command/LazyCommand.php', - 'Symfony\\Component\\Console\\Command\\ListCommand' => $vendorDir . '/symfony/console/Command/ListCommand.php', - 'Symfony\\Component\\Console\\Command\\LockableTrait' => $vendorDir . '/symfony/console/Command/LockableTrait.php', - 'Symfony\\Component\\Console\\Command\\SignalableCommandInterface' => $vendorDir . '/symfony/console/Command/SignalableCommandInterface.php', - 'Symfony\\Component\\Console\\Completion\\CompletionInput' => $vendorDir . '/symfony/console/Completion/CompletionInput.php', - 'Symfony\\Component\\Console\\Completion\\CompletionSuggestions' => $vendorDir . '/symfony/console/Completion/CompletionSuggestions.php', - 'Symfony\\Component\\Console\\Completion\\Output\\BashCompletionOutput' => $vendorDir . '/symfony/console/Completion/Output/BashCompletionOutput.php', - 'Symfony\\Component\\Console\\Completion\\Output\\CompletionOutputInterface' => $vendorDir . '/symfony/console/Completion/Output/CompletionOutputInterface.php', - 'Symfony\\Component\\Console\\Completion\\Suggestion' => $vendorDir . '/symfony/console/Completion/Suggestion.php', - 'Symfony\\Component\\Console\\ConsoleEvents' => $vendorDir . '/symfony/console/ConsoleEvents.php', - 'Symfony\\Component\\Console\\Cursor' => $vendorDir . '/symfony/console/Cursor.php', - 'Symfony\\Component\\Console\\DependencyInjection\\AddConsoleCommandPass' => $vendorDir . '/symfony/console/DependencyInjection/AddConsoleCommandPass.php', - 'Symfony\\Component\\Console\\Descriptor\\ApplicationDescription' => $vendorDir . '/symfony/console/Descriptor/ApplicationDescription.php', - 'Symfony\\Component\\Console\\Descriptor\\Descriptor' => $vendorDir . '/symfony/console/Descriptor/Descriptor.php', - 'Symfony\\Component\\Console\\Descriptor\\DescriptorInterface' => $vendorDir . '/symfony/console/Descriptor/DescriptorInterface.php', - 'Symfony\\Component\\Console\\Descriptor\\JsonDescriptor' => $vendorDir . '/symfony/console/Descriptor/JsonDescriptor.php', - 'Symfony\\Component\\Console\\Descriptor\\MarkdownDescriptor' => $vendorDir . '/symfony/console/Descriptor/MarkdownDescriptor.php', - 'Symfony\\Component\\Console\\Descriptor\\TextDescriptor' => $vendorDir . '/symfony/console/Descriptor/TextDescriptor.php', - 'Symfony\\Component\\Console\\Descriptor\\XmlDescriptor' => $vendorDir . '/symfony/console/Descriptor/XmlDescriptor.php', - 'Symfony\\Component\\Console\\EventListener\\ErrorListener' => $vendorDir . '/symfony/console/EventListener/ErrorListener.php', - 'Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => $vendorDir . '/symfony/console/Event/ConsoleCommandEvent.php', - 'Symfony\\Component\\Console\\Event\\ConsoleErrorEvent' => $vendorDir . '/symfony/console/Event/ConsoleErrorEvent.php', - 'Symfony\\Component\\Console\\Event\\ConsoleEvent' => $vendorDir . '/symfony/console/Event/ConsoleEvent.php', - 'Symfony\\Component\\Console\\Event\\ConsoleSignalEvent' => $vendorDir . '/symfony/console/Event/ConsoleSignalEvent.php', - 'Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => $vendorDir . '/symfony/console/Event/ConsoleTerminateEvent.php', - 'Symfony\\Component\\Console\\Exception\\CommandNotFoundException' => $vendorDir . '/symfony/console/Exception/CommandNotFoundException.php', - 'Symfony\\Component\\Console\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/console/Exception/ExceptionInterface.php', - 'Symfony\\Component\\Console\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/console/Exception/InvalidArgumentException.php', - 'Symfony\\Component\\Console\\Exception\\InvalidOptionException' => $vendorDir . '/symfony/console/Exception/InvalidOptionException.php', - 'Symfony\\Component\\Console\\Exception\\LogicException' => $vendorDir . '/symfony/console/Exception/LogicException.php', - 'Symfony\\Component\\Console\\Exception\\MissingInputException' => $vendorDir . '/symfony/console/Exception/MissingInputException.php', - 'Symfony\\Component\\Console\\Exception\\NamespaceNotFoundException' => $vendorDir . '/symfony/console/Exception/NamespaceNotFoundException.php', - 'Symfony\\Component\\Console\\Exception\\RuntimeException' => $vendorDir . '/symfony/console/Exception/RuntimeException.php', - 'Symfony\\Component\\Console\\Formatter\\NullOutputFormatter' => $vendorDir . '/symfony/console/Formatter/NullOutputFormatter.php', - 'Symfony\\Component\\Console\\Formatter\\NullOutputFormatterStyle' => $vendorDir . '/symfony/console/Formatter/NullOutputFormatterStyle.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatter' => $vendorDir . '/symfony/console/Formatter/OutputFormatter.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterInterface.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyle.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleInterface.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleStack.php', - 'Symfony\\Component\\Console\\Formatter\\WrappableOutputFormatterInterface' => $vendorDir . '/symfony/console/Formatter/WrappableOutputFormatterInterface.php', - 'Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => $vendorDir . '/symfony/console/Helper/DebugFormatterHelper.php', - 'Symfony\\Component\\Console\\Helper\\DescriptorHelper' => $vendorDir . '/symfony/console/Helper/DescriptorHelper.php', - 'Symfony\\Component\\Console\\Helper\\Dumper' => $vendorDir . '/symfony/console/Helper/Dumper.php', - 'Symfony\\Component\\Console\\Helper\\FormatterHelper' => $vendorDir . '/symfony/console/Helper/FormatterHelper.php', - 'Symfony\\Component\\Console\\Helper\\Helper' => $vendorDir . '/symfony/console/Helper/Helper.php', - 'Symfony\\Component\\Console\\Helper\\HelperInterface' => $vendorDir . '/symfony/console/Helper/HelperInterface.php', - 'Symfony\\Component\\Console\\Helper\\HelperSet' => $vendorDir . '/symfony/console/Helper/HelperSet.php', - 'Symfony\\Component\\Console\\Helper\\InputAwareHelper' => $vendorDir . '/symfony/console/Helper/InputAwareHelper.php', - 'Symfony\\Component\\Console\\Helper\\ProcessHelper' => $vendorDir . '/symfony/console/Helper/ProcessHelper.php', - 'Symfony\\Component\\Console\\Helper\\ProgressBar' => $vendorDir . '/symfony/console/Helper/ProgressBar.php', - 'Symfony\\Component\\Console\\Helper\\ProgressIndicator' => $vendorDir . '/symfony/console/Helper/ProgressIndicator.php', - 'Symfony\\Component\\Console\\Helper\\QuestionHelper' => $vendorDir . '/symfony/console/Helper/QuestionHelper.php', - 'Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => $vendorDir . '/symfony/console/Helper/SymfonyQuestionHelper.php', - 'Symfony\\Component\\Console\\Helper\\Table' => $vendorDir . '/symfony/console/Helper/Table.php', - 'Symfony\\Component\\Console\\Helper\\TableCell' => $vendorDir . '/symfony/console/Helper/TableCell.php', - 'Symfony\\Component\\Console\\Helper\\TableCellStyle' => $vendorDir . '/symfony/console/Helper/TableCellStyle.php', - 'Symfony\\Component\\Console\\Helper\\TableRows' => $vendorDir . '/symfony/console/Helper/TableRows.php', - 'Symfony\\Component\\Console\\Helper\\TableSeparator' => $vendorDir . '/symfony/console/Helper/TableSeparator.php', - 'Symfony\\Component\\Console\\Helper\\TableStyle' => $vendorDir . '/symfony/console/Helper/TableStyle.php', - 'Symfony\\Component\\Console\\Input\\ArgvInput' => $vendorDir . '/symfony/console/Input/ArgvInput.php', - 'Symfony\\Component\\Console\\Input\\ArrayInput' => $vendorDir . '/symfony/console/Input/ArrayInput.php', - 'Symfony\\Component\\Console\\Input\\Input' => $vendorDir . '/symfony/console/Input/Input.php', - 'Symfony\\Component\\Console\\Input\\InputArgument' => $vendorDir . '/symfony/console/Input/InputArgument.php', - 'Symfony\\Component\\Console\\Input\\InputAwareInterface' => $vendorDir . '/symfony/console/Input/InputAwareInterface.php', - 'Symfony\\Component\\Console\\Input\\InputDefinition' => $vendorDir . '/symfony/console/Input/InputDefinition.php', - 'Symfony\\Component\\Console\\Input\\InputInterface' => $vendorDir . '/symfony/console/Input/InputInterface.php', - 'Symfony\\Component\\Console\\Input\\InputOption' => $vendorDir . '/symfony/console/Input/InputOption.php', - 'Symfony\\Component\\Console\\Input\\StreamableInputInterface' => $vendorDir . '/symfony/console/Input/StreamableInputInterface.php', - 'Symfony\\Component\\Console\\Input\\StringInput' => $vendorDir . '/symfony/console/Input/StringInput.php', - 'Symfony\\Component\\Console\\Logger\\ConsoleLogger' => $vendorDir . '/symfony/console/Logger/ConsoleLogger.php', - 'Symfony\\Component\\Console\\Output\\BufferedOutput' => $vendorDir . '/symfony/console/Output/BufferedOutput.php', - 'Symfony\\Component\\Console\\Output\\ConsoleOutput' => $vendorDir . '/symfony/console/Output/ConsoleOutput.php', - 'Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => $vendorDir . '/symfony/console/Output/ConsoleOutputInterface.php', - 'Symfony\\Component\\Console\\Output\\ConsoleSectionOutput' => $vendorDir . '/symfony/console/Output/ConsoleSectionOutput.php', - 'Symfony\\Component\\Console\\Output\\NullOutput' => $vendorDir . '/symfony/console/Output/NullOutput.php', - 'Symfony\\Component\\Console\\Output\\Output' => $vendorDir . '/symfony/console/Output/Output.php', - 'Symfony\\Component\\Console\\Output\\OutputInterface' => $vendorDir . '/symfony/console/Output/OutputInterface.php', - 'Symfony\\Component\\Console\\Output\\StreamOutput' => $vendorDir . '/symfony/console/Output/StreamOutput.php', - 'Symfony\\Component\\Console\\Output\\TrimmedBufferOutput' => $vendorDir . '/symfony/console/Output/TrimmedBufferOutput.php', - 'Symfony\\Component\\Console\\Question\\ChoiceQuestion' => $vendorDir . '/symfony/console/Question/ChoiceQuestion.php', - 'Symfony\\Component\\Console\\Question\\ConfirmationQuestion' => $vendorDir . '/symfony/console/Question/ConfirmationQuestion.php', - 'Symfony\\Component\\Console\\Question\\Question' => $vendorDir . '/symfony/console/Question/Question.php', - 'Symfony\\Component\\Console\\SignalRegistry\\SignalRegistry' => $vendorDir . '/symfony/console/SignalRegistry/SignalRegistry.php', - 'Symfony\\Component\\Console\\SingleCommandApplication' => $vendorDir . '/symfony/console/SingleCommandApplication.php', - 'Symfony\\Component\\Console\\Style\\OutputStyle' => $vendorDir . '/symfony/console/Style/OutputStyle.php', - 'Symfony\\Component\\Console\\Style\\StyleInterface' => $vendorDir . '/symfony/console/Style/StyleInterface.php', - 'Symfony\\Component\\Console\\Style\\SymfonyStyle' => $vendorDir . '/symfony/console/Style/SymfonyStyle.php', - 'Symfony\\Component\\Console\\Terminal' => $vendorDir . '/symfony/console/Terminal.php', - 'Symfony\\Component\\Console\\Tester\\ApplicationTester' => $vendorDir . '/symfony/console/Tester/ApplicationTester.php', - 'Symfony\\Component\\Console\\Tester\\CommandCompletionTester' => $vendorDir . '/symfony/console/Tester/CommandCompletionTester.php', - 'Symfony\\Component\\Console\\Tester\\CommandTester' => $vendorDir . '/symfony/console/Tester/CommandTester.php', - 'Symfony\\Component\\Console\\Tester\\Constraint\\CommandIsSuccessful' => $vendorDir . '/symfony/console/Tester/Constraint/CommandIsSuccessful.php', - 'Symfony\\Component\\Console\\Tester\\TesterTrait' => $vendorDir . '/symfony/console/Tester/TesterTrait.php', - 'Symfony\\Component\\Process\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/process/Exception/ExceptionInterface.php', - 'Symfony\\Component\\Process\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/process/Exception/InvalidArgumentException.php', - 'Symfony\\Component\\Process\\Exception\\LogicException' => $vendorDir . '/symfony/process/Exception/LogicException.php', - 'Symfony\\Component\\Process\\Exception\\ProcessFailedException' => $vendorDir . '/symfony/process/Exception/ProcessFailedException.php', - 'Symfony\\Component\\Process\\Exception\\ProcessSignaledException' => $vendorDir . '/symfony/process/Exception/ProcessSignaledException.php', - 'Symfony\\Component\\Process\\Exception\\ProcessTimedOutException' => $vendorDir . '/symfony/process/Exception/ProcessTimedOutException.php', - 'Symfony\\Component\\Process\\Exception\\RuntimeException' => $vendorDir . '/symfony/process/Exception/RuntimeException.php', - 'Symfony\\Component\\Process\\ExecutableFinder' => $vendorDir . '/symfony/process/ExecutableFinder.php', - 'Symfony\\Component\\Process\\InputStream' => $vendorDir . '/symfony/process/InputStream.php', - 'Symfony\\Component\\Process\\PhpExecutableFinder' => $vendorDir . '/symfony/process/PhpExecutableFinder.php', - 'Symfony\\Component\\Process\\PhpProcess' => $vendorDir . '/symfony/process/PhpProcess.php', - 'Symfony\\Component\\Process\\Pipes\\AbstractPipes' => $vendorDir . '/symfony/process/Pipes/AbstractPipes.php', - 'Symfony\\Component\\Process\\Pipes\\PipesInterface' => $vendorDir . '/symfony/process/Pipes/PipesInterface.php', - 'Symfony\\Component\\Process\\Pipes\\UnixPipes' => $vendorDir . '/symfony/process/Pipes/UnixPipes.php', - 'Symfony\\Component\\Process\\Pipes\\WindowsPipes' => $vendorDir . '/symfony/process/Pipes/WindowsPipes.php', - 'Symfony\\Component\\Process\\Process' => $vendorDir . '/symfony/process/Process.php', - 'Symfony\\Component\\Process\\ProcessUtils' => $vendorDir . '/symfony/process/ProcessUtils.php', - 'Symfony\\Component\\String\\AbstractString' => $vendorDir . '/symfony/string/AbstractString.php', - 'Symfony\\Component\\String\\AbstractUnicodeString' => $vendorDir . '/symfony/string/AbstractUnicodeString.php', - 'Symfony\\Component\\String\\ByteString' => $vendorDir . '/symfony/string/ByteString.php', - 'Symfony\\Component\\String\\CodePointString' => $vendorDir . '/symfony/string/CodePointString.php', - 'Symfony\\Component\\String\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/string/Exception/ExceptionInterface.php', - 'Symfony\\Component\\String\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/string/Exception/InvalidArgumentException.php', - 'Symfony\\Component\\String\\Exception\\RuntimeException' => $vendorDir . '/symfony/string/Exception/RuntimeException.php', - 'Symfony\\Component\\String\\Inflector\\EnglishInflector' => $vendorDir . '/symfony/string/Inflector/EnglishInflector.php', - 'Symfony\\Component\\String\\Inflector\\FrenchInflector' => $vendorDir . '/symfony/string/Inflector/FrenchInflector.php', - 'Symfony\\Component\\String\\Inflector\\InflectorInterface' => $vendorDir . '/symfony/string/Inflector/InflectorInterface.php', - 'Symfony\\Component\\String\\LazyString' => $vendorDir . '/symfony/string/LazyString.php', - 'Symfony\\Component\\String\\Slugger\\AsciiSlugger' => $vendorDir . '/symfony/string/Slugger/AsciiSlugger.php', - 'Symfony\\Component\\String\\Slugger\\SluggerInterface' => $vendorDir . '/symfony/string/Slugger/SluggerInterface.php', - 'Symfony\\Component\\String\\UnicodeString' => $vendorDir . '/symfony/string/UnicodeString.php', - 'Symfony\\Component\\Yaml\\Command\\LintCommand' => $vendorDir . '/symfony/yaml/Command/LintCommand.php', - 'Symfony\\Component\\Yaml\\Dumper' => $vendorDir . '/symfony/yaml/Dumper.php', - 'Symfony\\Component\\Yaml\\Escaper' => $vendorDir . '/symfony/yaml/Escaper.php', - 'Symfony\\Component\\Yaml\\Exception\\DumpException' => $vendorDir . '/symfony/yaml/Exception/DumpException.php', - 'Symfony\\Component\\Yaml\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/yaml/Exception/ExceptionInterface.php', - 'Symfony\\Component\\Yaml\\Exception\\ParseException' => $vendorDir . '/symfony/yaml/Exception/ParseException.php', - 'Symfony\\Component\\Yaml\\Exception\\RuntimeException' => $vendorDir . '/symfony/yaml/Exception/RuntimeException.php', - 'Symfony\\Component\\Yaml\\Inline' => $vendorDir . '/symfony/yaml/Inline.php', - 'Symfony\\Component\\Yaml\\Parser' => $vendorDir . '/symfony/yaml/Parser.php', - 'Symfony\\Component\\Yaml\\Tag\\TaggedValue' => $vendorDir . '/symfony/yaml/Tag/TaggedValue.php', - 'Symfony\\Component\\Yaml\\Unescaper' => $vendorDir . '/symfony/yaml/Unescaper.php', - 'Symfony\\Component\\Yaml\\Yaml' => $vendorDir . '/symfony/yaml/Yaml.php', - 'Symfony\\Contracts\\Service\\Attribute\\Required' => $vendorDir . '/symfony/service-contracts/Attribute/Required.php', - 'Symfony\\Contracts\\Service\\Attribute\\SubscribedService' => $vendorDir . '/symfony/service-contracts/Attribute/SubscribedService.php', - 'Symfony\\Contracts\\Service\\ResetInterface' => $vendorDir . '/symfony/service-contracts/ResetInterface.php', - 'Symfony\\Contracts\\Service\\ServiceLocatorTrait' => $vendorDir . '/symfony/service-contracts/ServiceLocatorTrait.php', - 'Symfony\\Contracts\\Service\\ServiceProviderInterface' => $vendorDir . '/symfony/service-contracts/ServiceProviderInterface.php', - 'Symfony\\Contracts\\Service\\ServiceSubscriberInterface' => $vendorDir . '/symfony/service-contracts/ServiceSubscriberInterface.php', - 'Symfony\\Contracts\\Service\\ServiceSubscriberTrait' => $vendorDir . '/symfony/service-contracts/ServiceSubscriberTrait.php', - 'Symfony\\Contracts\\Service\\Test\\ServiceLocatorTest' => $vendorDir . '/symfony/service-contracts/Test/ServiceLocatorTest.php', - 'Symfony\\Polyfill\\Ctype\\Ctype' => $vendorDir . '/symfony/polyfill-ctype/Ctype.php', - 'Symfony\\Polyfill\\Intl\\Grapheme\\Grapheme' => $vendorDir . '/symfony/polyfill-intl-grapheme/Grapheme.php', - 'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Normalizer.php', - 'Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php', - 'Symfony\\Polyfill\\Php73\\Php73' => $vendorDir . '/symfony/polyfill-php73/Php73.php', - 'Symfony\\Polyfill\\Php80\\Php80' => $vendorDir . '/symfony/polyfill-php80/Php80.php', - 'Symfony\\Polyfill\\Php80\\PhpToken' => $vendorDir . '/symfony/polyfill-php80/PhpToken.php', - 'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', - 'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', -); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php deleted file mode 100644 index 1e5a2dd2e..000000000 --- a/vendor/composer/autoload_files.php +++ /dev/null @@ -1,23 +0,0 @@ - $vendorDir . '/react/promise/src/functions_include.php', - '972fda704d680a3a53c68e34e193cb22' => $vendorDir . '/react/promise-timer/src/functions_include.php', - 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', - '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', - '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', - 'cea474b4340aa9fa53661e887a21a316' => $vendorDir . '/react/promise-stream/src/functions_include.php', - '8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php', - 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', - '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php', - 'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php', - 'ebf8799635f67b5d7248946fe2154f4a' => $vendorDir . '/ringcentral/psr7/src/functions_include.php', - 'eee1afd8f38c52a8d46f7c5bbb92afdd' => $baseDir . '/src/Support/helpers.php', - '135133ad0ca20ef21cc262b30da9a000' => $baseDir . '/src/functions.php', -); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php deleted file mode 100644 index 02066fb2d..000000000 --- a/vendor/composer/autoload_namespaces.php +++ /dev/null @@ -1,10 +0,0 @@ - array($vendorDir . '/evenement/evenement/src'), -); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php deleted file mode 100644 index ba3b57b83..000000000 --- a/vendor/composer/autoload_psr4.php +++ /dev/null @@ -1,35 +0,0 @@ - array($vendorDir . '/symfony/polyfill-php80'), - 'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'), - 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), - 'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'), - 'Symfony\\Polyfill\\Intl\\Grapheme\\' => array($vendorDir . '/symfony/polyfill-intl-grapheme'), - 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), - 'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'), - 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'), - 'Symfony\\Component\\String\\' => array($vendorDir . '/symfony/string'), - 'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'), - 'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'), - 'RingCentral\\Psr7\\' => array($vendorDir . '/ringcentral/psr7/src'), - 'React\\Stream\\' => array($vendorDir . '/react/stream/src'), - 'React\\Socket\\' => array($vendorDir . '/react/socket/src'), - 'React\\Promise\\Timer\\' => array($vendorDir . '/react/promise-timer/src'), - 'React\\Promise\\Stream\\' => array($vendorDir . '/react/promise-stream/src'), - 'React\\Promise\\' => array($vendorDir . '/react/promise/src'), - 'React\\Http\\' => array($vendorDir . '/react/http/src'), - 'React\\EventLoop\\' => array($vendorDir . '/react/event-loop/src'), - 'React\\Dns\\' => array($vendorDir . '/react/dns/src'), - 'React\\Cache\\' => array($vendorDir . '/react/cache/src'), - 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'), - 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), - 'JsonSchema\\' => array($vendorDir . '/justinrainbow/json-schema/src/JsonSchema'), - 'Fig\\Http\\Message\\' => array($vendorDir . '/fig/http-message-util/src'), - 'Deployer\\' => array($baseDir . '/src'), -); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php deleted file mode 100644 index 333f19f9e..000000000 --- a/vendor/composer/autoload_real.php +++ /dev/null @@ -1,75 +0,0 @@ -= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require __DIR__ . '/autoload_static.php'; - - call_user_func(\Composer\Autoload\ComposerStaticInit234e1a4a29689e00066666da06e8ece1::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } - - $loader->register(true); - - if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit234e1a4a29689e00066666da06e8ece1::$files; - } else { - $includeFiles = require __DIR__ . '/autoload_files.php'; - } - foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire234e1a4a29689e00066666da06e8ece1($fileIdentifier, $file); - } - - return $loader; - } -} - -function composerRequire234e1a4a29689e00066666da06e8ece1($fileIdentifier, $file) -{ - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - require $file; - - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - } -} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php deleted file mode 100644 index 37c859b09..000000000 --- a/vendor/composer/autoload_static.php +++ /dev/null @@ -1,645 +0,0 @@ - __DIR__ . '/..' . '/react/promise/src/functions_include.php', - '972fda704d680a3a53c68e34e193cb22' => __DIR__ . '/..' . '/react/promise-timer/src/functions_include.php', - 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', - '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', - '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', - 'cea474b4340aa9fa53661e887a21a316' => __DIR__ . '/..' . '/react/promise-stream/src/functions_include.php', - '8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php', - 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', - '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php', - 'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php', - 'ebf8799635f67b5d7248946fe2154f4a' => __DIR__ . '/..' . '/ringcentral/psr7/src/functions_include.php', - 'eee1afd8f38c52a8d46f7c5bbb92afdd' => __DIR__ . '/../..' . '/src/Support/helpers.php', - '135133ad0ca20ef21cc262b30da9a000' => __DIR__ . '/../..' . '/src/functions.php', - ); - - public static $prefixLengthsPsr4 = array ( - 'S' => - array ( - 'Symfony\\Polyfill\\Php80\\' => 23, - 'Symfony\\Polyfill\\Php73\\' => 23, - 'Symfony\\Polyfill\\Mbstring\\' => 26, - 'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33, - 'Symfony\\Polyfill\\Intl\\Grapheme\\' => 31, - 'Symfony\\Polyfill\\Ctype\\' => 23, - 'Symfony\\Contracts\\Service\\' => 26, - 'Symfony\\Component\\Yaml\\' => 23, - 'Symfony\\Component\\String\\' => 25, - 'Symfony\\Component\\Process\\' => 26, - 'Symfony\\Component\\Console\\' => 26, - ), - 'R' => - array ( - 'RingCentral\\Psr7\\' => 17, - 'React\\Stream\\' => 13, - 'React\\Socket\\' => 13, - 'React\\Promise\\Timer\\' => 20, - 'React\\Promise\\Stream\\' => 21, - 'React\\Promise\\' => 14, - 'React\\Http\\' => 11, - 'React\\EventLoop\\' => 16, - 'React\\Dns\\' => 10, - 'React\\Cache\\' => 12, - ), - 'P' => - array ( - 'Psr\\Http\\Message\\' => 17, - 'Psr\\Container\\' => 14, - ), - 'J' => - array ( - 'JsonSchema\\' => 11, - ), - 'F' => - array ( - 'Fig\\Http\\Message\\' => 17, - ), - 'D' => - array ( - 'Deployer\\' => 9, - ), - ); - - public static $prefixDirsPsr4 = array ( - 'Symfony\\Polyfill\\Php80\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php80', - ), - 'Symfony\\Polyfill\\Php73\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php73', - ), - 'Symfony\\Polyfill\\Mbstring\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', - ), - 'Symfony\\Polyfill\\Intl\\Normalizer\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer', - ), - 'Symfony\\Polyfill\\Intl\\Grapheme\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme', - ), - 'Symfony\\Polyfill\\Ctype\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', - ), - 'Symfony\\Contracts\\Service\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/service-contracts', - ), - 'Symfony\\Component\\Yaml\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/yaml', - ), - 'Symfony\\Component\\String\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/string', - ), - 'Symfony\\Component\\Process\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/process', - ), - 'Symfony\\Component\\Console\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/console', - ), - 'RingCentral\\Psr7\\' => - array ( - 0 => __DIR__ . '/..' . '/ringcentral/psr7/src', - ), - 'React\\Stream\\' => - array ( - 0 => __DIR__ . '/..' . '/react/stream/src', - ), - 'React\\Socket\\' => - array ( - 0 => __DIR__ . '/..' . '/react/socket/src', - ), - 'React\\Promise\\Timer\\' => - array ( - 0 => __DIR__ . '/..' . '/react/promise-timer/src', - ), - 'React\\Promise\\Stream\\' => - array ( - 0 => __DIR__ . '/..' . '/react/promise-stream/src', - ), - 'React\\Promise\\' => - array ( - 0 => __DIR__ . '/..' . '/react/promise/src', - ), - 'React\\Http\\' => - array ( - 0 => __DIR__ . '/..' . '/react/http/src', - ), - 'React\\EventLoop\\' => - array ( - 0 => __DIR__ . '/..' . '/react/event-loop/src', - ), - 'React\\Dns\\' => - array ( - 0 => __DIR__ . '/..' . '/react/dns/src', - ), - 'React\\Cache\\' => - array ( - 0 => __DIR__ . '/..' . '/react/cache/src', - ), - 'Psr\\Http\\Message\\' => - array ( - 0 => __DIR__ . '/..' . '/psr/http-message/src', - ), - 'Psr\\Container\\' => - array ( - 0 => __DIR__ . '/..' . '/psr/container/src', - ), - 'JsonSchema\\' => - array ( - 0 => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema', - ), - 'Fig\\Http\\Message\\' => - array ( - 0 => __DIR__ . '/..' . '/fig/http-message-util/src', - ), - 'Deployer\\' => - array ( - 0 => __DIR__ . '/../..' . '/src', - ), - ); - - public static $prefixesPsr0 = array ( - 'E' => - array ( - 'Evenement' => - array ( - 0 => __DIR__ . '/..' . '/evenement/evenement/src', - ), - ), - ); - - public static $classMap = array ( - 'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', - 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', - 'Deployer\\Collection\\Collection' => __DIR__ . '/../..' . '/src/Collection/Collection.php', - 'Deployer\\Command\\BlackjackCommand' => __DIR__ . '/../..' . '/src/Command/BlackjackCommand.php', - 'Deployer\\Command\\CommandCommon' => __DIR__ . '/../..' . '/src/Command/CommandCommon.php', - 'Deployer\\Command\\ConfigCommand' => __DIR__ . '/../..' . '/src/Command/ConfigCommand.php', - 'Deployer\\Command\\CustomOption' => __DIR__ . '/../..' . '/src/Command/CustomOption.php', - 'Deployer\\Command\\InitCommand' => __DIR__ . '/../..' . '/src/Command/InitCommand.php', - 'Deployer\\Command\\MainCommand' => __DIR__ . '/../..' . '/src/Command/MainCommand.php', - 'Deployer\\Command\\RunCommand' => __DIR__ . '/../..' . '/src/Command/RunCommand.php', - 'Deployer\\Command\\SelectCommand' => __DIR__ . '/../..' . '/src/Command/SelectCommand.php', - 'Deployer\\Command\\SshCommand' => __DIR__ . '/../..' . '/src/Command/SshCommand.php', - 'Deployer\\Command\\TreeCommand' => __DIR__ . '/../..' . '/src/Command/TreeCommand.php', - 'Deployer\\Command\\WorkerCommand' => __DIR__ . '/../..' . '/src/Command/WorkerCommand.php', - 'Deployer\\Component\\PharUpdate\\Console\\Command' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Console/Command.php', - 'Deployer\\Component\\PharUpdate\\Console\\Helper' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Console/Helper.php', - 'Deployer\\Component\\PharUpdate\\Exception\\Exception' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Exception/Exception.php', - 'Deployer\\Component\\PharUpdate\\Exception\\ExceptionInterface' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Exception/ExceptionInterface.php', - 'Deployer\\Component\\PharUpdate\\Exception\\FileException' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Exception/FileException.php', - 'Deployer\\Component\\PharUpdate\\Exception\\InvalidArgumentException' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Exception/InvalidArgumentException.php', - 'Deployer\\Component\\PharUpdate\\Exception\\LogicException' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Exception/LogicException.php', - 'Deployer\\Component\\PharUpdate\\Manager' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Manager.php', - 'Deployer\\Component\\PharUpdate\\Manifest' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Manifest.php', - 'Deployer\\Component\\PharUpdate\\Update' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Update.php', - 'Deployer\\Component\\PharUpdate\\Version\\Builder' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Version/Builder.php', - 'Deployer\\Component\\PharUpdate\\Version\\Comparator' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Version/Comparator.php', - 'Deployer\\Component\\PharUpdate\\Version\\Dumper' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Version/Dumper.php', - 'Deployer\\Component\\PharUpdate\\Version\\Exception\\InvalidIdentifierException' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Version/Exception/InvalidIdentifierException.php', - 'Deployer\\Component\\PharUpdate\\Version\\Exception\\InvalidNumberException' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Version/Exception/InvalidNumberException.php', - 'Deployer\\Component\\PharUpdate\\Version\\Exception\\InvalidStringRepresentationException' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Version/Exception/InvalidStringRepresentationException.php', - 'Deployer\\Component\\PharUpdate\\Version\\Exception\\VersionException' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Version/Exception/VersionException.php', - 'Deployer\\Component\\PharUpdate\\Version\\Parser' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Version/Parser.php', - 'Deployer\\Component\\PharUpdate\\Version\\Validator' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Version/Validator.php', - 'Deployer\\Component\\PharUpdate\\Version\\Version' => __DIR__ . '/../..' . '/src/Component/PharUpdate/Version/Version.php', - 'Deployer\\Component\\Pimple\\Container' => __DIR__ . '/../..' . '/src/Component/Pimple/Container.php', - 'Deployer\\Component\\Pimple\\Exception\\ExpectedInvokableException' => __DIR__ . '/../..' . '/src/Component/Pimple/Exception/ExpectedInvokableException.php', - 'Deployer\\Component\\Pimple\\Exception\\FrozenServiceException' => __DIR__ . '/../..' . '/src/Component/Pimple/Exception/FrozenServiceException.php', - 'Deployer\\Component\\Pimple\\Exception\\InvalidServiceIdentifierException' => __DIR__ . '/../..' . '/src/Component/Pimple/Exception/InvalidServiceIdentifierException.php', - 'Deployer\\Component\\Pimple\\Exception\\UnknownIdentifierException' => __DIR__ . '/../..' . '/src/Component/Pimple/Exception/UnknownIdentifierException.php', - 'Deployer\\Component\\ProcessRunner\\Printer' => __DIR__ . '/../..' . '/src/Component/ProcessRunner/Printer.php', - 'Deployer\\Component\\ProcessRunner\\ProcessRunner' => __DIR__ . '/../..' . '/src/Component/ProcessRunner/ProcessRunner.php', - 'Deployer\\Component\\Ssh\\Client' => __DIR__ . '/../..' . '/src/Component/Ssh/Client.php', - 'Deployer\\Component\\Ssh\\IOArguments' => __DIR__ . '/../..' . '/src/Component/Ssh/IOArguments.php', - 'Deployer\\Configuration\\Configuration' => __DIR__ . '/../..' . '/src/Configuration/Configuration.php', - 'Deployer\\Deployer' => __DIR__ . '/../..' . '/src/Deployer.php', - 'Deployer\\Documentation\\ApiGen' => __DIR__ . '/../..' . '/src/Documentation/ApiGen.php', - 'Deployer\\Documentation\\DocConfig' => __DIR__ . '/../..' . '/src/Documentation/DocConfig.php', - 'Deployer\\Documentation\\DocGen' => __DIR__ . '/../..' . '/src/Documentation/DocGen.php', - 'Deployer\\Documentation\\DocRecipe' => __DIR__ . '/../..' . '/src/Documentation/DocRecipe.php', - 'Deployer\\Documentation\\DocTask' => __DIR__ . '/../..' . '/src/Documentation/DocTask.php', - 'Deployer\\Exception\\ConfigurationException' => __DIR__ . '/../..' . '/src/Exception/ConfigurationException.php', - 'Deployer\\Exception\\Exception' => __DIR__ . '/../..' . '/src/Exception/Exception.php', - 'Deployer\\Exception\\GracefulShutdownException' => __DIR__ . '/../..' . '/src/Exception/GracefulShutdownException.php', - 'Deployer\\Exception\\HttpieException' => __DIR__ . '/../..' . '/src/Exception/HttpieException.php', - 'Deployer\\Exception\\RunException' => __DIR__ . '/../..' . '/src/Exception/RunException.php', - 'Deployer\\Exception\\TimeoutException' => __DIR__ . '/../..' . '/src/Exception/TimeoutException.php', - 'Deployer\\Exception\\WillAskUser' => __DIR__ . '/../..' . '/src/Exception/WillAskUser.php', - 'Deployer\\Executor\\Master' => __DIR__ . '/../..' . '/src/Executor/Master.php', - 'Deployer\\Executor\\Messenger' => __DIR__ . '/../..' . '/src/Executor/Messenger.php', - 'Deployer\\Executor\\Planner' => __DIR__ . '/../..' . '/src/Executor/Planner.php', - 'Deployer\\Executor\\Server' => __DIR__ . '/../..' . '/src/Executor/Server.php', - 'Deployer\\Executor\\Worker' => __DIR__ . '/../..' . '/src/Executor/Worker.php', - 'Deployer\\Host\\Host' => __DIR__ . '/../..' . '/src/Host/Host.php', - 'Deployer\\Host\\HostCollection' => __DIR__ . '/../..' . '/src/Host/HostCollection.php', - 'Deployer\\Host\\Localhost' => __DIR__ . '/../..' . '/src/Host/Localhost.php', - 'Deployer\\Host\\Range' => __DIR__ . '/../..' . '/src/Host/Range.php', - 'Deployer\\Importer\\Importer' => __DIR__ . '/../..' . '/src/Importer/Importer.php', - 'Deployer\\Logger\\Handler\\FileHandler' => __DIR__ . '/../..' . '/src/Logger/Handler/FileHandler.php', - 'Deployer\\Logger\\Handler\\HandlerInterface' => __DIR__ . '/../..' . '/src/Logger/Handler/HandlerInterface.php', - 'Deployer\\Logger\\Handler\\NullHandler' => __DIR__ . '/../..' . '/src/Logger/Handler/NullHandler.php', - 'Deployer\\Logger\\Logger' => __DIR__ . '/../..' . '/src/Logger/Logger.php', - 'Deployer\\Selector\\Selector' => __DIR__ . '/../..' . '/src/Selector/Selector.php', - 'Deployer\\Support\\ObjectProxy' => __DIR__ . '/../..' . '/src/Support/ObjectProxy.php', - 'Deployer\\Support\\Reporter' => __DIR__ . '/../..' . '/src/Support/Reporter.php', - 'Deployer\\Task\\Context' => __DIR__ . '/../..' . '/src/Task/Context.php', - 'Deployer\\Task\\GroupTask' => __DIR__ . '/../..' . '/src/Task/GroupTask.php', - 'Deployer\\Task\\ScriptManager' => __DIR__ . '/../..' . '/src/Task/ScriptManager.php', - 'Deployer\\Task\\Task' => __DIR__ . '/../..' . '/src/Task/Task.php', - 'Deployer\\Task\\TaskCollection' => __DIR__ . '/../..' . '/src/Task/TaskCollection.php', - 'Deployer\\Utility\\Httpie' => __DIR__ . '/../..' . '/src/Utility/Httpie.php', - 'Deployer\\Utility\\Rsync' => __DIR__ . '/../..' . '/src/Utility/Rsync.php', - 'Evenement\\EventEmitter' => __DIR__ . '/..' . '/evenement/evenement/src/Evenement/EventEmitter.php', - 'Evenement\\EventEmitterInterface' => __DIR__ . '/..' . '/evenement/evenement/src/Evenement/EventEmitterInterface.php', - 'Evenement\\EventEmitterTrait' => __DIR__ . '/..' . '/evenement/evenement/src/Evenement/EventEmitterTrait.php', - 'Fig\\Http\\Message\\RequestMethodInterface' => __DIR__ . '/..' . '/fig/http-message-util/src/RequestMethodInterface.php', - 'Fig\\Http\\Message\\StatusCodeInterface' => __DIR__ . '/..' . '/fig/http-message-util/src/StatusCodeInterface.php', - 'JsonException' => __DIR__ . '/..' . '/symfony/polyfill-php73/Resources/stubs/JsonException.php', - 'JsonSchema\\Constraints\\BaseConstraint' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php', - 'JsonSchema\\Constraints\\CollectionConstraint' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php', - 'JsonSchema\\Constraints\\Constraint' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php', - 'JsonSchema\\Constraints\\ConstraintInterface' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php', - 'JsonSchema\\Constraints\\EnumConstraint' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php', - 'JsonSchema\\Constraints\\Factory' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php', - 'JsonSchema\\Constraints\\FormatConstraint' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php', - 'JsonSchema\\Constraints\\NumberConstraint' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php', - 'JsonSchema\\Constraints\\ObjectConstraint' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php', - 'JsonSchema\\Constraints\\SchemaConstraint' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php', - 'JsonSchema\\Constraints\\StringConstraint' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php', - 'JsonSchema\\Constraints\\TypeCheck\\LooseTypeCheck' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/LooseTypeCheck.php', - 'JsonSchema\\Constraints\\TypeCheck\\StrictTypeCheck' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/StrictTypeCheck.php', - 'JsonSchema\\Constraints\\TypeCheck\\TypeCheckInterface' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/TypeCheckInterface.php', - 'JsonSchema\\Constraints\\TypeConstraint' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php', - 'JsonSchema\\Constraints\\UndefinedConstraint' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php', - 'JsonSchema\\Entity\\JsonPointer' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Entity/JsonPointer.php', - 'JsonSchema\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Exception/ExceptionInterface.php', - 'JsonSchema\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.php', - 'JsonSchema\\Exception\\InvalidConfigException' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidConfigException.php', - 'JsonSchema\\Exception\\InvalidSchemaException' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaException.php', - 'JsonSchema\\Exception\\InvalidSchemaMediaTypeException' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.php', - 'JsonSchema\\Exception\\InvalidSourceUriException' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.php', - 'JsonSchema\\Exception\\JsonDecodingException' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php', - 'JsonSchema\\Exception\\ResourceNotFoundException' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.php', - 'JsonSchema\\Exception\\RuntimeException' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Exception/RuntimeException.php', - 'JsonSchema\\Exception\\UnresolvableJsonPointerException' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Exception/UnresolvableJsonPointerException.php', - 'JsonSchema\\Exception\\UriResolverException' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.php', - 'JsonSchema\\Exception\\ValidationException' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Exception/ValidationException.php', - 'JsonSchema\\Iterator\\ObjectIterator' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Iterator/ObjectIterator.php', - 'JsonSchema\\Rfc3339' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Rfc3339.php', - 'JsonSchema\\SchemaStorage' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/SchemaStorage.php', - 'JsonSchema\\SchemaStorageInterface' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/SchemaStorageInterface.php', - 'JsonSchema\\UriResolverInterface' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/UriResolverInterface.php', - 'JsonSchema\\UriRetrieverInterface' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/UriRetrieverInterface.php', - 'JsonSchema\\Uri\\Retrievers\\AbstractRetriever' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.php', - 'JsonSchema\\Uri\\Retrievers\\Curl' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php', - 'JsonSchema\\Uri\\Retrievers\\FileGetContents' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php', - 'JsonSchema\\Uri\\Retrievers\\PredefinedArray' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php', - 'JsonSchema\\Uri\\Retrievers\\UriRetrieverInterface' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php', - 'JsonSchema\\Uri\\UriResolver' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php', - 'JsonSchema\\Uri\\UriRetriever' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php', - 'JsonSchema\\Validator' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Validator.php', - 'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', - 'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', - 'Psr\\Container\\ContainerExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerExceptionInterface.php', - 'Psr\\Container\\ContainerInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerInterface.php', - 'Psr\\Container\\NotFoundExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/NotFoundExceptionInterface.php', - 'Psr\\Http\\Message\\MessageInterface' => __DIR__ . '/..' . '/psr/http-message/src/MessageInterface.php', - 'Psr\\Http\\Message\\RequestInterface' => __DIR__ . '/..' . '/psr/http-message/src/RequestInterface.php', - 'Psr\\Http\\Message\\ResponseInterface' => __DIR__ . '/..' . '/psr/http-message/src/ResponseInterface.php', - 'Psr\\Http\\Message\\ServerRequestInterface' => __DIR__ . '/..' . '/psr/http-message/src/ServerRequestInterface.php', - 'Psr\\Http\\Message\\StreamInterface' => __DIR__ . '/..' . '/psr/http-message/src/StreamInterface.php', - 'Psr\\Http\\Message\\UploadedFileInterface' => __DIR__ . '/..' . '/psr/http-message/src/UploadedFileInterface.php', - 'Psr\\Http\\Message\\UriInterface' => __DIR__ . '/..' . '/psr/http-message/src/UriInterface.php', - 'React\\Cache\\ArrayCache' => __DIR__ . '/..' . '/react/cache/src/ArrayCache.php', - 'React\\Cache\\CacheInterface' => __DIR__ . '/..' . '/react/cache/src/CacheInterface.php', - 'React\\Dns\\BadServerException' => __DIR__ . '/..' . '/react/dns/src/BadServerException.php', - 'React\\Dns\\Config\\Config' => __DIR__ . '/..' . '/react/dns/src/Config/Config.php', - 'React\\Dns\\Config\\HostsFile' => __DIR__ . '/..' . '/react/dns/src/Config/HostsFile.php', - 'React\\Dns\\Model\\Message' => __DIR__ . '/..' . '/react/dns/src/Model/Message.php', - 'React\\Dns\\Model\\Record' => __DIR__ . '/..' . '/react/dns/src/Model/Record.php', - 'React\\Dns\\Protocol\\BinaryDumper' => __DIR__ . '/..' . '/react/dns/src/Protocol/BinaryDumper.php', - 'React\\Dns\\Protocol\\Parser' => __DIR__ . '/..' . '/react/dns/src/Protocol/Parser.php', - 'React\\Dns\\Query\\CachingExecutor' => __DIR__ . '/..' . '/react/dns/src/Query/CachingExecutor.php', - 'React\\Dns\\Query\\CancellationException' => __DIR__ . '/..' . '/react/dns/src/Query/CancellationException.php', - 'React\\Dns\\Query\\CoopExecutor' => __DIR__ . '/..' . '/react/dns/src/Query/CoopExecutor.php', - 'React\\Dns\\Query\\ExecutorInterface' => __DIR__ . '/..' . '/react/dns/src/Query/ExecutorInterface.php', - 'React\\Dns\\Query\\FallbackExecutor' => __DIR__ . '/..' . '/react/dns/src/Query/FallbackExecutor.php', - 'React\\Dns\\Query\\HostsFileExecutor' => __DIR__ . '/..' . '/react/dns/src/Query/HostsFileExecutor.php', - 'React\\Dns\\Query\\Query' => __DIR__ . '/..' . '/react/dns/src/Query/Query.php', - 'React\\Dns\\Query\\RetryExecutor' => __DIR__ . '/..' . '/react/dns/src/Query/RetryExecutor.php', - 'React\\Dns\\Query\\SelectiveTransportExecutor' => __DIR__ . '/..' . '/react/dns/src/Query/SelectiveTransportExecutor.php', - 'React\\Dns\\Query\\TcpTransportExecutor' => __DIR__ . '/..' . '/react/dns/src/Query/TcpTransportExecutor.php', - 'React\\Dns\\Query\\TimeoutException' => __DIR__ . '/..' . '/react/dns/src/Query/TimeoutException.php', - 'React\\Dns\\Query\\TimeoutExecutor' => __DIR__ . '/..' . '/react/dns/src/Query/TimeoutExecutor.php', - 'React\\Dns\\Query\\UdpTransportExecutor' => __DIR__ . '/..' . '/react/dns/src/Query/UdpTransportExecutor.php', - 'React\\Dns\\RecordNotFoundException' => __DIR__ . '/..' . '/react/dns/src/RecordNotFoundException.php', - 'React\\Dns\\Resolver\\Factory' => __DIR__ . '/..' . '/react/dns/src/Resolver/Factory.php', - 'React\\Dns\\Resolver\\Resolver' => __DIR__ . '/..' . '/react/dns/src/Resolver/Resolver.php', - 'React\\Dns\\Resolver\\ResolverInterface' => __DIR__ . '/..' . '/react/dns/src/Resolver/ResolverInterface.php', - 'React\\EventLoop\\ExtEvLoop' => __DIR__ . '/..' . '/react/event-loop/src/ExtEvLoop.php', - 'React\\EventLoop\\ExtEventLoop' => __DIR__ . '/..' . '/react/event-loop/src/ExtEventLoop.php', - 'React\\EventLoop\\ExtLibevLoop' => __DIR__ . '/..' . '/react/event-loop/src/ExtLibevLoop.php', - 'React\\EventLoop\\ExtLibeventLoop' => __DIR__ . '/..' . '/react/event-loop/src/ExtLibeventLoop.php', - 'React\\EventLoop\\ExtUvLoop' => __DIR__ . '/..' . '/react/event-loop/src/ExtUvLoop.php', - 'React\\EventLoop\\Factory' => __DIR__ . '/..' . '/react/event-loop/src/Factory.php', - 'React\\EventLoop\\Loop' => __DIR__ . '/..' . '/react/event-loop/src/Loop.php', - 'React\\EventLoop\\LoopInterface' => __DIR__ . '/..' . '/react/event-loop/src/LoopInterface.php', - 'React\\EventLoop\\SignalsHandler' => __DIR__ . '/..' . '/react/event-loop/src/SignalsHandler.php', - 'React\\EventLoop\\StreamSelectLoop' => __DIR__ . '/..' . '/react/event-loop/src/StreamSelectLoop.php', - 'React\\EventLoop\\Tick\\FutureTickQueue' => __DIR__ . '/..' . '/react/event-loop/src/Tick/FutureTickQueue.php', - 'React\\EventLoop\\TimerInterface' => __DIR__ . '/..' . '/react/event-loop/src/TimerInterface.php', - 'React\\EventLoop\\Timer\\Timer' => __DIR__ . '/..' . '/react/event-loop/src/Timer/Timer.php', - 'React\\EventLoop\\Timer\\Timers' => __DIR__ . '/..' . '/react/event-loop/src/Timer/Timers.php', - 'React\\Http\\Browser' => __DIR__ . '/..' . '/react/http/src/Browser.php', - 'React\\Http\\Client\\Client' => __DIR__ . '/..' . '/react/http/src/Client/Client.php', - 'React\\Http\\Client\\Request' => __DIR__ . '/..' . '/react/http/src/Client/Request.php', - 'React\\Http\\Client\\RequestData' => __DIR__ . '/..' . '/react/http/src/Client/RequestData.php', - 'React\\Http\\HttpServer' => __DIR__ . '/..' . '/react/http/src/HttpServer.php', - 'React\\Http\\Io\\BufferedBody' => __DIR__ . '/..' . '/react/http/src/Io/BufferedBody.php', - 'React\\Http\\Io\\ChunkedDecoder' => __DIR__ . '/..' . '/react/http/src/Io/ChunkedDecoder.php', - 'React\\Http\\Io\\ChunkedEncoder' => __DIR__ . '/..' . '/react/http/src/Io/ChunkedEncoder.php', - 'React\\Http\\Io\\CloseProtectionStream' => __DIR__ . '/..' . '/react/http/src/Io/CloseProtectionStream.php', - 'React\\Http\\Io\\EmptyBodyStream' => __DIR__ . '/..' . '/react/http/src/Io/EmptyBodyStream.php', - 'React\\Http\\Io\\HttpBodyStream' => __DIR__ . '/..' . '/react/http/src/Io/HttpBodyStream.php', - 'React\\Http\\Io\\IniUtil' => __DIR__ . '/..' . '/react/http/src/Io/IniUtil.php', - 'React\\Http\\Io\\LengthLimitedStream' => __DIR__ . '/..' . '/react/http/src/Io/LengthLimitedStream.php', - 'React\\Http\\Io\\MiddlewareRunner' => __DIR__ . '/..' . '/react/http/src/Io/MiddlewareRunner.php', - 'React\\Http\\Io\\MultipartParser' => __DIR__ . '/..' . '/react/http/src/Io/MultipartParser.php', - 'React\\Http\\Io\\PauseBufferStream' => __DIR__ . '/..' . '/react/http/src/Io/PauseBufferStream.php', - 'React\\Http\\Io\\ReadableBodyStream' => __DIR__ . '/..' . '/react/http/src/Io/ReadableBodyStream.php', - 'React\\Http\\Io\\RequestHeaderParser' => __DIR__ . '/..' . '/react/http/src/Io/RequestHeaderParser.php', - 'React\\Http\\Io\\Sender' => __DIR__ . '/..' . '/react/http/src/Io/Sender.php', - 'React\\Http\\Io\\StreamingServer' => __DIR__ . '/..' . '/react/http/src/Io/StreamingServer.php', - 'React\\Http\\Io\\Transaction' => __DIR__ . '/..' . '/react/http/src/Io/Transaction.php', - 'React\\Http\\Io\\UploadedFile' => __DIR__ . '/..' . '/react/http/src/Io/UploadedFile.php', - 'React\\Http\\Message\\Response' => __DIR__ . '/..' . '/react/http/src/Message/Response.php', - 'React\\Http\\Message\\ResponseException' => __DIR__ . '/..' . '/react/http/src/Message/ResponseException.php', - 'React\\Http\\Message\\ServerRequest' => __DIR__ . '/..' . '/react/http/src/Message/ServerRequest.php', - 'React\\Http\\Middleware\\LimitConcurrentRequestsMiddleware' => __DIR__ . '/..' . '/react/http/src/Middleware/LimitConcurrentRequestsMiddleware.php', - 'React\\Http\\Middleware\\RequestBodyBufferMiddleware' => __DIR__ . '/..' . '/react/http/src/Middleware/RequestBodyBufferMiddleware.php', - 'React\\Http\\Middleware\\RequestBodyParserMiddleware' => __DIR__ . '/..' . '/react/http/src/Middleware/RequestBodyParserMiddleware.php', - 'React\\Http\\Middleware\\StreamingRequestMiddleware' => __DIR__ . '/..' . '/react/http/src/Middleware/StreamingRequestMiddleware.php', - 'React\\Http\\Server' => __DIR__ . '/..' . '/react/http/src/Server.php', - 'React\\Promise\\CancellablePromiseInterface' => __DIR__ . '/..' . '/react/promise/src/CancellablePromiseInterface.php', - 'React\\Promise\\CancellationQueue' => __DIR__ . '/..' . '/react/promise/src/CancellationQueue.php', - 'React\\Promise\\Deferred' => __DIR__ . '/..' . '/react/promise/src/Deferred.php', - 'React\\Promise\\Exception\\LengthException' => __DIR__ . '/..' . '/react/promise/src/Exception/LengthException.php', - 'React\\Promise\\ExtendedPromiseInterface' => __DIR__ . '/..' . '/react/promise/src/ExtendedPromiseInterface.php', - 'React\\Promise\\FulfilledPromise' => __DIR__ . '/..' . '/react/promise/src/FulfilledPromise.php', - 'React\\Promise\\LazyPromise' => __DIR__ . '/..' . '/react/promise/src/LazyPromise.php', - 'React\\Promise\\Promise' => __DIR__ . '/..' . '/react/promise/src/Promise.php', - 'React\\Promise\\PromiseInterface' => __DIR__ . '/..' . '/react/promise/src/PromiseInterface.php', - 'React\\Promise\\PromisorInterface' => __DIR__ . '/..' . '/react/promise/src/PromisorInterface.php', - 'React\\Promise\\RejectedPromise' => __DIR__ . '/..' . '/react/promise/src/RejectedPromise.php', - 'React\\Promise\\Stream\\UnwrapReadableStream' => __DIR__ . '/..' . '/react/promise-stream/src/UnwrapReadableStream.php', - 'React\\Promise\\Stream\\UnwrapWritableStream' => __DIR__ . '/..' . '/react/promise-stream/src/UnwrapWritableStream.php', - 'React\\Promise\\Timer\\TimeoutException' => __DIR__ . '/..' . '/react/promise-timer/src/TimeoutException.php', - 'React\\Promise\\UnhandledRejectionException' => __DIR__ . '/..' . '/react/promise/src/UnhandledRejectionException.php', - 'React\\Socket\\Connection' => __DIR__ . '/..' . '/react/socket/src/Connection.php', - 'React\\Socket\\ConnectionInterface' => __DIR__ . '/..' . '/react/socket/src/ConnectionInterface.php', - 'React\\Socket\\Connector' => __DIR__ . '/..' . '/react/socket/src/Connector.php', - 'React\\Socket\\ConnectorInterface' => __DIR__ . '/..' . '/react/socket/src/ConnectorInterface.php', - 'React\\Socket\\DnsConnector' => __DIR__ . '/..' . '/react/socket/src/DnsConnector.php', - 'React\\Socket\\FdServer' => __DIR__ . '/..' . '/react/socket/src/FdServer.php', - 'React\\Socket\\FixedUriConnector' => __DIR__ . '/..' . '/react/socket/src/FixedUriConnector.php', - 'React\\Socket\\HappyEyeBallsConnectionBuilder' => __DIR__ . '/..' . '/react/socket/src/HappyEyeBallsConnectionBuilder.php', - 'React\\Socket\\HappyEyeBallsConnector' => __DIR__ . '/..' . '/react/socket/src/HappyEyeBallsConnector.php', - 'React\\Socket\\LimitingServer' => __DIR__ . '/..' . '/react/socket/src/LimitingServer.php', - 'React\\Socket\\SecureConnector' => __DIR__ . '/..' . '/react/socket/src/SecureConnector.php', - 'React\\Socket\\SecureServer' => __DIR__ . '/..' . '/react/socket/src/SecureServer.php', - 'React\\Socket\\Server' => __DIR__ . '/..' . '/react/socket/src/Server.php', - 'React\\Socket\\ServerInterface' => __DIR__ . '/..' . '/react/socket/src/ServerInterface.php', - 'React\\Socket\\SocketServer' => __DIR__ . '/..' . '/react/socket/src/SocketServer.php', - 'React\\Socket\\StreamEncryption' => __DIR__ . '/..' . '/react/socket/src/StreamEncryption.php', - 'React\\Socket\\TcpConnector' => __DIR__ . '/..' . '/react/socket/src/TcpConnector.php', - 'React\\Socket\\TcpServer' => __DIR__ . '/..' . '/react/socket/src/TcpServer.php', - 'React\\Socket\\TimeoutConnector' => __DIR__ . '/..' . '/react/socket/src/TimeoutConnector.php', - 'React\\Socket\\UnixConnector' => __DIR__ . '/..' . '/react/socket/src/UnixConnector.php', - 'React\\Socket\\UnixServer' => __DIR__ . '/..' . '/react/socket/src/UnixServer.php', - 'React\\Stream\\CompositeStream' => __DIR__ . '/..' . '/react/stream/src/CompositeStream.php', - 'React\\Stream\\DuplexResourceStream' => __DIR__ . '/..' . '/react/stream/src/DuplexResourceStream.php', - 'React\\Stream\\DuplexStreamInterface' => __DIR__ . '/..' . '/react/stream/src/DuplexStreamInterface.php', - 'React\\Stream\\ReadableResourceStream' => __DIR__ . '/..' . '/react/stream/src/ReadableResourceStream.php', - 'React\\Stream\\ReadableStreamInterface' => __DIR__ . '/..' . '/react/stream/src/ReadableStreamInterface.php', - 'React\\Stream\\ThroughStream' => __DIR__ . '/..' . '/react/stream/src/ThroughStream.php', - 'React\\Stream\\Util' => __DIR__ . '/..' . '/react/stream/src/Util.php', - 'React\\Stream\\WritableResourceStream' => __DIR__ . '/..' . '/react/stream/src/WritableResourceStream.php', - 'React\\Stream\\WritableStreamInterface' => __DIR__ . '/..' . '/react/stream/src/WritableStreamInterface.php', - 'RingCentral\\Psr7\\AppendStream' => __DIR__ . '/..' . '/ringcentral/psr7/src/AppendStream.php', - 'RingCentral\\Psr7\\BufferStream' => __DIR__ . '/..' . '/ringcentral/psr7/src/BufferStream.php', - 'RingCentral\\Psr7\\CachingStream' => __DIR__ . '/..' . '/ringcentral/psr7/src/CachingStream.php', - 'RingCentral\\Psr7\\DroppingStream' => __DIR__ . '/..' . '/ringcentral/psr7/src/DroppingStream.php', - 'RingCentral\\Psr7\\FnStream' => __DIR__ . '/..' . '/ringcentral/psr7/src/FnStream.php', - 'RingCentral\\Psr7\\InflateStream' => __DIR__ . '/..' . '/ringcentral/psr7/src/InflateStream.php', - 'RingCentral\\Psr7\\LazyOpenStream' => __DIR__ . '/..' . '/ringcentral/psr7/src/LazyOpenStream.php', - 'RingCentral\\Psr7\\LimitStream' => __DIR__ . '/..' . '/ringcentral/psr7/src/LimitStream.php', - 'RingCentral\\Psr7\\MessageTrait' => __DIR__ . '/..' . '/ringcentral/psr7/src/MessageTrait.php', - 'RingCentral\\Psr7\\MultipartStream' => __DIR__ . '/..' . '/ringcentral/psr7/src/MultipartStream.php', - 'RingCentral\\Psr7\\NoSeekStream' => __DIR__ . '/..' . '/ringcentral/psr7/src/NoSeekStream.php', - 'RingCentral\\Psr7\\PumpStream' => __DIR__ . '/..' . '/ringcentral/psr7/src/PumpStream.php', - 'RingCentral\\Psr7\\Request' => __DIR__ . '/..' . '/ringcentral/psr7/src/Request.php', - 'RingCentral\\Psr7\\Response' => __DIR__ . '/..' . '/ringcentral/psr7/src/Response.php', - 'RingCentral\\Psr7\\ServerRequest' => __DIR__ . '/..' . '/ringcentral/psr7/src/ServerRequest.php', - 'RingCentral\\Psr7\\Stream' => __DIR__ . '/..' . '/ringcentral/psr7/src/Stream.php', - 'RingCentral\\Psr7\\StreamDecoratorTrait' => __DIR__ . '/..' . '/ringcentral/psr7/src/StreamDecoratorTrait.php', - 'RingCentral\\Psr7\\StreamWrapper' => __DIR__ . '/..' . '/ringcentral/psr7/src/StreamWrapper.php', - 'RingCentral\\Psr7\\Uri' => __DIR__ . '/..' . '/ringcentral/psr7/src/Uri.php', - 'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', - 'Symfony\\Component\\Console\\Application' => __DIR__ . '/..' . '/symfony/console/Application.php', - 'Symfony\\Component\\Console\\Attribute\\AsCommand' => __DIR__ . '/..' . '/symfony/console/Attribute/AsCommand.php', - 'Symfony\\Component\\Console\\CI\\GithubActionReporter' => __DIR__ . '/..' . '/symfony/console/CI/GithubActionReporter.php', - 'Symfony\\Component\\Console\\Color' => __DIR__ . '/..' . '/symfony/console/Color.php', - 'Symfony\\Component\\Console\\CommandLoader\\CommandLoaderInterface' => __DIR__ . '/..' . '/symfony/console/CommandLoader/CommandLoaderInterface.php', - 'Symfony\\Component\\Console\\CommandLoader\\ContainerCommandLoader' => __DIR__ . '/..' . '/symfony/console/CommandLoader/ContainerCommandLoader.php', - 'Symfony\\Component\\Console\\CommandLoader\\FactoryCommandLoader' => __DIR__ . '/..' . '/symfony/console/CommandLoader/FactoryCommandLoader.php', - 'Symfony\\Component\\Console\\Command\\Command' => __DIR__ . '/..' . '/symfony/console/Command/Command.php', - 'Symfony\\Component\\Console\\Command\\CompleteCommand' => __DIR__ . '/..' . '/symfony/console/Command/CompleteCommand.php', - 'Symfony\\Component\\Console\\Command\\DumpCompletionCommand' => __DIR__ . '/..' . '/symfony/console/Command/DumpCompletionCommand.php', - 'Symfony\\Component\\Console\\Command\\HelpCommand' => __DIR__ . '/..' . '/symfony/console/Command/HelpCommand.php', - 'Symfony\\Component\\Console\\Command\\LazyCommand' => __DIR__ . '/..' . '/symfony/console/Command/LazyCommand.php', - 'Symfony\\Component\\Console\\Command\\ListCommand' => __DIR__ . '/..' . '/symfony/console/Command/ListCommand.php', - 'Symfony\\Component\\Console\\Command\\LockableTrait' => __DIR__ . '/..' . '/symfony/console/Command/LockableTrait.php', - 'Symfony\\Component\\Console\\Command\\SignalableCommandInterface' => __DIR__ . '/..' . '/symfony/console/Command/SignalableCommandInterface.php', - 'Symfony\\Component\\Console\\Completion\\CompletionInput' => __DIR__ . '/..' . '/symfony/console/Completion/CompletionInput.php', - 'Symfony\\Component\\Console\\Completion\\CompletionSuggestions' => __DIR__ . '/..' . '/symfony/console/Completion/CompletionSuggestions.php', - 'Symfony\\Component\\Console\\Completion\\Output\\BashCompletionOutput' => __DIR__ . '/..' . '/symfony/console/Completion/Output/BashCompletionOutput.php', - 'Symfony\\Component\\Console\\Completion\\Output\\CompletionOutputInterface' => __DIR__ . '/..' . '/symfony/console/Completion/Output/CompletionOutputInterface.php', - 'Symfony\\Component\\Console\\Completion\\Suggestion' => __DIR__ . '/..' . '/symfony/console/Completion/Suggestion.php', - 'Symfony\\Component\\Console\\ConsoleEvents' => __DIR__ . '/..' . '/symfony/console/ConsoleEvents.php', - 'Symfony\\Component\\Console\\Cursor' => __DIR__ . '/..' . '/symfony/console/Cursor.php', - 'Symfony\\Component\\Console\\DependencyInjection\\AddConsoleCommandPass' => __DIR__ . '/..' . '/symfony/console/DependencyInjection/AddConsoleCommandPass.php', - 'Symfony\\Component\\Console\\Descriptor\\ApplicationDescription' => __DIR__ . '/..' . '/symfony/console/Descriptor/ApplicationDescription.php', - 'Symfony\\Component\\Console\\Descriptor\\Descriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/Descriptor.php', - 'Symfony\\Component\\Console\\Descriptor\\DescriptorInterface' => __DIR__ . '/..' . '/symfony/console/Descriptor/DescriptorInterface.php', - 'Symfony\\Component\\Console\\Descriptor\\JsonDescriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/JsonDescriptor.php', - 'Symfony\\Component\\Console\\Descriptor\\MarkdownDescriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/MarkdownDescriptor.php', - 'Symfony\\Component\\Console\\Descriptor\\TextDescriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/TextDescriptor.php', - 'Symfony\\Component\\Console\\Descriptor\\XmlDescriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/XmlDescriptor.php', - 'Symfony\\Component\\Console\\EventListener\\ErrorListener' => __DIR__ . '/..' . '/symfony/console/EventListener/ErrorListener.php', - 'Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleCommandEvent.php', - 'Symfony\\Component\\Console\\Event\\ConsoleErrorEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleErrorEvent.php', - 'Symfony\\Component\\Console\\Event\\ConsoleEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleEvent.php', - 'Symfony\\Component\\Console\\Event\\ConsoleSignalEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleSignalEvent.php', - 'Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleTerminateEvent.php', - 'Symfony\\Component\\Console\\Exception\\CommandNotFoundException' => __DIR__ . '/..' . '/symfony/console/Exception/CommandNotFoundException.php', - 'Symfony\\Component\\Console\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/console/Exception/ExceptionInterface.php', - 'Symfony\\Component\\Console\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/console/Exception/InvalidArgumentException.php', - 'Symfony\\Component\\Console\\Exception\\InvalidOptionException' => __DIR__ . '/..' . '/symfony/console/Exception/InvalidOptionException.php', - 'Symfony\\Component\\Console\\Exception\\LogicException' => __DIR__ . '/..' . '/symfony/console/Exception/LogicException.php', - 'Symfony\\Component\\Console\\Exception\\MissingInputException' => __DIR__ . '/..' . '/symfony/console/Exception/MissingInputException.php', - 'Symfony\\Component\\Console\\Exception\\NamespaceNotFoundException' => __DIR__ . '/..' . '/symfony/console/Exception/NamespaceNotFoundException.php', - 'Symfony\\Component\\Console\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/console/Exception/RuntimeException.php', - 'Symfony\\Component\\Console\\Formatter\\NullOutputFormatter' => __DIR__ . '/..' . '/symfony/console/Formatter/NullOutputFormatter.php', - 'Symfony\\Component\\Console\\Formatter\\NullOutputFormatterStyle' => __DIR__ . '/..' . '/symfony/console/Formatter/NullOutputFormatterStyle.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatter' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatter.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterInterface.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterStyle.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterStyleInterface.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterStyleStack.php', - 'Symfony\\Component\\Console\\Formatter\\WrappableOutputFormatterInterface' => __DIR__ . '/..' . '/symfony/console/Formatter/WrappableOutputFormatterInterface.php', - 'Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => __DIR__ . '/..' . '/symfony/console/Helper/DebugFormatterHelper.php', - 'Symfony\\Component\\Console\\Helper\\DescriptorHelper' => __DIR__ . '/..' . '/symfony/console/Helper/DescriptorHelper.php', - 'Symfony\\Component\\Console\\Helper\\Dumper' => __DIR__ . '/..' . '/symfony/console/Helper/Dumper.php', - 'Symfony\\Component\\Console\\Helper\\FormatterHelper' => __DIR__ . '/..' . '/symfony/console/Helper/FormatterHelper.php', - 'Symfony\\Component\\Console\\Helper\\Helper' => __DIR__ . '/..' . '/symfony/console/Helper/Helper.php', - 'Symfony\\Component\\Console\\Helper\\HelperInterface' => __DIR__ . '/..' . '/symfony/console/Helper/HelperInterface.php', - 'Symfony\\Component\\Console\\Helper\\HelperSet' => __DIR__ . '/..' . '/symfony/console/Helper/HelperSet.php', - 'Symfony\\Component\\Console\\Helper\\InputAwareHelper' => __DIR__ . '/..' . '/symfony/console/Helper/InputAwareHelper.php', - 'Symfony\\Component\\Console\\Helper\\ProcessHelper' => __DIR__ . '/..' . '/symfony/console/Helper/ProcessHelper.php', - 'Symfony\\Component\\Console\\Helper\\ProgressBar' => __DIR__ . '/..' . '/symfony/console/Helper/ProgressBar.php', - 'Symfony\\Component\\Console\\Helper\\ProgressIndicator' => __DIR__ . '/..' . '/symfony/console/Helper/ProgressIndicator.php', - 'Symfony\\Component\\Console\\Helper\\QuestionHelper' => __DIR__ . '/..' . '/symfony/console/Helper/QuestionHelper.php', - 'Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => __DIR__ . '/..' . '/symfony/console/Helper/SymfonyQuestionHelper.php', - 'Symfony\\Component\\Console\\Helper\\Table' => __DIR__ . '/..' . '/symfony/console/Helper/Table.php', - 'Symfony\\Component\\Console\\Helper\\TableCell' => __DIR__ . '/..' . '/symfony/console/Helper/TableCell.php', - 'Symfony\\Component\\Console\\Helper\\TableCellStyle' => __DIR__ . '/..' . '/symfony/console/Helper/TableCellStyle.php', - 'Symfony\\Component\\Console\\Helper\\TableRows' => __DIR__ . '/..' . '/symfony/console/Helper/TableRows.php', - 'Symfony\\Component\\Console\\Helper\\TableSeparator' => __DIR__ . '/..' . '/symfony/console/Helper/TableSeparator.php', - 'Symfony\\Component\\Console\\Helper\\TableStyle' => __DIR__ . '/..' . '/symfony/console/Helper/TableStyle.php', - 'Symfony\\Component\\Console\\Input\\ArgvInput' => __DIR__ . '/..' . '/symfony/console/Input/ArgvInput.php', - 'Symfony\\Component\\Console\\Input\\ArrayInput' => __DIR__ . '/..' . '/symfony/console/Input/ArrayInput.php', - 'Symfony\\Component\\Console\\Input\\Input' => __DIR__ . '/..' . '/symfony/console/Input/Input.php', - 'Symfony\\Component\\Console\\Input\\InputArgument' => __DIR__ . '/..' . '/symfony/console/Input/InputArgument.php', - 'Symfony\\Component\\Console\\Input\\InputAwareInterface' => __DIR__ . '/..' . '/symfony/console/Input/InputAwareInterface.php', - 'Symfony\\Component\\Console\\Input\\InputDefinition' => __DIR__ . '/..' . '/symfony/console/Input/InputDefinition.php', - 'Symfony\\Component\\Console\\Input\\InputInterface' => __DIR__ . '/..' . '/symfony/console/Input/InputInterface.php', - 'Symfony\\Component\\Console\\Input\\InputOption' => __DIR__ . '/..' . '/symfony/console/Input/InputOption.php', - 'Symfony\\Component\\Console\\Input\\StreamableInputInterface' => __DIR__ . '/..' . '/symfony/console/Input/StreamableInputInterface.php', - 'Symfony\\Component\\Console\\Input\\StringInput' => __DIR__ . '/..' . '/symfony/console/Input/StringInput.php', - 'Symfony\\Component\\Console\\Logger\\ConsoleLogger' => __DIR__ . '/..' . '/symfony/console/Logger/ConsoleLogger.php', - 'Symfony\\Component\\Console\\Output\\BufferedOutput' => __DIR__ . '/..' . '/symfony/console/Output/BufferedOutput.php', - 'Symfony\\Component\\Console\\Output\\ConsoleOutput' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleOutput.php', - 'Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleOutputInterface.php', - 'Symfony\\Component\\Console\\Output\\ConsoleSectionOutput' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleSectionOutput.php', - 'Symfony\\Component\\Console\\Output\\NullOutput' => __DIR__ . '/..' . '/symfony/console/Output/NullOutput.php', - 'Symfony\\Component\\Console\\Output\\Output' => __DIR__ . '/..' . '/symfony/console/Output/Output.php', - 'Symfony\\Component\\Console\\Output\\OutputInterface' => __DIR__ . '/..' . '/symfony/console/Output/OutputInterface.php', - 'Symfony\\Component\\Console\\Output\\StreamOutput' => __DIR__ . '/..' . '/symfony/console/Output/StreamOutput.php', - 'Symfony\\Component\\Console\\Output\\TrimmedBufferOutput' => __DIR__ . '/..' . '/symfony/console/Output/TrimmedBufferOutput.php', - 'Symfony\\Component\\Console\\Question\\ChoiceQuestion' => __DIR__ . '/..' . '/symfony/console/Question/ChoiceQuestion.php', - 'Symfony\\Component\\Console\\Question\\ConfirmationQuestion' => __DIR__ . '/..' . '/symfony/console/Question/ConfirmationQuestion.php', - 'Symfony\\Component\\Console\\Question\\Question' => __DIR__ . '/..' . '/symfony/console/Question/Question.php', - 'Symfony\\Component\\Console\\SignalRegistry\\SignalRegistry' => __DIR__ . '/..' . '/symfony/console/SignalRegistry/SignalRegistry.php', - 'Symfony\\Component\\Console\\SingleCommandApplication' => __DIR__ . '/..' . '/symfony/console/SingleCommandApplication.php', - 'Symfony\\Component\\Console\\Style\\OutputStyle' => __DIR__ . '/..' . '/symfony/console/Style/OutputStyle.php', - 'Symfony\\Component\\Console\\Style\\StyleInterface' => __DIR__ . '/..' . '/symfony/console/Style/StyleInterface.php', - 'Symfony\\Component\\Console\\Style\\SymfonyStyle' => __DIR__ . '/..' . '/symfony/console/Style/SymfonyStyle.php', - 'Symfony\\Component\\Console\\Terminal' => __DIR__ . '/..' . '/symfony/console/Terminal.php', - 'Symfony\\Component\\Console\\Tester\\ApplicationTester' => __DIR__ . '/..' . '/symfony/console/Tester/ApplicationTester.php', - 'Symfony\\Component\\Console\\Tester\\CommandCompletionTester' => __DIR__ . '/..' . '/symfony/console/Tester/CommandCompletionTester.php', - 'Symfony\\Component\\Console\\Tester\\CommandTester' => __DIR__ . '/..' . '/symfony/console/Tester/CommandTester.php', - 'Symfony\\Component\\Console\\Tester\\Constraint\\CommandIsSuccessful' => __DIR__ . '/..' . '/symfony/console/Tester/Constraint/CommandIsSuccessful.php', - 'Symfony\\Component\\Console\\Tester\\TesterTrait' => __DIR__ . '/..' . '/symfony/console/Tester/TesterTrait.php', - 'Symfony\\Component\\Process\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/process/Exception/ExceptionInterface.php', - 'Symfony\\Component\\Process\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/process/Exception/InvalidArgumentException.php', - 'Symfony\\Component\\Process\\Exception\\LogicException' => __DIR__ . '/..' . '/symfony/process/Exception/LogicException.php', - 'Symfony\\Component\\Process\\Exception\\ProcessFailedException' => __DIR__ . '/..' . '/symfony/process/Exception/ProcessFailedException.php', - 'Symfony\\Component\\Process\\Exception\\ProcessSignaledException' => __DIR__ . '/..' . '/symfony/process/Exception/ProcessSignaledException.php', - 'Symfony\\Component\\Process\\Exception\\ProcessTimedOutException' => __DIR__ . '/..' . '/symfony/process/Exception/ProcessTimedOutException.php', - 'Symfony\\Component\\Process\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/process/Exception/RuntimeException.php', - 'Symfony\\Component\\Process\\ExecutableFinder' => __DIR__ . '/..' . '/symfony/process/ExecutableFinder.php', - 'Symfony\\Component\\Process\\InputStream' => __DIR__ . '/..' . '/symfony/process/InputStream.php', - 'Symfony\\Component\\Process\\PhpExecutableFinder' => __DIR__ . '/..' . '/symfony/process/PhpExecutableFinder.php', - 'Symfony\\Component\\Process\\PhpProcess' => __DIR__ . '/..' . '/symfony/process/PhpProcess.php', - 'Symfony\\Component\\Process\\Pipes\\AbstractPipes' => __DIR__ . '/..' . '/symfony/process/Pipes/AbstractPipes.php', - 'Symfony\\Component\\Process\\Pipes\\PipesInterface' => __DIR__ . '/..' . '/symfony/process/Pipes/PipesInterface.php', - 'Symfony\\Component\\Process\\Pipes\\UnixPipes' => __DIR__ . '/..' . '/symfony/process/Pipes/UnixPipes.php', - 'Symfony\\Component\\Process\\Pipes\\WindowsPipes' => __DIR__ . '/..' . '/symfony/process/Pipes/WindowsPipes.php', - 'Symfony\\Component\\Process\\Process' => __DIR__ . '/..' . '/symfony/process/Process.php', - 'Symfony\\Component\\Process\\ProcessUtils' => __DIR__ . '/..' . '/symfony/process/ProcessUtils.php', - 'Symfony\\Component\\String\\AbstractString' => __DIR__ . '/..' . '/symfony/string/AbstractString.php', - 'Symfony\\Component\\String\\AbstractUnicodeString' => __DIR__ . '/..' . '/symfony/string/AbstractUnicodeString.php', - 'Symfony\\Component\\String\\ByteString' => __DIR__ . '/..' . '/symfony/string/ByteString.php', - 'Symfony\\Component\\String\\CodePointString' => __DIR__ . '/..' . '/symfony/string/CodePointString.php', - 'Symfony\\Component\\String\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/string/Exception/ExceptionInterface.php', - 'Symfony\\Component\\String\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/string/Exception/InvalidArgumentException.php', - 'Symfony\\Component\\String\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/string/Exception/RuntimeException.php', - 'Symfony\\Component\\String\\Inflector\\EnglishInflector' => __DIR__ . '/..' . '/symfony/string/Inflector/EnglishInflector.php', - 'Symfony\\Component\\String\\Inflector\\FrenchInflector' => __DIR__ . '/..' . '/symfony/string/Inflector/FrenchInflector.php', - 'Symfony\\Component\\String\\Inflector\\InflectorInterface' => __DIR__ . '/..' . '/symfony/string/Inflector/InflectorInterface.php', - 'Symfony\\Component\\String\\LazyString' => __DIR__ . '/..' . '/symfony/string/LazyString.php', - 'Symfony\\Component\\String\\Slugger\\AsciiSlugger' => __DIR__ . '/..' . '/symfony/string/Slugger/AsciiSlugger.php', - 'Symfony\\Component\\String\\Slugger\\SluggerInterface' => __DIR__ . '/..' . '/symfony/string/Slugger/SluggerInterface.php', - 'Symfony\\Component\\String\\UnicodeString' => __DIR__ . '/..' . '/symfony/string/UnicodeString.php', - 'Symfony\\Component\\Yaml\\Command\\LintCommand' => __DIR__ . '/..' . '/symfony/yaml/Command/LintCommand.php', - 'Symfony\\Component\\Yaml\\Dumper' => __DIR__ . '/..' . '/symfony/yaml/Dumper.php', - 'Symfony\\Component\\Yaml\\Escaper' => __DIR__ . '/..' . '/symfony/yaml/Escaper.php', - 'Symfony\\Component\\Yaml\\Exception\\DumpException' => __DIR__ . '/..' . '/symfony/yaml/Exception/DumpException.php', - 'Symfony\\Component\\Yaml\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/yaml/Exception/ExceptionInterface.php', - 'Symfony\\Component\\Yaml\\Exception\\ParseException' => __DIR__ . '/..' . '/symfony/yaml/Exception/ParseException.php', - 'Symfony\\Component\\Yaml\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/yaml/Exception/RuntimeException.php', - 'Symfony\\Component\\Yaml\\Inline' => __DIR__ . '/..' . '/symfony/yaml/Inline.php', - 'Symfony\\Component\\Yaml\\Parser' => __DIR__ . '/..' . '/symfony/yaml/Parser.php', - 'Symfony\\Component\\Yaml\\Tag\\TaggedValue' => __DIR__ . '/..' . '/symfony/yaml/Tag/TaggedValue.php', - 'Symfony\\Component\\Yaml\\Unescaper' => __DIR__ . '/..' . '/symfony/yaml/Unescaper.php', - 'Symfony\\Component\\Yaml\\Yaml' => __DIR__ . '/..' . '/symfony/yaml/Yaml.php', - 'Symfony\\Contracts\\Service\\Attribute\\Required' => __DIR__ . '/..' . '/symfony/service-contracts/Attribute/Required.php', - 'Symfony\\Contracts\\Service\\Attribute\\SubscribedService' => __DIR__ . '/..' . '/symfony/service-contracts/Attribute/SubscribedService.php', - 'Symfony\\Contracts\\Service\\ResetInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ResetInterface.php', - 'Symfony\\Contracts\\Service\\ServiceLocatorTrait' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceLocatorTrait.php', - 'Symfony\\Contracts\\Service\\ServiceProviderInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceProviderInterface.php', - 'Symfony\\Contracts\\Service\\ServiceSubscriberInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceSubscriberInterface.php', - 'Symfony\\Contracts\\Service\\ServiceSubscriberTrait' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceSubscriberTrait.php', - 'Symfony\\Contracts\\Service\\Test\\ServiceLocatorTest' => __DIR__ . '/..' . '/symfony/service-contracts/Test/ServiceLocatorTest.php', - 'Symfony\\Polyfill\\Ctype\\Ctype' => __DIR__ . '/..' . '/symfony/polyfill-ctype/Ctype.php', - 'Symfony\\Polyfill\\Intl\\Grapheme\\Grapheme' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/Grapheme.php', - 'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Normalizer.php', - 'Symfony\\Polyfill\\Mbstring\\Mbstring' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/Mbstring.php', - 'Symfony\\Polyfill\\Php73\\Php73' => __DIR__ . '/..' . '/symfony/polyfill-php73/Php73.php', - 'Symfony\\Polyfill\\Php80\\Php80' => __DIR__ . '/..' . '/symfony/polyfill-php80/Php80.php', - 'Symfony\\Polyfill\\Php80\\PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/PhpToken.php', - 'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', - 'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', - ); - - public static function getInitializer(ClassLoader $loader) - { - return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit234e1a4a29689e00066666da06e8ece1::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit234e1a4a29689e00066666da06e8ece1::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInit234e1a4a29689e00066666da06e8ece1::$prefixesPsr0; - $loader->classMap = ComposerStaticInit234e1a4a29689e00066666da06e8ece1::$classMap; - - }, null, ClassLoader::class); - } -} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php deleted file mode 100644 index 579b5b435..000000000 --- a/vendor/composer/installed.php +++ /dev/null @@ -1,281 +0,0 @@ - - array ( - 'pretty_version' => 'v7.1.2', - 'version' => '7.1.2.0', - 'aliases' => - array ( - ), - 'reference' => '6b354c2e89198e64a0244fb96cc5604312027800', - 'name' => 'deployer/deployer', - ), - 'versions' => - array ( - 'deployer/deployer' => - array ( - 'pretty_version' => 'v7.1.2', - 'version' => '7.1.2.0', - 'aliases' => - array ( - ), - 'reference' => '6b354c2e89198e64a0244fb96cc5604312027800', - ), - 'evenement/evenement' => - array ( - 'pretty_version' => 'v3.0.1', - 'version' => '3.0.1.0', - 'aliases' => - array ( - ), - 'reference' => '531bfb9d15f8aa57454f5f0285b18bec903b8fb7', - ), - 'fig/http-message-util' => - array ( - 'pretty_version' => '1.1.5', - 'version' => '1.1.5.0', - 'aliases' => - array ( - ), - 'reference' => '9d94dc0154230ac39e5bf89398b324a86f63f765', - ), - 'justinrainbow/json-schema' => - array ( - 'pretty_version' => '5.2.11', - 'version' => '5.2.11.0', - 'aliases' => - array ( - ), - 'reference' => '2ab6744b7296ded80f8cc4f9509abbff393399aa', - ), - 'psr/container' => - array ( - 'pretty_version' => '1.1.1', - 'version' => '1.1.1.0', - 'aliases' => - array ( - ), - 'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf', - ), - 'psr/http-message' => - array ( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'aliases' => - array ( - ), - 'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363', - ), - 'psr/http-message-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0', - ), - ), - 'psr/log-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0|2.0', - ), - ), - 'react/cache' => - array ( - 'pretty_version' => 'v1.1.1', - 'version' => '1.1.1.0', - 'aliases' => - array ( - ), - 'reference' => '4bf736a2cccec7298bdf745db77585966fc2ca7e', - ), - 'react/dns' => - array ( - 'pretty_version' => 'v1.9.0', - 'version' => '1.9.0.0', - 'aliases' => - array ( - ), - 'reference' => '6d38296756fa644e6cb1bfe95eff0f9a4ed6edcb', - ), - 'react/event-loop' => - array ( - 'pretty_version' => 'v1.2.0', - 'version' => '1.2.0.0', - 'aliases' => - array ( - ), - 'reference' => 'be6dee480fc4692cec0504e65eb486e3be1aa6f2', - ), - 'react/http' => - array ( - 'pretty_version' => 'v1.6.0', - 'version' => '1.6.0.0', - 'aliases' => - array ( - ), - 'reference' => '59961cc4a5b14481728f07c591546be18fa3a5c7', - ), - 'react/promise' => - array ( - 'pretty_version' => 'v2.9.0', - 'version' => '2.9.0.0', - 'aliases' => - array ( - ), - 'reference' => '234f8fd1023c9158e2314fa9d7d0e6a83db42910', - ), - 'react/promise-stream' => - array ( - 'pretty_version' => 'v1.3.0', - 'version' => '1.3.0.0', - 'aliases' => - array ( - ), - 'reference' => '3ebd94fe0d8edbf44937948af28d02d5437e9949', - ), - 'react/promise-timer' => - array ( - 'pretty_version' => 'v1.8.0', - 'version' => '1.8.0.0', - 'aliases' => - array ( - ), - 'reference' => '0bbbcc79589e5bfdddba68a287f1cb805581a479', - ), - 'react/socket' => - array ( - 'pretty_version' => 'v1.11.0', - 'version' => '1.11.0.0', - 'aliases' => - array ( - ), - 'reference' => 'f474156aaab4f09041144fa8b57c7d70aed32a1c', - ), - 'react/stream' => - array ( - 'pretty_version' => 'v1.2.0', - 'version' => '1.2.0.0', - 'aliases' => - array ( - ), - 'reference' => '7a423506ee1903e89f1e08ec5f0ed430ff784ae9', - ), - 'ringcentral/psr7' => - array ( - 'pretty_version' => '1.3.0', - 'version' => '1.3.0.0', - 'aliases' => - array ( - ), - 'reference' => '360faaec4b563958b673fb52bbe94e37f14bc686', - ), - 'symfony/console' => - array ( - 'pretty_version' => 'v5.4.17', - 'version' => '5.4.17.0', - 'aliases' => - array ( - ), - 'reference' => '58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f', - ), - 'symfony/deprecation-contracts' => - array ( - 'pretty_version' => 'v2.5.0', - 'version' => '2.5.0.0', - 'aliases' => - array ( - ), - 'reference' => '6f981ee24cf69ee7ce9736146d1c57c2780598a8', - ), - 'symfony/polyfill-ctype' => - array ( - 'pretty_version' => 'v1.25.0', - 'version' => '1.25.0.0', - 'aliases' => - array ( - ), - 'reference' => '30885182c981ab175d4d034db0f6f469898070ab', - ), - 'symfony/polyfill-intl-grapheme' => - array ( - 'pretty_version' => 'v1.25.0', - 'version' => '1.25.0.0', - 'aliases' => - array ( - ), - 'reference' => '81b86b50cf841a64252b439e738e97f4a34e2783', - ), - 'symfony/polyfill-intl-normalizer' => - array ( - 'pretty_version' => 'v1.25.0', - 'version' => '1.25.0.0', - 'aliases' => - array ( - ), - 'reference' => '8590a5f561694770bdcd3f9b5c69dde6945028e8', - ), - 'symfony/polyfill-mbstring' => - array ( - 'pretty_version' => 'v1.25.0', - 'version' => '1.25.0.0', - 'aliases' => - array ( - ), - 'reference' => '0abb51d2f102e00a4eefcf46ba7fec406d245825', - ), - 'symfony/polyfill-php73' => - array ( - 'pretty_version' => 'v1.25.0', - 'version' => '1.25.0.0', - 'aliases' => - array ( - ), - 'reference' => 'cc5db0e22b3cb4111010e48785a97f670b350ca5', - ), - 'symfony/polyfill-php80' => - array ( - 'pretty_version' => 'v1.25.0', - 'version' => '1.25.0.0', - 'aliases' => - array ( - ), - 'reference' => '4407588e0d3f1f52efb65fbe92babe41f37fe50c', - ), - 'symfony/process' => - array ( - 'pretty_version' => 'v5.4.5', - 'version' => '5.4.5.0', - 'aliases' => - array ( - ), - 'reference' => '95440409896f90a5f85db07a32b517ecec17fa4c', - ), - 'symfony/service-contracts' => - array ( - 'pretty_version' => 'v2.5.0', - 'version' => '2.5.0.0', - 'aliases' => - array ( - ), - 'reference' => '1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc', - ), - 'symfony/string' => - array ( - 'pretty_version' => 'v5.4.3', - 'version' => '5.4.3.0', - 'aliases' => - array ( - ), - 'reference' => '92043b7d8383e48104e411bc9434b260dbeb5a10', - ), - 'symfony/yaml' => - array ( - 'pretty_version' => 'v5.4.3', - 'version' => '5.4.3.0', - 'aliases' => - array ( - ), - 'reference' => 'e80f87d2c9495966768310fc531b487ce64237a2', - ), - ), -); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php deleted file mode 100644 index 92370c5a0..000000000 --- a/vendor/composer/platform_check.php +++ /dev/null @@ -1,26 +0,0 @@ -= 70300)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 7.3.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/vendor/evenement/evenement/examples/benchmark-emit-no-arguments.php b/vendor/evenement/evenement/examples/benchmark-emit-no-arguments.php deleted file mode 100644 index 53d7f4b22..000000000 --- a/vendor/evenement/evenement/examples/benchmark-emit-no-arguments.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -const ITERATIONS = 10000000; - -use Evenement\EventEmitter; - -require __DIR__.'/../vendor/autoload.php'; - -$emitter = new EventEmitter(); - -$emitter->on('event', function () {}); - -$start = microtime(true); -for ($i = 0; $i < ITERATIONS; $i++) { - $emitter->emit('event'); -} -$time = microtime(true) - $start; - -echo 'Emitting ', number_format(ITERATIONS), ' events took: ', number_format($time, 2), 's', PHP_EOL; diff --git a/vendor/evenement/evenement/examples/benchmark-emit-once.php b/vendor/evenement/evenement/examples/benchmark-emit-once.php deleted file mode 100644 index 74f4d1755..000000000 --- a/vendor/evenement/evenement/examples/benchmark-emit-once.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -ini_set('memory_limit', '512M'); - -const ITERATIONS = 100000; - -use Evenement\EventEmitter; - -require __DIR__.'/../vendor/autoload.php'; - -$emitter = new EventEmitter(); - -for ($i = 0; $i < ITERATIONS; $i++) { - $emitter->once('event', function ($a, $b, $c) {}); -} - -$start = microtime(true); -$emitter->emit('event', [1, 2, 3]); -$time = microtime(true) - $start; - -echo 'Emitting one event to ', number_format(ITERATIONS), ' once listeners took: ', number_format($time, 2), 's', PHP_EOL; diff --git a/vendor/evenement/evenement/examples/benchmark-emit-one-argument.php b/vendor/evenement/evenement/examples/benchmark-emit-one-argument.php deleted file mode 100644 index 39fc4ba09..000000000 --- a/vendor/evenement/evenement/examples/benchmark-emit-one-argument.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -const ITERATIONS = 10000000; - -use Evenement\EventEmitter; - -require __DIR__.'/../vendor/autoload.php'; - -$emitter = new EventEmitter(); - -$emitter->on('event', function ($a) {}); - -$start = microtime(true); -for ($i = 0; $i < ITERATIONS; $i++) { - $emitter->emit('event', [1]); -} -$time = microtime(true) - $start; - -echo 'Emitting ', number_format(ITERATIONS), ' events took: ', number_format($time, 2), 's', PHP_EOL; diff --git a/vendor/evenement/evenement/examples/benchmark-emit.php b/vendor/evenement/evenement/examples/benchmark-emit.php deleted file mode 100644 index 3ab639e07..000000000 --- a/vendor/evenement/evenement/examples/benchmark-emit.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -const ITERATIONS = 10000000; - -use Evenement\EventEmitter; - -require __DIR__.'/../vendor/autoload.php'; - -$emitter = new EventEmitter(); - -$emitter->on('event', function ($a, $b, $c) {}); - -$start = microtime(true); -for ($i = 0; $i < ITERATIONS; $i++) { - $emitter->emit('event', [1, 2, 3]); -} -$time = microtime(true) - $start; - -echo 'Emitting ', number_format(ITERATIONS), ' events took: ', number_format($time, 2), 's', PHP_EOL; diff --git a/vendor/evenement/evenement/examples/benchmark-remove-listener-once.php b/vendor/evenement/evenement/examples/benchmark-remove-listener-once.php deleted file mode 100644 index 414be3bd2..000000000 --- a/vendor/evenement/evenement/examples/benchmark-remove-listener-once.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. - */ - -ini_set('memory_limit', '512M'); - -const ITERATIONS = 100000; - -use Evenement\EventEmitter; - -require __DIR__.'/../vendor/autoload.php'; - -$emitter = new EventEmitter(); - -$listeners = []; -for ($i = 0; $i < ITERATIONS; $i++) { - $listeners[] = function ($a, $b, $c) {}; -} - -$start = microtime(true); -foreach ($listeners as $listener) { - $emitter->once('event', $listener); -} -$time = microtime(true) - $start; -echo 'Adding ', number_format(ITERATIONS), ' once listeners took: ', number_format($time, 2), 's', PHP_EOL; - -$start = microtime(true); -foreach ($listeners as $listener) { - $emitter->removeListener('event', $listener); -} -$time = microtime(true) - $start; -echo 'Removing ', number_format(ITERATIONS), ' once listeners took: ', number_format($time, 2), 's', PHP_EOL; diff --git a/vendor/evenement/evenement/src/Evenement/EventEmitter.php b/vendor/evenement/evenement/src/Evenement/EventEmitter.php deleted file mode 100644 index db189b972..000000000 --- a/vendor/evenement/evenement/src/Evenement/EventEmitter.php +++ /dev/null @@ -1,17 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Evenement; - -class EventEmitter implements EventEmitterInterface -{ - use EventEmitterTrait; -} diff --git a/vendor/evenement/evenement/src/Evenement/EventEmitterInterface.php b/vendor/evenement/evenement/src/Evenement/EventEmitterInterface.php deleted file mode 100644 index 310631a10..000000000 --- a/vendor/evenement/evenement/src/Evenement/EventEmitterInterface.php +++ /dev/null @@ -1,22 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Evenement; - -interface EventEmitterInterface -{ - public function on($event, callable $listener); - public function once($event, callable $listener); - public function removeListener($event, callable $listener); - public function removeAllListeners($event = null); - public function listeners($event = null); - public function emit($event, array $arguments = []); -} diff --git a/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php b/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php deleted file mode 100644 index a78e65ca5..000000000 --- a/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php +++ /dev/null @@ -1,135 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Evenement; - -use InvalidArgumentException; - -trait EventEmitterTrait -{ - protected $listeners = []; - protected $onceListeners = []; - - public function on($event, callable $listener) - { - if ($event === null) { - throw new InvalidArgumentException('event name must not be null'); - } - - if (!isset($this->listeners[$event])) { - $this->listeners[$event] = []; - } - - $this->listeners[$event][] = $listener; - - return $this; - } - - public function once($event, callable $listener) - { - if ($event === null) { - throw new InvalidArgumentException('event name must not be null'); - } - - if (!isset($this->onceListeners[$event])) { - $this->onceListeners[$event] = []; - } - - $this->onceListeners[$event][] = $listener; - - return $this; - } - - public function removeListener($event, callable $listener) - { - if ($event === null) { - throw new InvalidArgumentException('event name must not be null'); - } - - if (isset($this->listeners[$event])) { - $index = \array_search($listener, $this->listeners[$event], true); - if (false !== $index) { - unset($this->listeners[$event][$index]); - if (\count($this->listeners[$event]) === 0) { - unset($this->listeners[$event]); - } - } - } - - if (isset($this->onceListeners[$event])) { - $index = \array_search($listener, $this->onceListeners[$event], true); - if (false !== $index) { - unset($this->onceListeners[$event][$index]); - if (\count($this->onceListeners[$event]) === 0) { - unset($this->onceListeners[$event]); - } - } - } - } - - public function removeAllListeners($event = null) - { - if ($event !== null) { - unset($this->listeners[$event]); - } else { - $this->listeners = []; - } - - if ($event !== null) { - unset($this->onceListeners[$event]); - } else { - $this->onceListeners = []; - } - } - - public function listeners($event = null): array - { - if ($event === null) { - $events = []; - $eventNames = \array_unique( - \array_merge(\array_keys($this->listeners), \array_keys($this->onceListeners)) - ); - foreach ($eventNames as $eventName) { - $events[$eventName] = \array_merge( - isset($this->listeners[$eventName]) ? $this->listeners[$eventName] : [], - isset($this->onceListeners[$eventName]) ? $this->onceListeners[$eventName] : [] - ); - } - return $events; - } - - return \array_merge( - isset($this->listeners[$event]) ? $this->listeners[$event] : [], - isset($this->onceListeners[$event]) ? $this->onceListeners[$event] : [] - ); - } - - public function emit($event, array $arguments = []) - { - if ($event === null) { - throw new InvalidArgumentException('event name must not be null'); - } - - if (isset($this->listeners[$event])) { - foreach ($this->listeners[$event] as $listener) { - $listener(...$arguments); - } - } - - if (isset($this->onceListeners[$event])) { - $listeners = $this->onceListeners[$event]; - unset($this->onceListeners[$event]); - foreach ($listeners as $listener) { - $listener(...$arguments); - } - } - } -} diff --git a/vendor/fig/http-message-util/src/RequestMethodInterface.php b/vendor/fig/http-message-util/src/RequestMethodInterface.php deleted file mode 100644 index 97d9a93bc..000000000 --- a/vendor/fig/http-message-util/src/RequestMethodInterface.php +++ /dev/null @@ -1,34 +0,0 @@ - - * class RequestFactory implements RequestMethodInterface - * { - * public static function factory( - * $uri = '/', - * $method = self::METHOD_GET, - * $data = [] - * ) { - * } - * } - * - */ -interface RequestMethodInterface -{ - const METHOD_HEAD = 'HEAD'; - const METHOD_GET = 'GET'; - const METHOD_POST = 'POST'; - const METHOD_PUT = 'PUT'; - const METHOD_PATCH = 'PATCH'; - const METHOD_DELETE = 'DELETE'; - const METHOD_PURGE = 'PURGE'; - const METHOD_OPTIONS = 'OPTIONS'; - const METHOD_TRACE = 'TRACE'; - const METHOD_CONNECT = 'CONNECT'; -} diff --git a/vendor/fig/http-message-util/src/StatusCodeInterface.php b/vendor/fig/http-message-util/src/StatusCodeInterface.php deleted file mode 100644 index 99b7e780d..000000000 --- a/vendor/fig/http-message-util/src/StatusCodeInterface.php +++ /dev/null @@ -1,107 +0,0 @@ - - * class ResponseFactory implements StatusCodeInterface - * { - * public function createResponse($code = self::STATUS_OK) - * { - * } - * } - * - */ -interface StatusCodeInterface -{ - // Informational 1xx - const STATUS_CONTINUE = 100; - const STATUS_SWITCHING_PROTOCOLS = 101; - const STATUS_PROCESSING = 102; - const STATUS_EARLY_HINTS = 103; - // Successful 2xx - const STATUS_OK = 200; - const STATUS_CREATED = 201; - const STATUS_ACCEPTED = 202; - const STATUS_NON_AUTHORITATIVE_INFORMATION = 203; - const STATUS_NO_CONTENT = 204; - const STATUS_RESET_CONTENT = 205; - const STATUS_PARTIAL_CONTENT = 206; - const STATUS_MULTI_STATUS = 207; - const STATUS_ALREADY_REPORTED = 208; - const STATUS_IM_USED = 226; - // Redirection 3xx - const STATUS_MULTIPLE_CHOICES = 300; - const STATUS_MOVED_PERMANENTLY = 301; - const STATUS_FOUND = 302; - const STATUS_SEE_OTHER = 303; - const STATUS_NOT_MODIFIED = 304; - const STATUS_USE_PROXY = 305; - const STATUS_RESERVED = 306; - const STATUS_TEMPORARY_REDIRECT = 307; - const STATUS_PERMANENT_REDIRECT = 308; - // Client Errors 4xx - const STATUS_BAD_REQUEST = 400; - const STATUS_UNAUTHORIZED = 401; - const STATUS_PAYMENT_REQUIRED = 402; - const STATUS_FORBIDDEN = 403; - const STATUS_NOT_FOUND = 404; - const STATUS_METHOD_NOT_ALLOWED = 405; - const STATUS_NOT_ACCEPTABLE = 406; - const STATUS_PROXY_AUTHENTICATION_REQUIRED = 407; - const STATUS_REQUEST_TIMEOUT = 408; - const STATUS_CONFLICT = 409; - const STATUS_GONE = 410; - const STATUS_LENGTH_REQUIRED = 411; - const STATUS_PRECONDITION_FAILED = 412; - const STATUS_PAYLOAD_TOO_LARGE = 413; - const STATUS_URI_TOO_LONG = 414; - const STATUS_UNSUPPORTED_MEDIA_TYPE = 415; - const STATUS_RANGE_NOT_SATISFIABLE = 416; - const STATUS_EXPECTATION_FAILED = 417; - const STATUS_IM_A_TEAPOT = 418; - const STATUS_MISDIRECTED_REQUEST = 421; - const STATUS_UNPROCESSABLE_ENTITY = 422; - const STATUS_LOCKED = 423; - const STATUS_FAILED_DEPENDENCY = 424; - const STATUS_TOO_EARLY = 425; - const STATUS_UPGRADE_REQUIRED = 426; - const STATUS_PRECONDITION_REQUIRED = 428; - const STATUS_TOO_MANY_REQUESTS = 429; - const STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; - const STATUS_UNAVAILABLE_FOR_LEGAL_REASONS = 451; - // Server Errors 5xx - const STATUS_INTERNAL_SERVER_ERROR = 500; - const STATUS_NOT_IMPLEMENTED = 501; - const STATUS_BAD_GATEWAY = 502; - const STATUS_SERVICE_UNAVAILABLE = 503; - const STATUS_GATEWAY_TIMEOUT = 504; - const STATUS_VERSION_NOT_SUPPORTED = 505; - const STATUS_VARIANT_ALSO_NEGOTIATES = 506; - const STATUS_INSUFFICIENT_STORAGE = 507; - const STATUS_LOOP_DETECTED = 508; - const STATUS_NOT_EXTENDED = 510; - const STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511; -} diff --git a/vendor/justinrainbow/json-schema/demo/demo.php b/vendor/justinrainbow/json-schema/demo/demo.php deleted file mode 100644 index 98b518a7b..000000000 --- a/vendor/justinrainbow/json-schema/demo/demo.php +++ /dev/null @@ -1,18 +0,0 @@ -check($data, (object) array('$ref' => 'file://' . realpath('schema.json'))); - -if ($validator->isValid()) { - echo "The supplied JSON validates against the schema.\n"; -} else { - echo "JSON does not validate. Violations:\n"; - foreach ($validator->getErrors() as $error) { - echo sprintf("[%s] %s\n", $error['property'], $error['message']); - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php deleted file mode 100644 index 63968213e..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php +++ /dev/null @@ -1,148 +0,0 @@ -factory = $factory ?: new Factory(); - } - - public function addError(JsonPointer $path = null, $message, $constraint = '', array $more = null) - { - $error = array( - 'property' => $this->convertJsonPointerIntoPropertyPath($path ?: new JsonPointer('')), - 'pointer' => ltrim(strval($path ?: new JsonPointer('')), '#'), - 'message' => $message, - 'constraint' => $constraint, - 'context' => $this->factory->getErrorContext(), - ); - - if ($this->factory->getConfig(Constraint::CHECK_MODE_EXCEPTIONS)) { - throw new ValidationException(sprintf('Error validating %s: %s', $error['pointer'], $error['message'])); - } - - if (is_array($more) && count($more) > 0) { - $error += $more; - } - - $this->errors[] = $error; - $this->errorMask |= $error['context']; - } - - public function addErrors(array $errors) - { - if ($errors) { - $this->errors = array_merge($this->errors, $errors); - $errorMask = &$this->errorMask; - array_walk($errors, function ($error) use (&$errorMask) { - if (isset($error['context'])) { - $errorMask |= $error['context']; - } - }); - } - } - - public function getErrors($errorContext = Validator::ERROR_ALL) - { - if ($errorContext === Validator::ERROR_ALL) { - return $this->errors; - } - - return array_filter($this->errors, function ($error) use ($errorContext) { - if ($errorContext & $error['context']) { - return true; - } - }); - } - - public function numErrors($errorContext = Validator::ERROR_ALL) - { - if ($errorContext === Validator::ERROR_ALL) { - return count($this->errors); - } - - return count($this->getErrors($errorContext)); - } - - public function isValid() - { - return !$this->getErrors(); - } - - /** - * Clears any reported errors. Should be used between - * multiple validation checks. - */ - public function reset() - { - $this->errors = array(); - $this->errorMask = Validator::ERROR_NONE; - } - - /** - * Get the error mask - * - * @return int - */ - public function getErrorMask() - { - return $this->errorMask; - } - - /** - * Recursively cast an associative array to an object - * - * @param array $array - * - * @return object - */ - public static function arrayToObjectRecursive($array) - { - $json = json_encode($array); - if (json_last_error() !== \JSON_ERROR_NONE) { - $message = 'Unable to encode schema array as JSON'; - if (function_exists('json_last_error_msg')) { - $message .= ': ' . json_last_error_msg(); - } - throw new InvalidArgumentException($message); - } - - return (object) json_decode($json); - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php deleted file mode 100644 index d1384b884..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @author Bruno Prieto Reis - */ -class CollectionConstraint extends Constraint -{ - /** - * {@inheritdoc} - */ - public function check(&$value, $schema = null, JsonPointer $path = null, $i = null) - { - // Verify minItems - if (isset($schema->minItems) && count($value) < $schema->minItems) { - $this->addError($path, 'There must be a minimum of ' . $schema->minItems . ' items in the array', 'minItems', array('minItems' => $schema->minItems)); - } - - // Verify maxItems - if (isset($schema->maxItems) && count($value) > $schema->maxItems) { - $this->addError($path, 'There must be a maximum of ' . $schema->maxItems . ' items in the array', 'maxItems', array('maxItems' => $schema->maxItems)); - } - - // Verify uniqueItems - if (isset($schema->uniqueItems) && $schema->uniqueItems) { - $unique = $value; - if (is_array($value) && count($value)) { - $unique = array_map(function ($e) { - return var_export($e, true); - }, $value); - } - if (count(array_unique($unique)) != count($value)) { - $this->addError($path, 'There are no duplicates allowed in the array', 'uniqueItems'); - } - } - - // Verify items - if (isset($schema->items)) { - $this->validateItems($value, $schema, $path, $i); - } - } - - /** - * Validates the items - * - * @param array $value - * @param \stdClass $schema - * @param JsonPointer|null $path - * @param string $i - */ - protected function validateItems(&$value, $schema = null, JsonPointer $path = null, $i = null) - { - if (is_object($schema->items)) { - // just one type definition for the whole array - foreach ($value as $k => &$v) { - $initErrors = $this->getErrors(); - - // First check if its defined in "items" - $this->checkUndefined($v, $schema->items, $path, $k); - - // Recheck with "additionalItems" if the first test fails - if (count($initErrors) < count($this->getErrors()) && (isset($schema->additionalItems) && $schema->additionalItems !== false)) { - $secondErrors = $this->getErrors(); - $this->checkUndefined($v, $schema->additionalItems, $path, $k); - } - - // Reset errors if needed - if (isset($secondErrors) && count($secondErrors) < count($this->getErrors())) { - $this->errors = $secondErrors; - } elseif (isset($secondErrors) && count($secondErrors) === count($this->getErrors())) { - $this->errors = $initErrors; - } - } - unset($v); /* remove dangling reference to prevent any future bugs - * caused by accidentally using $v elsewhere */ - } else { - // Defined item type definitions - foreach ($value as $k => &$v) { - if (array_key_exists($k, $schema->items)) { - $this->checkUndefined($v, $schema->items[$k], $path, $k); - } else { - // Additional items - if (property_exists($schema, 'additionalItems')) { - if ($schema->additionalItems !== false) { - $this->checkUndefined($v, $schema->additionalItems, $path, $k); - } else { - $this->addError( - $path, 'The item ' . $i . '[' . $k . '] is not defined and the definition does not allow additional items', 'additionalItems', array('additionalItems' => $schema->additionalItems)); - } - } else { - // Should be valid against an empty schema - $this->checkUndefined($v, new \stdClass(), $path, $k); - } - } - } - unset($v); /* remove dangling reference to prevent any future bugs - * caused by accidentally using $v elsewhere */ - - // Treat when we have more schema definitions than values, not for empty arrays - if (count($value) > 0) { - for ($k = count($value); $k < count($schema->items); $k++) { - $undefinedInstance = $this->factory->createInstanceFor('undefined'); - $this->checkUndefined($undefinedInstance, $schema->items[$k], $path, $k); - } - } - } - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php deleted file mode 100644 index c61b89ad2..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php +++ /dev/null @@ -1,218 +0,0 @@ - - * @author Bruno Prieto Reis - */ -abstract class Constraint extends BaseConstraint implements ConstraintInterface -{ - protected $inlineSchemaProperty = '$schema'; - - const CHECK_MODE_NONE = 0x00000000; - const CHECK_MODE_NORMAL = 0x00000001; - const CHECK_MODE_TYPE_CAST = 0x00000002; - const CHECK_MODE_COERCE_TYPES = 0x00000004; - const CHECK_MODE_APPLY_DEFAULTS = 0x00000008; - const CHECK_MODE_EXCEPTIONS = 0x00000010; - const CHECK_MODE_DISABLE_FORMAT = 0x00000020; - const CHECK_MODE_ONLY_REQUIRED_DEFAULTS = 0x00000080; - const CHECK_MODE_VALIDATE_SCHEMA = 0x00000100; - - /** - * Bubble down the path - * - * @param JsonPointer|null $path Current path - * @param mixed $i What to append to the path - * - * @return JsonPointer; - */ - protected function incrementPath(JsonPointer $path = null, $i) - { - $path = $path ?: new JsonPointer(''); - - if ($i === null || $i === '') { - return $path; - } - - $path = $path->withPropertyPaths( - array_merge( - $path->getPropertyPaths(), - array($i) - ) - ); - - return $path; - } - - /** - * Validates an array - * - * @param mixed $value - * @param mixed $schema - * @param JsonPointer|null $path - * @param mixed $i - */ - protected function checkArray(&$value, $schema = null, JsonPointer $path = null, $i = null) - { - $validator = $this->factory->createInstanceFor('collection'); - $validator->check($value, $schema, $path, $i); - - $this->addErrors($validator->getErrors()); - } - - /** - * Validates an object - * - * @param mixed $value - * @param mixed $schema - * @param JsonPointer|null $path - * @param mixed $properties - * @param mixed $additionalProperties - * @param mixed $patternProperties - */ - protected function checkObject(&$value, $schema = null, JsonPointer $path = null, $properties = null, - $additionalProperties = null, $patternProperties = null, $appliedDefaults = array()) - { - $validator = $this->factory->createInstanceFor('object'); - $validator->check($value, $schema, $path, $properties, $additionalProperties, $patternProperties, $appliedDefaults); - - $this->addErrors($validator->getErrors()); - } - - /** - * Validates the type of a property - * - * @param mixed $value - * @param mixed $schema - * @param JsonPointer|null $path - * @param mixed $i - */ - protected function checkType(&$value, $schema = null, JsonPointer $path = null, $i = null) - { - $validator = $this->factory->createInstanceFor('type'); - $validator->check($value, $schema, $path, $i); - - $this->addErrors($validator->getErrors()); - } - - /** - * Checks a undefined element - * - * @param mixed $value - * @param mixed $schema - * @param JsonPointer|null $path - * @param mixed $i - */ - protected function checkUndefined(&$value, $schema = null, JsonPointer $path = null, $i = null, $fromDefault = false) - { - $validator = $this->factory->createInstanceFor('undefined'); - - $validator->check($value, $this->factory->getSchemaStorage()->resolveRefSchema($schema), $path, $i, $fromDefault); - - $this->addErrors($validator->getErrors()); - } - - /** - * Checks a string element - * - * @param mixed $value - * @param mixed $schema - * @param JsonPointer|null $path - * @param mixed $i - */ - protected function checkString($value, $schema = null, JsonPointer $path = null, $i = null) - { - $validator = $this->factory->createInstanceFor('string'); - $validator->check($value, $schema, $path, $i); - - $this->addErrors($validator->getErrors()); - } - - /** - * Checks a number element - * - * @param mixed $value - * @param mixed $schema - * @param JsonPointer $path - * @param mixed $i - */ - protected function checkNumber($value, $schema = null, JsonPointer $path = null, $i = null) - { - $validator = $this->factory->createInstanceFor('number'); - $validator->check($value, $schema, $path, $i); - - $this->addErrors($validator->getErrors()); - } - - /** - * Checks a enum element - * - * @param mixed $value - * @param mixed $schema - * @param JsonPointer|null $path - * @param mixed $i - */ - protected function checkEnum($value, $schema = null, JsonPointer $path = null, $i = null) - { - $validator = $this->factory->createInstanceFor('enum'); - $validator->check($value, $schema, $path, $i); - - $this->addErrors($validator->getErrors()); - } - - /** - * Checks format of an element - * - * @param mixed $value - * @param mixed $schema - * @param JsonPointer|null $path - * @param mixed $i - */ - protected function checkFormat($value, $schema = null, JsonPointer $path = null, $i = null) - { - $validator = $this->factory->createInstanceFor('format'); - $validator->check($value, $schema, $path, $i); - - $this->addErrors($validator->getErrors()); - } - - /** - * Get the type check based on the set check mode. - * - * @return TypeCheck\TypeCheckInterface - */ - protected function getTypeCheck() - { - return $this->factory->getTypeCheck(); - } - - /** - * @param JsonPointer $pointer - * - * @return string property path - */ - protected function convertJsonPointerIntoPropertyPath(JsonPointer $pointer) - { - $result = array_map( - function ($path) { - return sprintf(is_numeric($path) ? '[%d]' : '.%s', $path); - }, - $pointer->getPropertyPaths() - ); - - return trim(implode('', $result), '.'); - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php deleted file mode 100644 index 442268e68..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php +++ /dev/null @@ -1,65 +0,0 @@ - - */ -interface ConstraintInterface -{ - /** - * returns all collected errors - * - * @return array - */ - public function getErrors(); - - /** - * adds errors to this validator - * - * @param array $errors - */ - public function addErrors(array $errors); - - /** - * adds an error - * - * @param JsonPointer|null $path - * @param string $message - * @param string $constraint the constraint/rule that is broken, e.g.: 'minLength' - * @param array $more more array elements to add to the error - */ - public function addError(JsonPointer $path = null, $message, $constraint='', array $more = null); - - /** - * checks if the validator has not raised errors - * - * @return bool - */ - public function isValid(); - - /** - * invokes the validation of an element - * - * @abstract - * - * @param mixed $value - * @param mixed $schema - * @param JsonPointer|null $path - * @param mixed $i - * - * @throws \JsonSchema\Exception\ExceptionInterface - */ - public function check(&$value, $schema = null, JsonPointer $path = null, $i = null); -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php deleted file mode 100644 index 0fd2b6a0a..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @author Bruno Prieto Reis - */ -class EnumConstraint extends Constraint -{ - /** - * {@inheritdoc} - */ - public function check(&$element, $schema = null, JsonPointer $path = null, $i = null) - { - // Only validate enum if the attribute exists - if ($element instanceof UndefinedConstraint && (!isset($schema->required) || !$schema->required)) { - return; - } - $type = gettype($element); - - foreach ($schema->enum as $enum) { - $enumType = gettype($enum); - if ($this->factory->getConfig(self::CHECK_MODE_TYPE_CAST) && $type == 'array' && $enumType == 'object') { - if ((object) $element == $enum) { - return; - } - } - - if ($type === gettype($enum)) { - if ($type == 'object') { - if ($element == $enum) { - return; - } - } elseif ($element === $enum) { - return; - } - } - } - - $this->addError($path, 'Does not have a value in the enumeration ' . json_encode($schema->enum), 'enum', array('enum' => $schema->enum)); - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php deleted file mode 100644 index 4e771c19c..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php +++ /dev/null @@ -1,220 +0,0 @@ - 'JsonSchema\Constraints\CollectionConstraint', - 'collection' => 'JsonSchema\Constraints\CollectionConstraint', - 'object' => 'JsonSchema\Constraints\ObjectConstraint', - 'type' => 'JsonSchema\Constraints\TypeConstraint', - 'undefined' => 'JsonSchema\Constraints\UndefinedConstraint', - 'string' => 'JsonSchema\Constraints\StringConstraint', - 'number' => 'JsonSchema\Constraints\NumberConstraint', - 'enum' => 'JsonSchema\Constraints\EnumConstraint', - 'format' => 'JsonSchema\Constraints\FormatConstraint', - 'schema' => 'JsonSchema\Constraints\SchemaConstraint', - 'validator' => 'JsonSchema\Validator' - ); - - /** - * @var array - */ - private $instanceCache = array(); - - /** - * @param SchemaStorage $schemaStorage - * @param UriRetrieverInterface $uriRetriever - * @param int $checkMode - */ - public function __construct( - SchemaStorageInterface $schemaStorage = null, - UriRetrieverInterface $uriRetriever = null, - $checkMode = Constraint::CHECK_MODE_NORMAL - ) { - // set provided config options - $this->setConfig($checkMode); - - $this->uriRetriever = $uriRetriever ?: new UriRetriever(); - $this->schemaStorage = $schemaStorage ?: new SchemaStorage($this->uriRetriever); - } - - /** - * Set config values - * - * @param int $checkMode Set checkMode options - does not preserve existing flags - */ - public function setConfig($checkMode = Constraint::CHECK_MODE_NORMAL) - { - $this->checkMode = $checkMode; - } - - /** - * Enable checkMode flags - * - * @param int $options - */ - public function addConfig($options) - { - $this->checkMode |= $options; - } - - /** - * Disable checkMode flags - * - * @param int $options - */ - public function removeConfig($options) - { - $this->checkMode &= ~$options; - } - - /** - * Get checkMode option - * - * @param int $options Options to get, if null then return entire bitmask - * - * @return int - */ - public function getConfig($options = null) - { - if ($options === null) { - return $this->checkMode; - } - - return $this->checkMode & $options; - } - - /** - * @return UriRetrieverInterface - */ - public function getUriRetriever() - { - return $this->uriRetriever; - } - - public function getSchemaStorage() - { - return $this->schemaStorage; - } - - public function getTypeCheck() - { - if (!isset($this->typeCheck[$this->checkMode])) { - $this->typeCheck[$this->checkMode] = ($this->checkMode & Constraint::CHECK_MODE_TYPE_CAST) - ? new TypeCheck\LooseTypeCheck() - : new TypeCheck\StrictTypeCheck(); - } - - return $this->typeCheck[$this->checkMode]; - } - - /** - * @param string $name - * @param string $class - * - * @return Factory - */ - public function setConstraintClass($name, $class) - { - // Ensure class exists - if (!class_exists($class)) { - throw new InvalidArgumentException('Unknown constraint ' . $name); - } - // Ensure class is appropriate - if (!in_array('JsonSchema\Constraints\ConstraintInterface', class_implements($class))) { - throw new InvalidArgumentException('Invalid class ' . $name); - } - $this->constraintMap[$name] = $class; - - return $this; - } - - /** - * Create a constraint instance for the given constraint name. - * - * @param string $constraintName - * - * @throws InvalidArgumentException if is not possible create the constraint instance - * - * @return ConstraintInterface|ObjectConstraint - */ - public function createInstanceFor($constraintName) - { - if (!isset($this->constraintMap[$constraintName])) { - throw new InvalidArgumentException('Unknown constraint ' . $constraintName); - } - - if (!isset($this->instanceCache[$constraintName])) { - $this->instanceCache[$constraintName] = new $this->constraintMap[$constraintName]($this); - } - - return clone $this->instanceCache[$constraintName]; - } - - /** - * Get the error context - * - * @return string - */ - public function getErrorContext() - { - return $this->errorContext; - } - - /** - * Set the error context - * - * @param string $validationContext - */ - public function setErrorContext($errorContext) - { - $this->errorContext = $errorContext; - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php deleted file mode 100644 index 578cdb14d..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php +++ /dev/null @@ -1,214 +0,0 @@ - - * - * @see http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.23 - */ -class FormatConstraint extends Constraint -{ - /** - * {@inheritdoc} - */ - public function check(&$element, $schema = null, JsonPointer $path = null, $i = null) - { - if (!isset($schema->format) || $this->factory->getConfig(self::CHECK_MODE_DISABLE_FORMAT)) { - return; - } - - switch ($schema->format) { - case 'date': - if (!$date = $this->validateDateTime($element, 'Y-m-d')) { - $this->addError($path, sprintf('Invalid date %s, expected format YYYY-MM-DD', json_encode($element)), 'format', array('format' => $schema->format)); - } - break; - - case 'time': - if (!$this->validateDateTime($element, 'H:i:s')) { - $this->addError($path, sprintf('Invalid time %s, expected format hh:mm:ss', json_encode($element)), 'format', array('format' => $schema->format)); - } - break; - - case 'date-time': - if (null === Rfc3339::createFromString($element)) { - $this->addError($path, sprintf('Invalid date-time %s, expected format YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss+hh:mm', json_encode($element)), 'format', array('format' => $schema->format)); - } - break; - - case 'utc-millisec': - if (!$this->validateDateTime($element, 'U')) { - $this->addError($path, sprintf('Invalid time %s, expected integer of milliseconds since Epoch', json_encode($element)), 'format', array('format' => $schema->format)); - } - break; - - case 'regex': - if (!$this->validateRegex($element)) { - $this->addError($path, 'Invalid regex format ' . $element, 'format', array('format' => $schema->format)); - } - break; - - case 'color': - if (!$this->validateColor($element)) { - $this->addError($path, 'Invalid color', 'format', array('format' => $schema->format)); - } - break; - - case 'style': - if (!$this->validateStyle($element)) { - $this->addError($path, 'Invalid style', 'format', array('format' => $schema->format)); - } - break; - - case 'phone': - if (!$this->validatePhone($element)) { - $this->addError($path, 'Invalid phone number', 'format', array('format' => $schema->format)); - } - break; - - case 'uri': - if (null === filter_var($element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE)) { - $this->addError($path, 'Invalid URL format', 'format', array('format' => $schema->format)); - } - break; - - case 'uriref': - case 'uri-reference': - if (null === filter_var($element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE)) { - // FILTER_VALIDATE_URL does not conform to RFC-3986, and cannot handle relative URLs, but - // the json-schema spec uses RFC-3986, so need a bit of hackery to properly validate them. - // See https://tools.ietf.org/html/rfc3986#section-4.2 for additional information. - if (substr($element, 0, 2) === '//') { // network-path reference - $validURL = filter_var('scheme:' . $element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE); - } elseif (substr($element, 0, 1) === '/') { // absolute-path reference - $validURL = filter_var('scheme://host' . $element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE); - } elseif (strlen($element)) { // relative-path reference - $pathParts = explode('/', $element, 2); - if (strpos($pathParts[0], ':') !== false) { - $validURL = null; - } else { - $validURL = filter_var('scheme://host/' . $element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE); - } - } else { - $validURL = null; - } - if ($validURL === null) { - $this->addError($path, 'Invalid URL format', 'format', array('format' => $schema->format)); - } - } - break; - - case 'email': - $filterFlags = FILTER_NULL_ON_FAILURE; - if (defined('FILTER_FLAG_EMAIL_UNICODE')) { - // Only available from PHP >= 7.1.0, so ignore it for coverage checks - $filterFlags |= constant('FILTER_FLAG_EMAIL_UNICODE'); // @codeCoverageIgnore - } - if (null === filter_var($element, FILTER_VALIDATE_EMAIL, $filterFlags)) { - $this->addError($path, 'Invalid email', 'format', array('format' => $schema->format)); - } - break; - - case 'ip-address': - case 'ipv4': - if (null === filter_var($element, FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE | FILTER_FLAG_IPV4)) { - $this->addError($path, 'Invalid IP address', 'format', array('format' => $schema->format)); - } - break; - - case 'ipv6': - if (null === filter_var($element, FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE | FILTER_FLAG_IPV6)) { - $this->addError($path, 'Invalid IP address', 'format', array('format' => $schema->format)); - } - break; - - case 'host-name': - case 'hostname': - if (!$this->validateHostname($element)) { - $this->addError($path, 'Invalid hostname', 'format', array('format' => $schema->format)); - } - break; - - default: - // Empty as it should be: - // The value of this keyword is called a format attribute. It MUST be a string. - // A format attribute can generally only validate a given set of instance types. - // If the type of the instance to validate is not in this set, validation for - // this format attribute and instance SHOULD succeed. - // http://json-schema.org/latest/json-schema-validation.html#anchor105 - break; - } - } - - protected function validateDateTime($datetime, $format) - { - $dt = \DateTime::createFromFormat($format, $datetime); - - if (!$dt) { - return false; - } - - if ($datetime === $dt->format($format)) { - return true; - } - - // handles the case where a non-6 digit microsecond datetime is passed - // which will fail the above string comparison because the passed - // $datetime may be '2000-05-01T12:12:12.123Z' but format() will return - // '2000-05-01T12:12:12.123000Z' - if ((strpos('u', $format) !== -1) && (preg_match('/\.\d+Z$/', $datetime))) { - return true; - } - - return false; - } - - protected function validateRegex($regex) - { - return false !== @preg_match('/' . $regex . '/u', ''); - } - - protected function validateColor($color) - { - if (in_array(strtolower($color), array('aqua', 'black', 'blue', 'fuchsia', - 'gray', 'green', 'lime', 'maroon', 'navy', 'olive', 'orange', 'purple', - 'red', 'silver', 'teal', 'white', 'yellow'))) { - return true; - } - - return preg_match('/^#([a-f0-9]{3}|[a-f0-9]{6})$/i', $color); - } - - protected function validateStyle($style) - { - $properties = explode(';', rtrim($style, ';')); - $invalidEntries = preg_grep('/^\s*[-a-z]+\s*:\s*.+$/i', $properties, PREG_GREP_INVERT); - - return empty($invalidEntries); - } - - protected function validatePhone($phone) - { - return preg_match('/^\+?(\(\d{3}\)|\d{3}) \d{3} \d{4}$/', $phone); - } - - protected function validateHostname($host) - { - $hostnameRegex = '/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/i'; - - return preg_match($hostnameRegex, $host); - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php deleted file mode 100644 index d4c31a469..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @author Bruno Prieto Reis - */ -class NumberConstraint extends Constraint -{ - /** - * {@inheritdoc} - */ - public function check(&$element, $schema = null, JsonPointer $path = null, $i = null) - { - // Verify minimum - if (isset($schema->exclusiveMinimum)) { - if (isset($schema->minimum)) { - if ($schema->exclusiveMinimum && $element <= $schema->minimum) { - $this->addError($path, 'Must have a minimum value of ' . $schema->minimum, 'exclusiveMinimum', array('minimum' => $schema->minimum)); - } elseif ($element < $schema->minimum) { - $this->addError($path, 'Must have a minimum value of ' . $schema->minimum, 'minimum', array('minimum' => $schema->minimum)); - } - } else { - $this->addError($path, 'Use of exclusiveMinimum requires presence of minimum', 'missingMinimum'); - } - } elseif (isset($schema->minimum) && $element < $schema->minimum) { - $this->addError($path, 'Must have a minimum value of ' . $schema->minimum, 'minimum', array('minimum' => $schema->minimum)); - } - - // Verify maximum - if (isset($schema->exclusiveMaximum)) { - if (isset($schema->maximum)) { - if ($schema->exclusiveMaximum && $element >= $schema->maximum) { - $this->addError($path, 'Must have a maximum value of ' . $schema->maximum, 'exclusiveMaximum', array('maximum' => $schema->maximum)); - } elseif ($element > $schema->maximum) { - $this->addError($path, 'Must have a maximum value of ' . $schema->maximum, 'maximum', array('maximum' => $schema->maximum)); - } - } else { - $this->addError($path, 'Use of exclusiveMaximum requires presence of maximum', 'missingMaximum'); - } - } elseif (isset($schema->maximum) && $element > $schema->maximum) { - $this->addError($path, 'Must have a maximum value of ' . $schema->maximum, 'maximum', array('maximum' => $schema->maximum)); - } - - // Verify divisibleBy - Draft v3 - if (isset($schema->divisibleBy) && $this->fmod($element, $schema->divisibleBy) != 0) { - $this->addError($path, 'Is not divisible by ' . $schema->divisibleBy, 'divisibleBy', array('divisibleBy' => $schema->divisibleBy)); - } - - // Verify multipleOf - Draft v4 - if (isset($schema->multipleOf) && $this->fmod($element, $schema->multipleOf) != 0) { - $this->addError($path, 'Must be a multiple of ' . $schema->multipleOf, 'multipleOf', array('multipleOf' => $schema->multipleOf)); - } - - $this->checkFormat($element, $schema, $path, $i); - } - - private function fmod($number1, $number2) - { - $modulus = ($number1 - round($number1 / $number2) * $number2); - $precision = 0.0000000001; - - if (-$precision < $modulus && $modulus < $precision) { - return 0.0; - } - - return $modulus; - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php deleted file mode 100644 index 0010d2941..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php +++ /dev/null @@ -1,192 +0,0 @@ - - * @author Bruno Prieto Reis - */ -class ObjectConstraint extends Constraint -{ - /** - * @var array List of properties to which a default value has been applied - */ - protected $appliedDefaults = array(); - - /** - * {@inheritdoc} - */ - public function check(&$element, $schema = null, JsonPointer $path = null, $properties = null, - $additionalProp = null, $patternProperties = null, $appliedDefaults = array()) - { - if ($element instanceof UndefinedConstraint) { - return; - } - - $this->appliedDefaults = $appliedDefaults; - - $matches = array(); - if ($patternProperties) { - // validate the element pattern properties - $matches = $this->validatePatternProperties($element, $path, $patternProperties); - } - - if ($properties) { - // validate the element properties - $this->validateProperties($element, $properties, $path); - } - - // validate additional element properties & constraints - $this->validateElement($element, $matches, $schema, $path, $properties, $additionalProp); - } - - public function validatePatternProperties($element, JsonPointer $path = null, $patternProperties) - { - $try = array('/', '#', '+', '~', '%'); - $matches = array(); - foreach ($patternProperties as $pregex => $schema) { - $delimiter = '/'; - // Choose delimiter. Necessary for patterns like ^/ , otherwise you get error - foreach ($try as $delimiter) { - if (strpos($pregex, $delimiter) === false) { // safe to use - break; - } - } - - // Validate the pattern before using it to test for matches - if (@preg_match($delimiter . $pregex . $delimiter . 'u', '') === false) { - $this->addError($path, 'The pattern "' . $pregex . '" is invalid', 'pregex', array('pregex' => $pregex)); - continue; - } - foreach ($element as $i => $value) { - if (preg_match($delimiter . $pregex . $delimiter . 'u', $i)) { - $matches[] = $i; - $this->checkUndefined($value, $schema ?: new \stdClass(), $path, $i, in_array($i, $this->appliedDefaults)); - } - } - } - - return $matches; - } - - /** - * Validates the element properties - * - * @param \StdClass $element Element to validate - * @param array $matches Matches from patternProperties (if any) - * @param \StdClass $schema ObjectConstraint definition - * @param JsonPointer|null $path Current test path - * @param \StdClass $properties Properties - * @param mixed $additionalProp Additional properties - */ - public function validateElement($element, $matches, $schema = null, JsonPointer $path = null, - $properties = null, $additionalProp = null) - { - $this->validateMinMaxConstraint($element, $schema, $path); - - foreach ($element as $i => $value) { - $definition = $this->getProperty($properties, $i); - - // no additional properties allowed - if (!in_array($i, $matches) && $additionalProp === false && $this->inlineSchemaProperty !== $i && !$definition) { - $this->addError($path, 'The property ' . $i . ' is not defined and the definition does not allow additional properties', 'additionalProp'); - } - - // additional properties defined - if (!in_array($i, $matches) && $additionalProp && !$definition) { - if ($additionalProp === true) { - $this->checkUndefined($value, null, $path, $i, in_array($i, $this->appliedDefaults)); - } else { - $this->checkUndefined($value, $additionalProp, $path, $i, in_array($i, $this->appliedDefaults)); - } - } - - // property requires presence of another - $require = $this->getProperty($definition, 'requires'); - if ($require && !$this->getProperty($element, $require)) { - $this->addError($path, 'The presence of the property ' . $i . ' requires that ' . $require . ' also be present', 'requires'); - } - - $property = $this->getProperty($element, $i, $this->factory->createInstanceFor('undefined')); - if (is_object($property)) { - $this->validateMinMaxConstraint(!($property instanceof UndefinedConstraint) ? $property : $element, $definition, $path); - } - } - } - - /** - * Validates the definition properties - * - * @param \stdClass $element Element to validate - * @param \stdClass $properties Property definitions - * @param JsonPointer|null $path Path? - */ - public function validateProperties(&$element, $properties = null, JsonPointer $path = null) - { - $undefinedConstraint = $this->factory->createInstanceFor('undefined'); - - foreach ($properties as $i => $value) { - $property = &$this->getProperty($element, $i, $undefinedConstraint); - $definition = $this->getProperty($properties, $i); - - if (is_object($definition)) { - // Undefined constraint will check for is_object() and quit if is not - so why pass it? - $this->checkUndefined($property, $definition, $path, $i, in_array($i, $this->appliedDefaults)); - } - } - } - - /** - * retrieves a property from an object or array - * - * @param mixed $element Element to validate - * @param string $property Property to retrieve - * @param mixed $fallback Default value if property is not found - * - * @return mixed - */ - protected function &getProperty(&$element, $property, $fallback = null) - { - if (is_array($element) && (isset($element[$property]) || array_key_exists($property, $element)) /*$this->checkMode == self::CHECK_MODE_TYPE_CAST*/) { - return $element[$property]; - } elseif (is_object($element) && property_exists($element, $property)) { - return $element->$property; - } - - return $fallback; - } - - /** - * validating minimum and maximum property constraints (if present) against an element - * - * @param \stdClass $element Element to validate - * @param \stdClass $objectDefinition ObjectConstraint definition - * @param JsonPointer|null $path Path to test? - */ - protected function validateMinMaxConstraint($element, $objectDefinition, JsonPointer $path = null) - { - // Verify minimum number of properties - if (isset($objectDefinition->minProperties) && !is_object($objectDefinition->minProperties)) { - if ($this->getTypeCheck()->propertyCount($element) < $objectDefinition->minProperties) { - $this->addError($path, 'Must contain a minimum of ' . $objectDefinition->minProperties . ' properties', 'minProperties', array('minProperties' => $objectDefinition->minProperties)); - } - } - // Verify maximum number of properties - if (isset($objectDefinition->maxProperties) && !is_object($objectDefinition->maxProperties)) { - if ($this->getTypeCheck()->propertyCount($element) > $objectDefinition->maxProperties) { - $this->addError($path, 'Must contain no more than ' . $objectDefinition->maxProperties . ' properties', 'maxProperties', array('maxProperties' => $objectDefinition->maxProperties)); - } - } - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php deleted file mode 100644 index db665ad38..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @author Bruno Prieto Reis - */ -class SchemaConstraint extends Constraint -{ - const DEFAULT_SCHEMA_SPEC = 'http://json-schema.org/draft-04/schema#'; - - /** - * {@inheritdoc} - */ - public function check(&$element, $schema = null, JsonPointer $path = null, $i = null) - { - if ($schema !== null) { - // passed schema - $validationSchema = $schema; - } elseif ($this->getTypeCheck()->propertyExists($element, $this->inlineSchemaProperty)) { - // inline schema - $validationSchema = $this->getTypeCheck()->propertyGet($element, $this->inlineSchemaProperty); - } else { - throw new InvalidArgumentException('no schema found to verify against'); - } - - // cast array schemas to object - if (is_array($validationSchema)) { - $validationSchema = BaseConstraint::arrayToObjectRecursive($validationSchema); - } - - // validate schema against whatever is defined in $validationSchema->$schema. If no - // schema is defined, assume self::DEFAULT_SCHEMA_SPEC (currently draft-04). - if ($this->factory->getConfig(self::CHECK_MODE_VALIDATE_SCHEMA)) { - if (!$this->getTypeCheck()->isObject($validationSchema)) { - throw new RuntimeException('Cannot validate the schema of a non-object'); - } - if ($this->getTypeCheck()->propertyExists($validationSchema, '$schema')) { - $schemaSpec = $this->getTypeCheck()->propertyGet($validationSchema, '$schema'); - } else { - $schemaSpec = self::DEFAULT_SCHEMA_SPEC; - } - - // get the spec schema - $schemaStorage = $this->factory->getSchemaStorage(); - if (!$this->getTypeCheck()->isObject($schemaSpec)) { - $schemaSpec = $schemaStorage->getSchema($schemaSpec); - } - - // save error count, config & subtract CHECK_MODE_VALIDATE_SCHEMA - $initialErrorCount = $this->numErrors(); - $initialConfig = $this->factory->getConfig(); - $initialContext = $this->factory->getErrorContext(); - $this->factory->removeConfig(self::CHECK_MODE_VALIDATE_SCHEMA | self::CHECK_MODE_APPLY_DEFAULTS); - $this->factory->addConfig(self::CHECK_MODE_TYPE_CAST); - $this->factory->setErrorContext(Validator::ERROR_SCHEMA_VALIDATION); - - // validate schema - try { - $this->check($validationSchema, $schemaSpec); - } catch (\Exception $e) { - if ($this->factory->getConfig(self::CHECK_MODE_EXCEPTIONS)) { - throw new InvalidSchemaException('Schema did not pass validation', 0, $e); - } - } - if ($this->numErrors() > $initialErrorCount) { - $this->addError($path, 'Schema is not valid', 'schema'); - } - - // restore the initial config - $this->factory->setConfig($initialConfig); - $this->factory->setErrorContext($initialContext); - } - - // validate element against $validationSchema - $this->checkUndefined($element, $validationSchema, $path, $i); - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php deleted file mode 100644 index c66af1ed6..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @author Bruno Prieto Reis - */ -class StringConstraint extends Constraint -{ - /** - * {@inheritdoc} - */ - public function check(&$element, $schema = null, JsonPointer $path = null, $i = null) - { - // Verify maxLength - if (isset($schema->maxLength) && $this->strlen($element) > $schema->maxLength) { - $this->addError($path, 'Must be at most ' . $schema->maxLength . ' characters long', 'maxLength', array( - 'maxLength' => $schema->maxLength, - )); - } - - //verify minLength - if (isset($schema->minLength) && $this->strlen($element) < $schema->minLength) { - $this->addError($path, 'Must be at least ' . $schema->minLength . ' characters long', 'minLength', array( - 'minLength' => $schema->minLength, - )); - } - - // Verify a regex pattern - if (isset($schema->pattern) && !preg_match('#' . str_replace('#', '\\#', $schema->pattern) . '#u', $element)) { - $this->addError($path, 'Does not match the regex pattern ' . $schema->pattern, 'pattern', array( - 'pattern' => $schema->pattern, - )); - } - - $this->checkFormat($element, $schema, $path, $i); - } - - private function strlen($string) - { - if (extension_loaded('mbstring')) { - return mb_strlen($string, mb_detect_encoding($string)); - } - - // mbstring is present on all test platforms, so strlen() can be ignored for coverage - return strlen($string); // @codeCoverageIgnore - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/LooseTypeCheck.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/LooseTypeCheck.php deleted file mode 100644 index 984288539..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/LooseTypeCheck.php +++ /dev/null @@ -1,68 +0,0 @@ -{$property}; - } - - return $value[$property]; - } - - public static function propertySet(&$value, $property, $data) - { - if (is_object($value)) { - $value->{$property} = $data; - } else { - $value[$property] = $data; - } - } - - public static function propertyExists($value, $property) - { - if (is_object($value)) { - return property_exists($value, $property); - } - - return array_key_exists($property, $value); - } - - public static function propertyCount($value) - { - if (is_object($value)) { - return count(get_object_vars($value)); - } - - return count($value); - } - - /** - * Check if the provided array is associative or not - * - * @param array $arr - * - * @return bool - */ - private static function isAssociativeArray($arr) - { - return array_keys($arr) !== range(0, count($arr) - 1); - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/StrictTypeCheck.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/StrictTypeCheck.php deleted file mode 100644 index 59fa12be7..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/StrictTypeCheck.php +++ /dev/null @@ -1,40 +0,0 @@ -{$property}; - } - - public static function propertySet(&$value, $property, $data) - { - $value->{$property} = $data; - } - - public static function propertyExists($value, $property) - { - return property_exists($value, $property); - } - - public static function propertyCount($value) - { - if (!is_object($value)) { - return 0; - } - - return count(get_object_vars($value)); - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/TypeCheckInterface.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/TypeCheckInterface.php deleted file mode 100644 index 10b40ea0f..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/TypeCheckInterface.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @author Bruno Prieto Reis - */ -class TypeConstraint extends Constraint -{ - /** - * @var array|string[] type wordings for validation error messages - */ - public static $wording = array( - 'integer' => 'an integer', - 'number' => 'a number', - 'boolean' => 'a boolean', - 'object' => 'an object', - 'array' => 'an array', - 'string' => 'a string', - 'null' => 'a null', - 'any' => null, // validation of 'any' is always true so is not needed in message wording - 0 => null, // validation of a false-y value is always true, so not needed as well - ); - - /** - * {@inheritdoc} - */ - public function check(&$value = null, $schema = null, JsonPointer $path = null, $i = null) - { - $type = isset($schema->type) ? $schema->type : null; - $isValid = false; - $wording = array(); - - if (is_array($type)) { - $this->validateTypesArray($value, $type, $wording, $isValid, $path); - } elseif (is_object($type)) { - $this->checkUndefined($value, $type, $path); - - return; - } else { - $isValid = $this->validateType($value, $type); - } - - if ($isValid === false) { - if (!is_array($type)) { - $this->validateTypeNameWording($type); - $wording[] = self::$wording[$type]; - } - $this->addError($path, ucwords(gettype($value)) . ' value found, but ' . - $this->implodeWith($wording, ', ', 'or') . ' is required', 'type'); - } - } - - /** - * Validates the given $value against the array of types in $type. Sets the value - * of $isValid to true, if at least one $type mateches the type of $value or the value - * passed as $isValid is already true. - * - * @param mixed $value Value to validate - * @param array $type TypeConstraints to check agains - * @param array $validTypesWording An array of wordings of the valid types of the array $type - * @param bool $isValid The current validation value - * @param $path - */ - protected function validateTypesArray(&$value, array $type, &$validTypesWording, &$isValid, $path) - { - foreach ($type as $tp) { - // $tp can be an object, if it's a schema instead of a simple type, validate it - // with a new type constraint - if (is_object($tp)) { - if (!$isValid) { - $validator = $this->factory->createInstanceFor('type'); - $subSchema = new \stdClass(); - $subSchema->type = $tp; - $validator->check($value, $subSchema, $path, null); - $error = $validator->getErrors(); - $isValid = !(bool) $error; - $validTypesWording[] = self::$wording['object']; - } - } else { - $this->validateTypeNameWording($tp); - $validTypesWording[] = self::$wording[$tp]; - if (!$isValid) { - $isValid = $this->validateType($value, $tp); - } - } - } - } - - /** - * Implodes the given array like implode() with turned around parameters and with the - * difference, that, if $listEnd isn't false, the last element delimiter is $listEnd instead of - * $delimiter. - * - * @param array $elements The elements to implode - * @param string $delimiter The delimiter to use - * @param bool $listEnd The last delimiter to use (defaults to $delimiter) - * - * @return string - */ - protected function implodeWith(array $elements, $delimiter = ', ', $listEnd = false) - { - if ($listEnd === false || !isset($elements[1])) { - return implode($delimiter, $elements); - } - $lastElement = array_slice($elements, -1); - $firsElements = join($delimiter, array_slice($elements, 0, -1)); - $implodedElements = array_merge(array($firsElements), $lastElement); - - return join(" $listEnd ", $implodedElements); - } - - /** - * Validates the given $type, if there's an associated self::$wording. If not, throws an - * exception. - * - * @param string $type The type to validate - * - * @throws StandardUnexpectedValueException - */ - protected function validateTypeNameWording($type) - { - if (!isset(self::$wording[$type])) { - throw new StandardUnexpectedValueException( - sprintf( - 'No wording for %s available, expected wordings are: [%s]', - var_export($type, true), - implode(', ', array_filter(self::$wording))) - ); - } - } - - /** - * Verifies that a given value is of a certain type - * - * @param mixed $value Value to validate - * @param string $type TypeConstraint to check against - * - * @throws InvalidArgumentException - * - * @return bool - */ - protected function validateType(&$value, $type) - { - //mostly the case for inline schema - if (!$type) { - return true; - } - - if ('any' === $type) { - return true; - } - - if ('object' === $type) { - return $this->getTypeCheck()->isObject($value); - } - - if ('array' === $type) { - return $this->getTypeCheck()->isArray($value); - } - - $coerce = $this->factory->getConfig(Constraint::CHECK_MODE_COERCE_TYPES); - - if ('integer' === $type) { - if ($coerce) { - $value = $this->toInteger($value); - } - - return is_int($value); - } - - if ('number' === $type) { - if ($coerce) { - $value = $this->toNumber($value); - } - - return is_numeric($value) && !is_string($value); - } - - if ('boolean' === $type) { - if ($coerce) { - $value = $this->toBoolean($value); - } - - return is_bool($value); - } - - if ('string' === $type) { - return is_string($value); - } - - if ('email' === $type) { - return is_string($value); - } - - if ('null' === $type) { - return is_null($value); - } - - throw new InvalidArgumentException((is_object($value) ? 'object' : $value) . ' is an invalid type for ' . $type); - } - - /** - * Converts a value to boolean. For example, "true" becomes true. - * - * @param $value The value to convert to boolean - * - * @return bool|mixed - */ - protected function toBoolean($value) - { - if ($value === 'true') { - return true; - } - - if ($value === 'false') { - return false; - } - - return $value; - } - - /** - * Converts a numeric string to a number. For example, "4" becomes 4. - * - * @param mixed $value the value to convert to a number - * - * @return int|float|mixed - */ - protected function toNumber($value) - { - if (is_numeric($value)) { - return $value + 0; // cast to number - } - - return $value; - } - - protected function toInteger($value) - { - if (is_numeric($value) && (int) $value == $value) { - return (int) $value; // cast to number - } - - return $value; - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php deleted file mode 100644 index 8effd4ba2..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php +++ /dev/null @@ -1,419 +0,0 @@ - - * @author Bruno Prieto Reis - */ -class UndefinedConstraint extends Constraint -{ - /** - * @var array List of properties to which a default value has been applied - */ - protected $appliedDefaults = array(); - - /** - * {@inheritdoc} - */ - public function check(&$value, $schema = null, JsonPointer $path = null, $i = null, $fromDefault = false) - { - if (is_null($schema) || !is_object($schema)) { - return; - } - - $path = $this->incrementPath($path ?: new JsonPointer(''), $i); - if ($fromDefault) { - $path->setFromDefault(); - } - - // check special properties - $this->validateCommonProperties($value, $schema, $path, $i); - - // check allOf, anyOf, and oneOf properties - $this->validateOfProperties($value, $schema, $path, ''); - - // check known types - $this->validateTypes($value, $schema, $path, $i); - } - - /** - * Validates the value against the types - * - * @param mixed $value - * @param mixed $schema - * @param JsonPointer $path - * @param string $i - */ - public function validateTypes(&$value, $schema, JsonPointer $path, $i = null) - { - // check array - if ($this->getTypeCheck()->isArray($value)) { - $this->checkArray($value, $schema, $path, $i); - } - - // check object - if (LooseTypeCheck::isObject($value)) { // object processing should always be run on assoc arrays, - // so use LooseTypeCheck here even if CHECK_MODE_TYPE_CAST - // is not set (i.e. don't use $this->getTypeCheck() here). - $this->checkObject( - $value, - $schema, - $path, - isset($schema->properties) ? $schema->properties : null, - isset($schema->additionalProperties) ? $schema->additionalProperties : null, - isset($schema->patternProperties) ? $schema->patternProperties : null, - $this->appliedDefaults - ); - } - - // check string - if (is_string($value)) { - $this->checkString($value, $schema, $path, $i); - } - - // check numeric - if (is_numeric($value)) { - $this->checkNumber($value, $schema, $path, $i); - } - - // check enum - if (isset($schema->enum)) { - $this->checkEnum($value, $schema, $path, $i); - } - } - - /** - * Validates common properties - * - * @param mixed $value - * @param mixed $schema - * @param JsonPointer $path - * @param string $i - */ - protected function validateCommonProperties(&$value, $schema, JsonPointer $path, $i = '') - { - // if it extends another schema, it must pass that schema as well - if (isset($schema->extends)) { - if (is_string($schema->extends)) { - $schema->extends = $this->validateUri($schema, $schema->extends); - } - if (is_array($schema->extends)) { - foreach ($schema->extends as $extends) { - $this->checkUndefined($value, $extends, $path, $i); - } - } else { - $this->checkUndefined($value, $schema->extends, $path, $i); - } - } - - // Apply default values from schema - if (!$path->fromDefault()) { - $this->applyDefaultValues($value, $schema, $path); - } - - // Verify required values - if ($this->getTypeCheck()->isObject($value)) { - if (!($value instanceof self) && isset($schema->required) && is_array($schema->required)) { - // Draft 4 - Required is an array of strings - e.g. "required": ["foo", ...] - foreach ($schema->required as $required) { - if (!$this->getTypeCheck()->propertyExists($value, $required)) { - $this->addError( - $this->incrementPath($path ?: new JsonPointer(''), $required), - 'The property ' . $required . ' is required', - 'required' - ); - } - } - } elseif (isset($schema->required) && !is_array($schema->required)) { - // Draft 3 - Required attribute - e.g. "foo": {"type": "string", "required": true} - if ($schema->required && $value instanceof self) { - $propertyPaths = $path->getPropertyPaths(); - $propertyName = end($propertyPaths); - $this->addError( - $path, - 'The property ' . $propertyName . ' is required', - 'required' - ); - } - } else { - // if the value is both undefined and not required, skip remaining checks - // in this method which assume an actual, defined instance when validating. - if ($value instanceof self) { - return; - } - } - } - - // Verify type - if (!($value instanceof self)) { - $this->checkType($value, $schema, $path, $i); - } - - // Verify disallowed items - if (isset($schema->disallow)) { - $initErrors = $this->getErrors(); - - $typeSchema = new \stdClass(); - $typeSchema->type = $schema->disallow; - $this->checkType($value, $typeSchema, $path); - - // if no new errors were raised it must be a disallowed value - if (count($this->getErrors()) == count($initErrors)) { - $this->addError($path, 'Disallowed value was matched', 'disallow'); - } else { - $this->errors = $initErrors; - } - } - - if (isset($schema->not)) { - $initErrors = $this->getErrors(); - $this->checkUndefined($value, $schema->not, $path, $i); - - // if no new errors were raised then the instance validated against the "not" schema - if (count($this->getErrors()) == count($initErrors)) { - $this->addError($path, 'Matched a schema which it should not', 'not'); - } else { - $this->errors = $initErrors; - } - } - - // Verify that dependencies are met - if (isset($schema->dependencies) && $this->getTypeCheck()->isObject($value)) { - $this->validateDependencies($value, $schema->dependencies, $path); - } - } - - /** - * Check whether a default should be applied for this value - * - * @param mixed $schema - * @param mixed $parentSchema - * @param bool $requiredOnly - * - * @return bool - */ - private function shouldApplyDefaultValue($requiredOnly, $schema, $name = null, $parentSchema = null) - { - // required-only mode is off - if (!$requiredOnly) { - return true; - } - // draft-04 required is set - if ( - $name !== null - && isset($parentSchema->required) - && is_array($parentSchema->required) - && in_array($name, $parentSchema->required) - ) { - return true; - } - // draft-03 required is set - if (isset($schema->required) && !is_array($schema->required) && $schema->required) { - return true; - } - // default case - return false; - } - - /** - * Apply default values - * - * @param mixed $value - * @param mixed $schema - * @param JsonPointer $path - */ - protected function applyDefaultValues(&$value, $schema, $path) - { - // only apply defaults if feature is enabled - if (!$this->factory->getConfig(self::CHECK_MODE_APPLY_DEFAULTS)) { - return; - } - - // apply defaults if appropriate - $requiredOnly = $this->factory->getConfig(self::CHECK_MODE_ONLY_REQUIRED_DEFAULTS); - if (isset($schema->properties) && LooseTypeCheck::isObject($value)) { - // $value is an object or assoc array, and properties are defined - treat as an object - foreach ($schema->properties as $currentProperty => $propertyDefinition) { - $propertyDefinition = $this->factory->getSchemaStorage()->resolveRefSchema($propertyDefinition); - if ( - !LooseTypeCheck::propertyExists($value, $currentProperty) - && property_exists($propertyDefinition, 'default') - && $this->shouldApplyDefaultValue($requiredOnly, $propertyDefinition, $currentProperty, $schema) - ) { - // assign default value - if (is_object($propertyDefinition->default)) { - LooseTypeCheck::propertySet($value, $currentProperty, clone $propertyDefinition->default); - } else { - LooseTypeCheck::propertySet($value, $currentProperty, $propertyDefinition->default); - } - $this->appliedDefaults[] = $currentProperty; - } - } - } elseif (isset($schema->items) && LooseTypeCheck::isArray($value)) { - $items = array(); - if (LooseTypeCheck::isArray($schema->items)) { - $items = $schema->items; - } elseif (isset($schema->minItems) && count($value) < $schema->minItems) { - $items = array_fill(count($value), $schema->minItems - count($value), $schema->items); - } - // $value is an array, and items are defined - treat as plain array - foreach ($items as $currentItem => $itemDefinition) { - $itemDefinition = $this->factory->getSchemaStorage()->resolveRefSchema($itemDefinition); - if ( - !array_key_exists($currentItem, $value) - && property_exists($itemDefinition, 'default') - && $this->shouldApplyDefaultValue($requiredOnly, $itemDefinition)) { - if (is_object($itemDefinition->default)) { - $value[$currentItem] = clone $itemDefinition->default; - } else { - $value[$currentItem] = $itemDefinition->default; - } - } - $path->setFromDefault(); - } - } elseif ( - $value instanceof self - && property_exists($schema, 'default') - && $this->shouldApplyDefaultValue($requiredOnly, $schema)) { - // $value is a leaf, not a container - apply the default directly - $value = is_object($schema->default) ? clone $schema->default : $schema->default; - $path->setFromDefault(); - } - } - - /** - * Validate allOf, anyOf, and oneOf properties - * - * @param mixed $value - * @param mixed $schema - * @param JsonPointer $path - * @param string $i - */ - protected function validateOfProperties(&$value, $schema, JsonPointer $path, $i = '') - { - // Verify type - if ($value instanceof self) { - return; - } - - if (isset($schema->allOf)) { - $isValid = true; - foreach ($schema->allOf as $allOf) { - $initErrors = $this->getErrors(); - $this->checkUndefined($value, $allOf, $path, $i); - $isValid = $isValid && (count($this->getErrors()) == count($initErrors)); - } - if (!$isValid) { - $this->addError($path, 'Failed to match all schemas', 'allOf'); - } - } - - if (isset($schema->anyOf)) { - $isValid = false; - $startErrors = $this->getErrors(); - $caughtException = null; - foreach ($schema->anyOf as $anyOf) { - $initErrors = $this->getErrors(); - try { - $this->checkUndefined($value, $anyOf, $path, $i); - if ($isValid = (count($this->getErrors()) == count($initErrors))) { - break; - } - } catch (ValidationException $e) { - $isValid = false; - } - } - if (!$isValid) { - $this->addError($path, 'Failed to match at least one schema', 'anyOf'); - } else { - $this->errors = $startErrors; - } - } - - if (isset($schema->oneOf)) { - $allErrors = array(); - $matchedSchemas = 0; - $startErrors = $this->getErrors(); - foreach ($schema->oneOf as $oneOf) { - try { - $this->errors = array(); - $this->checkUndefined($value, $oneOf, $path, $i); - if (count($this->getErrors()) == 0) { - $matchedSchemas++; - } - $allErrors = array_merge($allErrors, array_values($this->getErrors())); - } catch (ValidationException $e) { - // deliberately do nothing here - validation failed, but we want to check - // other schema options in the OneOf field. - } - } - if ($matchedSchemas !== 1) { - $this->addErrors(array_merge($allErrors, $startErrors)); - $this->addError($path, 'Failed to match exactly one schema', 'oneOf'); - } else { - $this->errors = $startErrors; - } - } - } - - /** - * Validate dependencies - * - * @param mixed $value - * @param mixed $dependencies - * @param JsonPointer $path - * @param string $i - */ - protected function validateDependencies($value, $dependencies, JsonPointer $path, $i = '') - { - foreach ($dependencies as $key => $dependency) { - if ($this->getTypeCheck()->propertyExists($value, $key)) { - if (is_string($dependency)) { - // Draft 3 string is allowed - e.g. "dependencies": {"bar": "foo"} - if (!$this->getTypeCheck()->propertyExists($value, $dependency)) { - $this->addError($path, "$key depends on $dependency and $dependency is missing", 'dependencies'); - } - } elseif (is_array($dependency)) { - // Draft 4 must be an array - e.g. "dependencies": {"bar": ["foo"]} - foreach ($dependency as $d) { - if (!$this->getTypeCheck()->propertyExists($value, $d)) { - $this->addError($path, "$key depends on $d and $d is missing", 'dependencies'); - } - } - } elseif (is_object($dependency)) { - // Schema - e.g. "dependencies": {"bar": {"properties": {"foo": {...}}}} - $this->checkUndefined($value, $dependency, $path, $i); - } - } - } - } - - protected function validateUri($schema, $schemaUri = null) - { - $resolver = new UriResolver(); - $retriever = $this->factory->getUriRetriever(); - - $jsonSchema = null; - if ($resolver->isValid($schemaUri)) { - $schemaId = property_exists($schema, 'id') ? $schema->id : null; - $jsonSchema = $retriever->retrieve($schemaId, $schemaUri); - } - - return $jsonSchema; - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Entity/JsonPointer.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Entity/JsonPointer.php deleted file mode 100644 index fcaf5b8d7..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Entity/JsonPointer.php +++ /dev/null @@ -1,161 +0,0 @@ - - */ -class JsonPointer -{ - /** @var string */ - private $filename; - - /** @var string[] */ - private $propertyPaths = array(); - - /** - * @var bool Whether the value at this path was set from a schema default - */ - private $fromDefault = false; - - /** - * @param string $value - * - * @throws InvalidArgumentException when $value is not a string - */ - public function __construct($value) - { - if (!is_string($value)) { - throw new InvalidArgumentException('Ref value must be a string'); - } - - $splitRef = explode('#', $value, 2); - $this->filename = $splitRef[0]; - if (array_key_exists(1, $splitRef)) { - $this->propertyPaths = $this->decodePropertyPaths($splitRef[1]); - } - } - - /** - * @param string $propertyPathString - * - * @return string[] - */ - private function decodePropertyPaths($propertyPathString) - { - $paths = array(); - foreach (explode('/', trim($propertyPathString, '/')) as $path) { - $path = $this->decodePath($path); - if (is_string($path) && '' !== $path) { - $paths[] = $path; - } - } - - return $paths; - } - - /** - * @return array - */ - private function encodePropertyPaths() - { - return array_map( - array($this, 'encodePath'), - $this->getPropertyPaths() - ); - } - - /** - * @param string $path - * - * @return string - */ - private function decodePath($path) - { - return strtr($path, array('~1' => '/', '~0' => '~', '%25' => '%')); - } - - /** - * @param string $path - * - * @return string - */ - private function encodePath($path) - { - return strtr($path, array('/' => '~1', '~' => '~0', '%' => '%25')); - } - - /** - * @return string - */ - public function getFilename() - { - return $this->filename; - } - - /** - * @return string[] - */ - public function getPropertyPaths() - { - return $this->propertyPaths; - } - - /** - * @param array $propertyPaths - * - * @return JsonPointer - */ - public function withPropertyPaths(array $propertyPaths) - { - $new = clone $this; - $new->propertyPaths = $propertyPaths; - - return $new; - } - - /** - * @return string - */ - public function getPropertyPathAsString() - { - return rtrim('#/' . implode('/', $this->encodePropertyPaths()), '/'); - } - - /** - * @return string - */ - public function __toString() - { - return $this->getFilename() . $this->getPropertyPathAsString(); - } - - /** - * Mark the value at this path as being set from a schema default - */ - public function setFromDefault() - { - $this->fromDefault = true; - } - - /** - * Check whether the value at this path was set from a schema default - * - * @return bool - */ - public function fromDefault() - { - return $this->fromDefault; - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ExceptionInterface.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ExceptionInterface.php deleted file mode 100644 index 439bd277e..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ExceptionInterface.php +++ /dev/null @@ -1,7 +0,0 @@ - - */ -class UnresolvableJsonPointerException extends InvalidArgumentException -{ -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.php deleted file mode 100644 index 13b73033d..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.php +++ /dev/null @@ -1,17 +0,0 @@ - - */ -class ObjectIterator implements \Iterator, \Countable -{ - /** @var object */ - private $object; - - /** @var int */ - private $position = 0; - - /** @var array */ - private $data = array(); - - /** @var bool */ - private $initialized = false; - - /** - * @param object $object - */ - public function __construct($object) - { - $this->object = $object; - } - - /** - * {@inheritdoc} - */ - public function current() - { - $this->initialize(); - - return $this->data[$this->position]; - } - - /** - * {@inheritdoc} - */ - public function next() - { - $this->initialize(); - $this->position++; - } - - /** - * {@inheritdoc} - */ - public function key() - { - $this->initialize(); - - return $this->position; - } - - /** - * {@inheritdoc} - */ - public function valid() - { - $this->initialize(); - - return isset($this->data[$this->position]); - } - - /** - * {@inheritdoc} - */ - public function rewind() - { - $this->initialize(); - $this->position = 0; - } - - /** - * {@inheritdoc} - */ - public function count() - { - $this->initialize(); - - return count($this->data); - } - - /** - * Initializer - */ - private function initialize() - { - if (!$this->initialized) { - $this->data = $this->buildDataFromObject($this->object); - $this->initialized = true; - } - } - - /** - * @param object $object - * - * @return array - */ - private function buildDataFromObject($object) - { - $result = array(); - - $stack = new \SplStack(); - $stack->push($object); - - while (!$stack->isEmpty()) { - $current = $stack->pop(); - if (is_object($current)) { - array_push($result, $current); - } - - foreach ($this->getDataFromItem($current) as $propertyName => $propertyValue) { - if (is_object($propertyValue) || is_array($propertyValue)) { - $stack->push($propertyValue); - } - } - } - - return $result; - } - - /** - * @param object|array $item - * - * @return array - */ - private function getDataFromItem($item) - { - if (!is_object($item) && !is_array($item)) { - return array(); - } - - return is_object($item) ? get_object_vars($item) : $item; - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Rfc3339.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Rfc3339.php deleted file mode 100644 index adca581a4..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Rfc3339.php +++ /dev/null @@ -1,30 +0,0 @@ -uriRetriever = $uriRetriever ?: new UriRetriever(); - $this->uriResolver = $uriResolver ?: new UriResolver(); - } - - /** - * @return UriRetrieverInterface - */ - public function getUriRetriever() - { - return $this->uriRetriever; - } - - /** - * @return UriResolverInterface - */ - public function getUriResolver() - { - return $this->uriResolver; - } - - /** - * {@inheritdoc} - */ - public function addSchema($id, $schema = null) - { - if (is_null($schema) && $id !== self::INTERNAL_PROVIDED_SCHEMA_URI) { - // if the schema was user-provided to Validator and is still null, then assume this is - // what the user intended, as there's no way for us to retrieve anything else. User-supplied - // schemas do not have an associated URI when passed via Validator::validate(). - $schema = $this->uriRetriever->retrieve($id); - } - - // cast array schemas to object - if (is_array($schema)) { - $schema = BaseConstraint::arrayToObjectRecursive($schema); - } - - // workaround for bug in draft-03 & draft-04 meta-schemas (id & $ref defined with incorrect format) - // see https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues/177#issuecomment-293051367 - if (is_object($schema) && property_exists($schema, 'id')) { - if ($schema->id == 'http://json-schema.org/draft-04/schema#') { - $schema->properties->id->format = 'uri-reference'; - } elseif ($schema->id == 'http://json-schema.org/draft-03/schema#') { - $schema->properties->id->format = 'uri-reference'; - $schema->properties->{'$ref'}->format = 'uri-reference'; - } - } - - // resolve references - $this->expandRefs($schema, $id); - - $this->schemas[$id] = $schema; - } - - /** - * Recursively resolve all references against the provided base - * - * @param mixed $schema - * @param string $base - */ - private function expandRefs(&$schema, $base = null) - { - if (!is_object($schema)) { - if (is_array($schema)) { - foreach ($schema as &$member) { - $this->expandRefs($member, $base); - } - } - - return; - } - - if (property_exists($schema, 'id') && is_string($schema->id) && $base != $schema->id) { - $base = $this->uriResolver->resolve($schema->id, $base); - } - - if (property_exists($schema, '$ref') && is_string($schema->{'$ref'})) { - $refPointer = new JsonPointer($this->uriResolver->resolve($schema->{'$ref'}, $base)); - $schema->{'$ref'} = (string) $refPointer; - } - - foreach ($schema as &$member) { - $this->expandRefs($member, $base); - } - } - - /** - * {@inheritdoc} - */ - public function getSchema($id) - { - if (!array_key_exists($id, $this->schemas)) { - $this->addSchema($id); - } - - return $this->schemas[$id]; - } - - /** - * {@inheritdoc} - */ - public function resolveRef($ref) - { - $jsonPointer = new JsonPointer($ref); - - // resolve filename for pointer - $fileName = $jsonPointer->getFilename(); - if (!strlen($fileName)) { - throw new UnresolvableJsonPointerException(sprintf( - "Could not resolve fragment '%s': no file is defined", - $jsonPointer->getPropertyPathAsString() - )); - } - - // get & process the schema - $refSchema = $this->getSchema($fileName); - foreach ($jsonPointer->getPropertyPaths() as $path) { - if (is_object($refSchema) && property_exists($refSchema, $path)) { - $refSchema = $this->resolveRefSchema($refSchema->{$path}); - } elseif (is_array($refSchema) && array_key_exists($path, $refSchema)) { - $refSchema = $this->resolveRefSchema($refSchema[$path]); - } else { - throw new UnresolvableJsonPointerException(sprintf( - 'File: %s is found, but could not resolve fragment: %s', - $jsonPointer->getFilename(), - $jsonPointer->getPropertyPathAsString() - )); - } - } - - return $refSchema; - } - - /** - * {@inheritdoc} - */ - public function resolveRefSchema($refSchema) - { - if (is_object($refSchema) && property_exists($refSchema, '$ref') && is_string($refSchema->{'$ref'})) { - $newSchema = $this->resolveRef($refSchema->{'$ref'}); - $refSchema = (object) (get_object_vars($refSchema) + get_object_vars($newSchema)); - unset($refSchema->{'$ref'}); - } - - return $refSchema; - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorageInterface.php b/vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorageInterface.php deleted file mode 100644 index ddaf6633e..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorageInterface.php +++ /dev/null @@ -1,41 +0,0 @@ - - */ -abstract class AbstractRetriever implements UriRetrieverInterface -{ - /** - * Media content type - * - * @var string - */ - protected $contentType; - - /** - * {@inheritdoc} - * - * @see \JsonSchema\Uri\Retrievers\UriRetrieverInterface::getContentType() - */ - public function getContentType() - { - return $this->contentType; - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php deleted file mode 100644 index 81c86037d..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php +++ /dev/null @@ -1,83 +0,0 @@ - - */ -class Curl extends AbstractRetriever -{ - protected $messageBody; - - public function __construct() - { - if (!function_exists('curl_init')) { - // Cannot test this, because curl_init is present on all test platforms plus mock - throw new RuntimeException('cURL not installed'); // @codeCoverageIgnore - } - } - - /** - * {@inheritdoc} - * - * @see \JsonSchema\Uri\Retrievers\UriRetrieverInterface::retrieve() - */ - public function retrieve($uri) - { - $ch = curl_init(); - - curl_setopt($ch, CURLOPT_URL, $uri); - curl_setopt($ch, CURLOPT_HEADER, true); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: ' . Validator::SCHEMA_MEDIA_TYPE)); - - $response = curl_exec($ch); - if (false === $response) { - throw new \JsonSchema\Exception\ResourceNotFoundException('JSON schema not found'); - } - - $this->fetchMessageBody($response); - $this->fetchContentType($response); - - curl_close($ch); - - return $this->messageBody; - } - - /** - * @param string $response cURL HTTP response - */ - private function fetchMessageBody($response) - { - preg_match("/(?:\r\n){2}(.*)$/ms", $response, $match); - $this->messageBody = $match[1]; - } - - /** - * @param string $response cURL HTTP response - * - * @return bool Whether the Content-Type header was found or not - */ - protected function fetchContentType($response) - { - if (0 < preg_match("/Content-Type:(\V*)/ims", $response, $match)) { - $this->contentType = trim($match[1]); - - return true; - } - - return false; - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php deleted file mode 100644 index 7019814f1..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php +++ /dev/null @@ -1,93 +0,0 @@ - - */ -class FileGetContents extends AbstractRetriever -{ - protected $messageBody; - - /** - * {@inheritdoc} - * - * @see \JsonSchema\Uri\Retrievers\UriRetrieverInterface::retrieve() - */ - public function retrieve($uri) - { - $errorMessage = null; - set_error_handler(function ($errno, $errstr) use (&$errorMessage) { - $errorMessage = $errstr; - }); - $response = file_get_contents($uri); - restore_error_handler(); - - if ($errorMessage) { - throw new ResourceNotFoundException($errorMessage); - } - - if (false === $response) { - throw new ResourceNotFoundException('JSON schema not found at ' . $uri); - } - - if ($response == '' - && substr($uri, 0, 7) == 'file://' && substr($uri, -1) == '/' - ) { - throw new ResourceNotFoundException('JSON schema not found at ' . $uri); - } - - $this->messageBody = $response; - if (!empty($http_response_header)) { - // $http_response_header cannot be tested, because it's defined in the method's local scope - // See http://php.net/manual/en/reserved.variables.httpresponseheader.php for more info. - $this->fetchContentType($http_response_header); // @codeCoverageIgnore - } else { // @codeCoverageIgnore - // Could be a "file://" url or something else - fake up the response - $this->contentType = null; - } - - return $this->messageBody; - } - - /** - * @param array $headers HTTP Response Headers - * - * @return bool Whether the Content-Type header was found or not - */ - private function fetchContentType(array $headers) - { - foreach ($headers as $header) { - if ($this->contentType = self::getContentTypeMatchInHeader($header)) { - return true; - } - } - - return false; - } - - /** - * @param string $header - * - * @return string|null - */ - protected static function getContentTypeMatchInHeader($header) - { - if (0 < preg_match("/Content-Type:(\V*)/ims", $header, $match)) { - return trim($match[1]); - } - - return null; - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php deleted file mode 100644 index a663d3417..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php +++ /dev/null @@ -1,56 +0,0 @@ - '{ ... }', - * 'http://acme.com/schemas/address#' => '{ ... }', - * )) - * - * $schema = $retriever->retrieve('http://acme.com/schemas/person#'); - */ -class PredefinedArray extends AbstractRetriever -{ - /** - * Contains schemas as URI => JSON - * - * @var array - */ - private $schemas; - - /** - * Constructor - * - * @param array $schemas - * @param string $contentType - */ - public function __construct(array $schemas, $contentType = Validator::SCHEMA_MEDIA_TYPE) - { - $this->schemas = $schemas; - $this->contentType = $contentType; - } - - /** - * {@inheritdoc} - * - * @see \JsonSchema\Uri\Retrievers\UriRetrieverInterface::retrieve() - */ - public function retrieve($uri) - { - if (!array_key_exists($uri, $this->schemas)) { - throw new \JsonSchema\Exception\ResourceNotFoundException(sprintf( - 'The JSON schema "%s" was not found.', - $uri - )); - } - - return $this->schemas[$uri]; - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php deleted file mode 100644 index 2cc40cf25..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php +++ /dev/null @@ -1,36 +0,0 @@ - - */ -interface UriRetrieverInterface -{ - /** - * Retrieve a schema from the specified URI - * - * @param string $uri URI that resolves to a JSON schema - * - * @throws \JsonSchema\Exception\ResourceNotFoundException - * - * @return mixed string|null - */ - public function retrieve($uri); - - /** - * Get media content type - * - * @return string - */ - public function getContentType(); -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php deleted file mode 100644 index 8ab6650e9..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php +++ /dev/null @@ -1,175 +0,0 @@ - - */ -class UriResolver implements UriResolverInterface -{ - /** - * Parses a URI into five main components - * - * @param string $uri - * - * @return array - */ - public function parse($uri) - { - preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match); - - $components = array(); - if (5 < count($match)) { - $components = array( - 'scheme' => $match[2], - 'authority' => $match[4], - 'path' => $match[5] - ); - } - if (7 < count($match)) { - $components['query'] = $match[7]; - } - if (9 < count($match)) { - $components['fragment'] = $match[9]; - } - - return $components; - } - - /** - * Builds a URI based on n array with the main components - * - * @param array $components - * - * @return string - */ - public function generate(array $components) - { - $uri = $components['scheme'] . '://' - . $components['authority'] - . $components['path']; - - if (array_key_exists('query', $components) && strlen($components['query'])) { - $uri .= '?' . $components['query']; - } - if (array_key_exists('fragment', $components)) { - $uri .= '#' . $components['fragment']; - } - - return $uri; - } - - /** - * {@inheritdoc} - */ - public function resolve($uri, $baseUri = null) - { - // treat non-uri base as local file path - if ( - !is_null($baseUri) && - !filter_var($baseUri, \FILTER_VALIDATE_URL) && - !preg_match('|^[^/]+://|u', $baseUri) - ) { - if (is_file($baseUri)) { - $baseUri = 'file://' . realpath($baseUri); - } elseif (is_dir($baseUri)) { - $baseUri = 'file://' . realpath($baseUri) . '/'; - } else { - $baseUri = 'file://' . getcwd() . '/' . $baseUri; - } - } - - if ($uri == '') { - return $baseUri; - } - - $components = $this->parse($uri); - $path = $components['path']; - - if (!empty($components['scheme'])) { - return $uri; - } - $baseComponents = $this->parse($baseUri); - $basePath = $baseComponents['path']; - - $baseComponents['path'] = self::combineRelativePathWithBasePath($path, $basePath); - if (isset($components['fragment'])) { - $baseComponents['fragment'] = $components['fragment']; - } - - return $this->generate($baseComponents); - } - - /** - * Tries to glue a relative path onto an absolute one - * - * @param string $relativePath - * @param string $basePath - * - * @throws UriResolverException - * - * @return string Merged path - */ - public static function combineRelativePathWithBasePath($relativePath, $basePath) - { - $relativePath = self::normalizePath($relativePath); - if ($relativePath == '') { - return $basePath; - } - if ($relativePath[0] == '/') { - return $relativePath; - } - - $basePathSegments = explode('/', $basePath); - - preg_match('|^/?(\.\./(?:\./)*)*|', $relativePath, $match); - $numLevelUp = strlen($match[0]) /3 + 1; - if ($numLevelUp >= count($basePathSegments)) { - throw new UriResolverException(sprintf("Unable to resolve URI '%s' from base '%s'", $relativePath, $basePath)); - } - - $basePathSegments = array_slice($basePathSegments, 0, -$numLevelUp); - $path = preg_replace('|^/?(\.\./(\./)*)*|', '', $relativePath); - - return implode('/', $basePathSegments) . '/' . $path; - } - - /** - * Normalizes a URI path component by removing dot-slash and double slashes - * - * @param string $path - * - * @return string - */ - private static function normalizePath($path) - { - $path = preg_replace('|((?parse($uri); - - return !empty($components); - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php b/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php deleted file mode 100644 index 41147a2a0..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php +++ /dev/null @@ -1,349 +0,0 @@ - - */ -class UriRetriever implements BaseUriRetrieverInterface -{ - /** - * @var array Map of URL translations - */ - protected $translationMap = array( - // use local copies of the spec schemas - '|^https?://json-schema.org/draft-(0[34])/schema#?|' => 'package://dist/schema/json-schema-draft-$1.json' - ); - - /** - * @var array A list of endpoints for media type check exclusion - */ - protected $allowedInvalidContentTypeEndpoints = array( - 'http://json-schema.org/', - 'https://json-schema.org/' - ); - - /** - * @var null|UriRetrieverInterface - */ - protected $uriRetriever = null; - - /** - * @var array|object[] - * - * @see loadSchema - */ - private $schemaCache = array(); - - /** - * Adds an endpoint to the media type validation exclusion list - * - * @param string $endpoint - */ - public function addInvalidContentTypeEndpoint($endpoint) - { - $this->allowedInvalidContentTypeEndpoints[] = $endpoint; - } - - /** - * Guarantee the correct media type was encountered - * - * @param UriRetrieverInterface $uriRetriever - * @param string $uri - * - * @return bool|void - */ - public function confirmMediaType($uriRetriever, $uri) - { - $contentType = $uriRetriever->getContentType(); - - if (is_null($contentType)) { - // Well, we didn't get an invalid one - return; - } - - if (in_array($contentType, array(Validator::SCHEMA_MEDIA_TYPE, 'application/json'))) { - return; - } - - foreach ($this->allowedInvalidContentTypeEndpoints as $endpoint) { - if (strpos($uri, $endpoint) === 0) { - return true; - } - } - - throw new InvalidSchemaMediaTypeException(sprintf('Media type %s expected', Validator::SCHEMA_MEDIA_TYPE)); - } - - /** - * Get a URI Retriever - * - * If none is specified, sets a default FileGetContents retriever and - * returns that object. - * - * @return UriRetrieverInterface - */ - public function getUriRetriever() - { - if (is_null($this->uriRetriever)) { - $this->setUriRetriever(new FileGetContents()); - } - - return $this->uriRetriever; - } - - /** - * Resolve a schema based on pointer - * - * URIs can have a fragment at the end in the format of - * #/path/to/object and we are to look up the 'path' property of - * the first object then the 'to' and 'object' properties. - * - * @param object $jsonSchema JSON Schema contents - * @param string $uri JSON Schema URI - * - * @throws ResourceNotFoundException - * - * @return object JSON Schema after walking down the fragment pieces - */ - public function resolvePointer($jsonSchema, $uri) - { - $resolver = new UriResolver(); - $parsed = $resolver->parse($uri); - if (empty($parsed['fragment'])) { - return $jsonSchema; - } - - $path = explode('/', $parsed['fragment']); - while ($path) { - $pathElement = array_shift($path); - if (!empty($pathElement)) { - $pathElement = str_replace('~1', '/', $pathElement); - $pathElement = str_replace('~0', '~', $pathElement); - if (!empty($jsonSchema->$pathElement)) { - $jsonSchema = $jsonSchema->$pathElement; - } else { - throw new ResourceNotFoundException( - 'Fragment "' . $parsed['fragment'] . '" not found' - . ' in ' . $uri - ); - } - - if (!is_object($jsonSchema)) { - throw new ResourceNotFoundException( - 'Fragment part "' . $pathElement . '" is no object ' - . ' in ' . $uri - ); - } - } - } - - return $jsonSchema; - } - - /** - * {@inheritdoc} - */ - public function retrieve($uri, $baseUri = null, $translate = true) - { - $resolver = new UriResolver(); - $resolvedUri = $fetchUri = $resolver->resolve($uri, $baseUri); - - //fetch URL without #fragment - $arParts = $resolver->parse($resolvedUri); - if (isset($arParts['fragment'])) { - unset($arParts['fragment']); - $fetchUri = $resolver->generate($arParts); - } - - // apply URI translations - if ($translate) { - $fetchUri = $this->translate($fetchUri); - } - - $jsonSchema = $this->loadSchema($fetchUri); - - // Use the JSON pointer if specified - $jsonSchema = $this->resolvePointer($jsonSchema, $resolvedUri); - - if ($jsonSchema instanceof \stdClass) { - $jsonSchema->id = $resolvedUri; - } - - return $jsonSchema; - } - - /** - * Fetch a schema from the given URI, json-decode it and return it. - * Caches schema objects. - * - * @param string $fetchUri Absolute URI - * - * @return object JSON schema object - */ - protected function loadSchema($fetchUri) - { - if (isset($this->schemaCache[$fetchUri])) { - return $this->schemaCache[$fetchUri]; - } - - $uriRetriever = $this->getUriRetriever(); - $contents = $this->uriRetriever->retrieve($fetchUri); - $this->confirmMediaType($uriRetriever, $fetchUri); - $jsonSchema = json_decode($contents); - - if (JSON_ERROR_NONE < $error = json_last_error()) { - throw new JsonDecodingException($error); - } - - $this->schemaCache[$fetchUri] = $jsonSchema; - - return $jsonSchema; - } - - /** - * Set the URI Retriever - * - * @param UriRetrieverInterface $uriRetriever - * - * @return $this for chaining - */ - public function setUriRetriever(UriRetrieverInterface $uriRetriever) - { - $this->uriRetriever = $uriRetriever; - - return $this; - } - - /** - * Parses a URI into five main components - * - * @param string $uri - * - * @return array - */ - public function parse($uri) - { - preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match); - - $components = array(); - if (5 < count($match)) { - $components = array( - 'scheme' => $match[2], - 'authority' => $match[4], - 'path' => $match[5] - ); - } - - if (7 < count($match)) { - $components['query'] = $match[7]; - } - - if (9 < count($match)) { - $components['fragment'] = $match[9]; - } - - return $components; - } - - /** - * Builds a URI based on n array with the main components - * - * @param array $components - * - * @return string - */ - public function generate(array $components) - { - $uri = $components['scheme'] . '://' - . $components['authority'] - . $components['path']; - - if (array_key_exists('query', $components)) { - $uri .= $components['query']; - } - - if (array_key_exists('fragment', $components)) { - $uri .= $components['fragment']; - } - - return $uri; - } - - /** - * Resolves a URI - * - * @param string $uri Absolute or relative - * @param string $baseUri Optional base URI - * - * @return string - */ - public function resolve($uri, $baseUri = null) - { - $components = $this->parse($uri); - $path = $components['path']; - - if ((array_key_exists('scheme', $components)) && ('http' === $components['scheme'])) { - return $uri; - } - - $baseComponents = $this->parse($baseUri); - $basePath = $baseComponents['path']; - - $baseComponents['path'] = UriResolver::combineRelativePathWithBasePath($path, $basePath); - - return $this->generate($baseComponents); - } - - /** - * @param string $uri - * - * @return bool - */ - public function isValid($uri) - { - $components = $this->parse($uri); - - return !empty($components); - } - - /** - * Set a URL translation rule - */ - public function setTranslation($from, $to) - { - $this->translationMap[$from] = $to; - } - - /** - * Apply URI translation rules - */ - public function translate($uri) - { - foreach ($this->translationMap as $from => $to) { - $uri = preg_replace($from, $to, $uri); - } - - // translate references to local files within the json-schema package - $uri = preg_replace('|^package://|', sprintf('file://%s/', realpath(__DIR__ . '/../../..')), $uri); - - return $uri; - } -} diff --git a/vendor/justinrainbow/json-schema/src/JsonSchema/UriResolverInterface.php b/vendor/justinrainbow/json-schema/src/JsonSchema/UriResolverInterface.php deleted file mode 100644 index 4eb50c03c..000000000 --- a/vendor/justinrainbow/json-schema/src/JsonSchema/UriResolverInterface.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @author Bruno Prieto Reis - * - * @see README.md - */ -class Validator extends BaseConstraint -{ - const SCHEMA_MEDIA_TYPE = 'application/schema+json'; - - const ERROR_NONE = 0x00000000; - const ERROR_ALL = 0xFFFFFFFF; - const ERROR_DOCUMENT_VALIDATION = 0x00000001; - const ERROR_SCHEMA_VALIDATION = 0x00000002; - - /** - * Validates the given data against the schema and returns an object containing the results - * Both the php object and the schema are supposed to be a result of a json_decode call. - * The validation works as defined by the schema proposal in http://json-schema.org. - * - * Note that the first argument is passed by reference, so you must pass in a variable. - */ - public function validate(&$value, $schema = null, $checkMode = null) - { - // make sure $schema is an object - if (is_array($schema)) { - $schema = self::arrayToObjectRecursive($schema); - } - - // set checkMode - $initialCheckMode = $this->factory->getConfig(); - if ($checkMode !== null) { - $this->factory->setConfig($checkMode); - } - - // add provided schema to SchemaStorage with internal URI to allow internal $ref resolution - if (is_object($schema) && property_exists($schema, 'id')) { - $schemaURI = $schema->id; - } else { - $schemaURI = SchemaStorage::INTERNAL_PROVIDED_SCHEMA_URI; - } - $this->factory->getSchemaStorage()->addSchema($schemaURI, $schema); - - $validator = $this->factory->createInstanceFor('schema'); - $validator->check( - $value, - $this->factory->getSchemaStorage()->getSchema($schemaURI) - ); - - $this->factory->setConfig($initialCheckMode); - - $this->addErrors(array_unique($validator->getErrors(), SORT_REGULAR)); - - return $validator->getErrorMask(); - } - - /** - * Alias to validate(), to maintain backwards-compatibility with the previous API - */ - public function check($value, $schema) - { - return $this->validate($value, $schema); - } - - /** - * Alias to validate(), to maintain backwards-compatibility with the previous API - */ - public function coerce(&$value, $schema) - { - return $this->validate($value, $schema, Constraint::CHECK_MODE_COERCE_TYPES); - } -} diff --git a/vendor/psr/container/src/ContainerExceptionInterface.php b/vendor/psr/container/src/ContainerExceptionInterface.php deleted file mode 100644 index cf10b8b4f..000000000 --- a/vendor/psr/container/src/ContainerExceptionInterface.php +++ /dev/null @@ -1,10 +0,0 @@ -getHeaders() as $name => $values) { - * echo $name . ": " . implode(", ", $values); - * } - * - * // Emit headers iteratively: - * foreach ($message->getHeaders() as $name => $values) { - * foreach ($values as $value) { - * header(sprintf('%s: %s', $name, $value), false); - * } - * } - * - * While header names are not case-sensitive, getHeaders() will preserve the - * exact case in which headers were originally specified. - * - * @return string[][] Returns an associative array of the message's headers. Each - * key MUST be a header name, and each value MUST be an array of strings - * for that header. - */ - public function getHeaders(); - - /** - * Checks if a header exists by the given case-insensitive name. - * - * @param string $name Case-insensitive header field name. - * @return bool Returns true if any header names match the given header - * name using a case-insensitive string comparison. Returns false if - * no matching header name is found in the message. - */ - public function hasHeader($name); - - /** - * Retrieves a message header value by the given case-insensitive name. - * - * This method returns an array of all the header values of the given - * case-insensitive header name. - * - * If the header does not appear in the message, this method MUST return an - * empty array. - * - * @param string $name Case-insensitive header field name. - * @return string[] An array of string values as provided for the given - * header. If the header does not appear in the message, this method MUST - * return an empty array. - */ - public function getHeader($name); - - /** - * Retrieves a comma-separated string of the values for a single header. - * - * This method returns all of the header values of the given - * case-insensitive header name as a string concatenated together using - * a comma. - * - * NOTE: Not all header values may be appropriately represented using - * comma concatenation. For such headers, use getHeader() instead - * and supply your own delimiter when concatenating. - * - * If the header does not appear in the message, this method MUST return - * an empty string. - * - * @param string $name Case-insensitive header field name. - * @return string A string of values as provided for the given header - * concatenated together using a comma. If the header does not appear in - * the message, this method MUST return an empty string. - */ - public function getHeaderLine($name); - - /** - * Return an instance with the provided value replacing the specified header. - * - * While header names are case-insensitive, the casing of the header will - * be preserved by this function, and returned from getHeaders(). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new and/or updated header and value. - * - * @param string $name Case-insensitive header field name. - * @param string|string[] $value Header value(s). - * @return static - * @throws \InvalidArgumentException for invalid header names or values. - */ - public function withHeader($name, $value); - - /** - * Return an instance with the specified header appended with the given value. - * - * Existing values for the specified header will be maintained. The new - * value(s) will be appended to the existing list. If the header did not - * exist previously, it will be added. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new header and/or value. - * - * @param string $name Case-insensitive header field name to add. - * @param string|string[] $value Header value(s). - * @return static - * @throws \InvalidArgumentException for invalid header names or values. - */ - public function withAddedHeader($name, $value); - - /** - * Return an instance without the specified header. - * - * Header resolution MUST be done without case-sensitivity. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that removes - * the named header. - * - * @param string $name Case-insensitive header field name to remove. - * @return static - */ - public function withoutHeader($name); - - /** - * Gets the body of the message. - * - * @return StreamInterface Returns the body as a stream. - */ - public function getBody(); - - /** - * Return an instance with the specified message body. - * - * The body MUST be a StreamInterface object. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return a new instance that has the - * new body stream. - * - * @param StreamInterface $body Body. - * @return static - * @throws \InvalidArgumentException When the body is not valid. - */ - public function withBody(StreamInterface $body); -} diff --git a/vendor/psr/http-message/src/RequestInterface.php b/vendor/psr/http-message/src/RequestInterface.php deleted file mode 100644 index a96d4fd63..000000000 --- a/vendor/psr/http-message/src/RequestInterface.php +++ /dev/null @@ -1,129 +0,0 @@ -getQuery()` - * or from the `QUERY_STRING` server param. - * - * @return array - */ - public function getQueryParams(); - - /** - * Return an instance with the specified query string arguments. - * - * These values SHOULD remain immutable over the course of the incoming - * request. They MAY be injected during instantiation, such as from PHP's - * $_GET superglobal, or MAY be derived from some other value such as the - * URI. In cases where the arguments are parsed from the URI, the data - * MUST be compatible with what PHP's parse_str() would return for - * purposes of how duplicate query parameters are handled, and how nested - * sets are handled. - * - * Setting query string arguments MUST NOT change the URI stored by the - * request, nor the values in the server params. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated query string arguments. - * - * @param array $query Array of query string arguments, typically from - * $_GET. - * @return static - */ - public function withQueryParams(array $query); - - /** - * Retrieve normalized file upload data. - * - * This method returns upload metadata in a normalized tree, with each leaf - * an instance of Psr\Http\Message\UploadedFileInterface. - * - * These values MAY be prepared from $_FILES or the message body during - * instantiation, or MAY be injected via withUploadedFiles(). - * - * @return array An array tree of UploadedFileInterface instances; an empty - * array MUST be returned if no data is present. - */ - public function getUploadedFiles(); - - /** - * Create a new instance with the specified uploaded files. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated body parameters. - * - * @param array $uploadedFiles An array tree of UploadedFileInterface instances. - * @return static - * @throws \InvalidArgumentException if an invalid structure is provided. - */ - public function withUploadedFiles(array $uploadedFiles); - - /** - * Retrieve any parameters provided in the request body. - * - * If the request Content-Type is either application/x-www-form-urlencoded - * or multipart/form-data, and the request method is POST, this method MUST - * return the contents of $_POST. - * - * Otherwise, this method may return any results of deserializing - * the request body content; as parsing returns structured content, the - * potential types MUST be arrays or objects only. A null value indicates - * the absence of body content. - * - * @return null|array|object The deserialized body parameters, if any. - * These will typically be an array or object. - */ - public function getParsedBody(); - - /** - * Return an instance with the specified body parameters. - * - * These MAY be injected during instantiation. - * - * If the request Content-Type is either application/x-www-form-urlencoded - * or multipart/form-data, and the request method is POST, use this method - * ONLY to inject the contents of $_POST. - * - * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of - * deserializing the request body content. Deserialization/parsing returns - * structured data, and, as such, this method ONLY accepts arrays or objects, - * or a null value if nothing was available to parse. - * - * As an example, if content negotiation determines that the request data - * is a JSON payload, this method could be used to create a request - * instance with the deserialized parameters. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated body parameters. - * - * @param null|array|object $data The deserialized body data. This will - * typically be in an array or object. - * @return static - * @throws \InvalidArgumentException if an unsupported argument type is - * provided. - */ - public function withParsedBody($data); - - /** - * Retrieve attributes derived from the request. - * - * The request "attributes" may be used to allow injection of any - * parameters derived from the request: e.g., the results of path - * match operations; the results of decrypting cookies; the results of - * deserializing non-form-encoded message bodies; etc. Attributes - * will be application and request specific, and CAN be mutable. - * - * @return array Attributes derived from the request. - */ - public function getAttributes(); - - /** - * Retrieve a single derived request attribute. - * - * Retrieves a single derived request attribute as described in - * getAttributes(). If the attribute has not been previously set, returns - * the default value as provided. - * - * This method obviates the need for a hasAttribute() method, as it allows - * specifying a default value to return if the attribute is not found. - * - * @see getAttributes() - * @param string $name The attribute name. - * @param mixed $default Default value to return if the attribute does not exist. - * @return mixed - */ - public function getAttribute($name, $default = null); - - /** - * Return an instance with the specified derived request attribute. - * - * This method allows setting a single derived request attribute as - * described in getAttributes(). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated attribute. - * - * @see getAttributes() - * @param string $name The attribute name. - * @param mixed $value The value of the attribute. - * @return static - */ - public function withAttribute($name, $value); - - /** - * Return an instance that removes the specified derived request attribute. - * - * This method allows removing a single derived request attribute as - * described in getAttributes(). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that removes - * the attribute. - * - * @see getAttributes() - * @param string $name The attribute name. - * @return static - */ - public function withoutAttribute($name); -} diff --git a/vendor/psr/http-message/src/StreamInterface.php b/vendor/psr/http-message/src/StreamInterface.php deleted file mode 100644 index f68f39126..000000000 --- a/vendor/psr/http-message/src/StreamInterface.php +++ /dev/null @@ -1,158 +0,0 @@ - - * [user-info@]host[:port] - * - * - * If the port component is not set or is the standard port for the current - * scheme, it SHOULD NOT be included. - * - * @see https://tools.ietf.org/html/rfc3986#section-3.2 - * @return string The URI authority, in "[user-info@]host[:port]" format. - */ - public function getAuthority(); - - /** - * Retrieve the user information component of the URI. - * - * If no user information is present, this method MUST return an empty - * string. - * - * If a user is present in the URI, this will return that value; - * additionally, if the password is also present, it will be appended to the - * user value, with a colon (":") separating the values. - * - * The trailing "@" character is not part of the user information and MUST - * NOT be added. - * - * @return string The URI user information, in "username[:password]" format. - */ - public function getUserInfo(); - - /** - * Retrieve the host component of the URI. - * - * If no host is present, this method MUST return an empty string. - * - * The value returned MUST be normalized to lowercase, per RFC 3986 - * Section 3.2.2. - * - * @see http://tools.ietf.org/html/rfc3986#section-3.2.2 - * @return string The URI host. - */ - public function getHost(); - - /** - * Retrieve the port component of the URI. - * - * If a port is present, and it is non-standard for the current scheme, - * this method MUST return it as an integer. If the port is the standard port - * used with the current scheme, this method SHOULD return null. - * - * If no port is present, and no scheme is present, this method MUST return - * a null value. - * - * If no port is present, but a scheme is present, this method MAY return - * the standard port for that scheme, but SHOULD return null. - * - * @return null|int The URI port. - */ - public function getPort(); - - /** - * Retrieve the path component of the URI. - * - * The path can either be empty or absolute (starting with a slash) or - * rootless (not starting with a slash). Implementations MUST support all - * three syntaxes. - * - * Normally, the empty path "" and absolute path "/" are considered equal as - * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically - * do this normalization because in contexts with a trimmed base path, e.g. - * the front controller, this difference becomes significant. It's the task - * of the user to handle both "" and "/". - * - * The value returned MUST be percent-encoded, but MUST NOT double-encode - * any characters. To determine what characters to encode, please refer to - * RFC 3986, Sections 2 and 3.3. - * - * As an example, if the value should include a slash ("/") not intended as - * delimiter between path segments, that value MUST be passed in encoded - * form (e.g., "%2F") to the instance. - * - * @see https://tools.ietf.org/html/rfc3986#section-2 - * @see https://tools.ietf.org/html/rfc3986#section-3.3 - * @return string The URI path. - */ - public function getPath(); - - /** - * Retrieve the query string of the URI. - * - * If no query string is present, this method MUST return an empty string. - * - * The leading "?" character is not part of the query and MUST NOT be - * added. - * - * The value returned MUST be percent-encoded, but MUST NOT double-encode - * any characters. To determine what characters to encode, please refer to - * RFC 3986, Sections 2 and 3.4. - * - * As an example, if a value in a key/value pair of the query string should - * include an ampersand ("&") not intended as a delimiter between values, - * that value MUST be passed in encoded form (e.g., "%26") to the instance. - * - * @see https://tools.ietf.org/html/rfc3986#section-2 - * @see https://tools.ietf.org/html/rfc3986#section-3.4 - * @return string The URI query string. - */ - public function getQuery(); - - /** - * Retrieve the fragment component of the URI. - * - * If no fragment is present, this method MUST return an empty string. - * - * The leading "#" character is not part of the fragment and MUST NOT be - * added. - * - * The value returned MUST be percent-encoded, but MUST NOT double-encode - * any characters. To determine what characters to encode, please refer to - * RFC 3986, Sections 2 and 3.5. - * - * @see https://tools.ietf.org/html/rfc3986#section-2 - * @see https://tools.ietf.org/html/rfc3986#section-3.5 - * @return string The URI fragment. - */ - public function getFragment(); - - /** - * Return an instance with the specified scheme. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified scheme. - * - * Implementations MUST support the schemes "http" and "https" case - * insensitively, and MAY accommodate other schemes if required. - * - * An empty scheme is equivalent to removing the scheme. - * - * @param string $scheme The scheme to use with the new instance. - * @return static A new instance with the specified scheme. - * @throws \InvalidArgumentException for invalid or unsupported schemes. - */ - public function withScheme($scheme); - - /** - * Return an instance with the specified user information. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified user information. - * - * Password is optional, but the user information MUST include the - * user; an empty string for the user is equivalent to removing user - * information. - * - * @param string $user The user name to use for authority. - * @param null|string $password The password associated with $user. - * @return static A new instance with the specified user information. - */ - public function withUserInfo($user, $password = null); - - /** - * Return an instance with the specified host. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified host. - * - * An empty host value is equivalent to removing the host. - * - * @param string $host The hostname to use with the new instance. - * @return static A new instance with the specified host. - * @throws \InvalidArgumentException for invalid hostnames. - */ - public function withHost($host); - - /** - * Return an instance with the specified port. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified port. - * - * Implementations MUST raise an exception for ports outside the - * established TCP and UDP port ranges. - * - * A null value provided for the port is equivalent to removing the port - * information. - * - * @param null|int $port The port to use with the new instance; a null value - * removes the port information. - * @return static A new instance with the specified port. - * @throws \InvalidArgumentException for invalid ports. - */ - public function withPort($port); - - /** - * Return an instance with the specified path. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified path. - * - * The path can either be empty or absolute (starting with a slash) or - * rootless (not starting with a slash). Implementations MUST support all - * three syntaxes. - * - * If the path is intended to be domain-relative rather than path relative then - * it must begin with a slash ("/"). Paths not starting with a slash ("/") - * are assumed to be relative to some base path known to the application or - * consumer. - * - * Users can provide both encoded and decoded path characters. - * Implementations ensure the correct encoding as outlined in getPath(). - * - * @param string $path The path to use with the new instance. - * @return static A new instance with the specified path. - * @throws \InvalidArgumentException for invalid paths. - */ - public function withPath($path); - - /** - * Return an instance with the specified query string. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified query string. - * - * Users can provide both encoded and decoded query characters. - * Implementations ensure the correct encoding as outlined in getQuery(). - * - * An empty query string value is equivalent to removing the query string. - * - * @param string $query The query string to use with the new instance. - * @return static A new instance with the specified query string. - * @throws \InvalidArgumentException for invalid query strings. - */ - public function withQuery($query); - - /** - * Return an instance with the specified URI fragment. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified URI fragment. - * - * Users can provide both encoded and decoded fragment characters. - * Implementations ensure the correct encoding as outlined in getFragment(). - * - * An empty fragment value is equivalent to removing the fragment. - * - * @param string $fragment The fragment to use with the new instance. - * @return static A new instance with the specified fragment. - */ - public function withFragment($fragment); - - /** - * Return the string representation as a URI reference. - * - * Depending on which components of the URI are present, the resulting - * string is either a full URI or relative reference according to RFC 3986, - * Section 4.1. The method concatenates the various components of the URI, - * using the appropriate delimiters: - * - * - If a scheme is present, it MUST be suffixed by ":". - * - If an authority is present, it MUST be prefixed by "//". - * - The path can be concatenated without delimiters. But there are two - * cases where the path has to be adjusted to make the URI reference - * valid as PHP does not allow to throw an exception in __toString(): - * - If the path is rootless and an authority is present, the path MUST - * be prefixed by "/". - * - If the path is starting with more than one "/" and no authority is - * present, the starting slashes MUST be reduced to one. - * - If a query is present, it MUST be prefixed by "?". - * - If a fragment is present, it MUST be prefixed by "#". - * - * @see http://tools.ietf.org/html/rfc3986#section-4.1 - * @return string - */ - public function __toString(); -} diff --git a/vendor/react/cache/src/ArrayCache.php b/vendor/react/cache/src/ArrayCache.php deleted file mode 100644 index 81f25effa..000000000 --- a/vendor/react/cache/src/ArrayCache.php +++ /dev/null @@ -1,181 +0,0 @@ -set('foo', 'bar'); - * ``` - * - * Its constructor accepts an optional `?int $limit` parameter to limit the - * maximum number of entries to store in the LRU cache. If you add more - * entries to this instance, it will automatically take care of removing - * the one that was least recently used (LRU). - * - * For example, this snippet will overwrite the first value and only store - * the last two entries: - * - * ```php - * $cache = new ArrayCache(2); - * - * $cache->set('foo', '1'); - * $cache->set('bar', '2'); - * $cache->set('baz', '3'); - * ``` - * - * This cache implementation is known to rely on wall-clock time to schedule - * future cache expiration times when using any version before PHP 7.3, - * because a monotonic time source is only available as of PHP 7.3 (`hrtime()`). - * While this does not affect many common use cases, this is an important - * distinction for programs that rely on a high time precision or on systems - * that are subject to discontinuous time adjustments (time jumps). - * This means that if you store a cache item with a TTL of 30s on PHP < 7.3 - * and then adjust your system time forward by 20s, the cache item may - * expire in 10s. See also [`set()`](#set) for more details. - * - * @param int|null $limit maximum number of entries to store in the LRU cache - */ - public function __construct($limit = null) - { - $this->limit = $limit; - - // prefer high-resolution timer, available as of PHP 7.3+ - $this->supportsHighResolution = \function_exists('hrtime'); - } - - public function get($key, $default = null) - { - // delete key if it is already expired => below will detect this as a cache miss - if (isset($this->expires[$key]) && $this->now() - $this->expires[$key] > 0) { - unset($this->data[$key], $this->expires[$key]); - } - - if (!\array_key_exists($key, $this->data)) { - return Promise\resolve($default); - } - - // remove and append to end of array to keep track of LRU info - $value = $this->data[$key]; - unset($this->data[$key]); - $this->data[$key] = $value; - - return Promise\resolve($value); - } - - public function set($key, $value, $ttl = null) - { - // unset before setting to ensure this entry will be added to end of array (LRU info) - unset($this->data[$key]); - $this->data[$key] = $value; - - // sort expiration times if TTL is given (first will expire first) - unset($this->expires[$key]); - if ($ttl !== null) { - $this->expires[$key] = $this->now() + $ttl; - \asort($this->expires); - } - - // ensure size limit is not exceeded or remove first entry from array - if ($this->limit !== null && \count($this->data) > $this->limit) { - // first try to check if there's any expired entry - // expiration times are sorted, so we can simply look at the first one - \reset($this->expires); - $key = \key($this->expires); - - // check to see if the first in the list of expiring keys is already expired - // if the first key is not expired, we have to overwrite by using LRU info - if ($key === null || $this->now() - $this->expires[$key] < 0) { - \reset($this->data); - $key = \key($this->data); - } - unset($this->data[$key], $this->expires[$key]); - } - - return Promise\resolve(true); - } - - public function delete($key) - { - unset($this->data[$key], $this->expires[$key]); - - return Promise\resolve(true); - } - - public function getMultiple(array $keys, $default = null) - { - $values = array(); - - foreach ($keys as $key) { - $values[$key] = $this->get($key, $default); - } - - return Promise\all($values); - } - - public function setMultiple(array $values, $ttl = null) - { - foreach ($values as $key => $value) { - $this->set($key, $value, $ttl); - } - - return Promise\resolve(true); - } - - public function deleteMultiple(array $keys) - { - foreach ($keys as $key) { - unset($this->data[$key], $this->expires[$key]); - } - - return Promise\resolve(true); - } - - public function clear() - { - $this->data = array(); - $this->expires = array(); - - return Promise\resolve(true); - } - - public function has($key) - { - // delete key if it is already expired - if (isset($this->expires[$key]) && $this->now() - $this->expires[$key] > 0) { - unset($this->data[$key], $this->expires[$key]); - } - - if (!\array_key_exists($key, $this->data)) { - return Promise\resolve(false); - } - - // remove and append to end of array to keep track of LRU info - $value = $this->data[$key]; - unset($this->data[$key]); - $this->data[$key] = $value; - - return Promise\resolve(true); - } - - /** - * @return float - */ - private function now() - { - return $this->supportsHighResolution ? \hrtime(true) * 1e-9 : \microtime(true); - } -} diff --git a/vendor/react/cache/src/CacheInterface.php b/vendor/react/cache/src/CacheInterface.php deleted file mode 100644 index 8e51c190c..000000000 --- a/vendor/react/cache/src/CacheInterface.php +++ /dev/null @@ -1,194 +0,0 @@ -get('foo') - * ->then('var_dump'); - * ``` - * - * This example fetches the value of the key `foo` and passes it to the - * `var_dump` function. You can use any of the composition provided by - * [promises](https://github.com/reactphp/promise). - * - * @param string $key - * @param mixed $default Default value to return for cache miss or null if not given. - * @return PromiseInterface - */ - public function get($key, $default = null); - - /** - * Stores an item in the cache. - * - * This method will resolve with `true` on success or `false` when an error - * occurs. If the cache implementation has to go over the network to store - * it, it may take a while. - * - * The optional `$ttl` parameter sets the maximum time-to-live in seconds - * for this cache item. If this parameter is omitted (or `null`), the item - * will stay in the cache for as long as the underlying implementation - * supports. Trying to access an expired cache item results in a cache miss, - * see also [`get()`](#get). - * - * ```php - * $cache->set('foo', 'bar', 60); - * ``` - * - * This example eventually sets the value of the key `foo` to `bar`. If it - * already exists, it is overridden. - * - * This interface does not enforce any particular TTL resolution, so special - * care may have to be taken if you rely on very high precision with - * millisecond accuracy or below. Cache implementations SHOULD work on a - * best effort basis and SHOULD provide at least second accuracy unless - * otherwise noted. Many existing cache implementations are known to provide - * microsecond or millisecond accuracy, but it's generally not recommended - * to rely on this high precision. - * - * This interface suggests that cache implementations SHOULD use a monotonic - * time source if available. Given that a monotonic time source is only - * available as of PHP 7.3 by default, cache implementations MAY fall back - * to using wall-clock time. - * While this does not affect many common use cases, this is an important - * distinction for programs that rely on a high time precision or on systems - * that are subject to discontinuous time adjustments (time jumps). - * This means that if you store a cache item with a TTL of 30s and then - * adjust your system time forward by 20s, the cache item SHOULD still - * expire in 30s. - * - * @param string $key - * @param mixed $value - * @param ?float $ttl - * @return PromiseInterface Returns a promise which resolves to `true` on success or `false` on error - */ - public function set($key, $value, $ttl = null); - - /** - * Deletes an item from the cache. - * - * This method will resolve with `true` on success or `false` when an error - * occurs. When no item for `$key` is found in the cache, it also resolves - * to `true`. If the cache implementation has to go over the network to - * delete it, it may take a while. - * - * ```php - * $cache->delete('foo'); - * ``` - * - * This example eventually deletes the key `foo` from the cache. As with - * `set()`, this may not happen instantly and a promise is returned to - * provide guarantees whether or not the item has been removed from cache. - * - * @param string $key - * @return PromiseInterface Returns a promise which resolves to `true` on success or `false` on error - */ - public function delete($key); - - /** - * Retrieves multiple cache items by their unique keys. - * - * This method will resolve with an array of cached values on success or with the - * given `$default` value when an item can not be found or when an error occurs. - * Similarly, an expired cache item (once the time-to-live is expired) is - * considered a cache miss. - * - * ```php - * $cache->getMultiple(array('name', 'age'))->then(function (array $values) { - * $name = $values['name'] ?? 'User'; - * $age = $values['age'] ?? 'n/a'; - * - * echo $name . ' is ' . $age . PHP_EOL; - * }); - * ``` - * - * This example fetches the cache items for the `name` and `age` keys and - * prints some example output. You can use any of the composition provided - * by [promises](https://github.com/reactphp/promise). - * - * @param string[] $keys A list of keys that can obtained in a single operation. - * @param mixed $default Default value to return for keys that do not exist. - * @return PromiseInterface Returns a promise which resolves to an `array` of cached values - */ - public function getMultiple(array $keys, $default = null); - - /** - * Persists a set of key => value pairs in the cache, with an optional TTL. - * - * This method will resolve with `true` on success or `false` when an error - * occurs. If the cache implementation has to go over the network to store - * it, it may take a while. - * - * The optional `$ttl` parameter sets the maximum time-to-live in seconds - * for these cache items. If this parameter is omitted (or `null`), these items - * will stay in the cache for as long as the underlying implementation - * supports. Trying to access an expired cache items results in a cache miss, - * see also [`get()`](#get). - * - * ```php - * $cache->setMultiple(array('foo' => 1, 'bar' => 2), 60); - * ``` - * - * This example eventually sets the list of values - the key `foo` to 1 value - * and the key `bar` to 2. If some of the keys already exist, they are overridden. - * - * @param array $values A list of key => value pairs for a multiple-set operation. - * @param ?float $ttl Optional. The TTL value of this item. - * @return PromiseInterface Returns a promise which resolves to `true` on success or `false` on error - */ - public function setMultiple(array $values, $ttl = null); - - /** - * Deletes multiple cache items in a single operation. - * - * @param string[] $keys A list of string-based keys to be deleted. - * @return PromiseInterface Returns a promise which resolves to `true` on success or `false` on error - */ - public function deleteMultiple(array $keys); - - /** - * Wipes clean the entire cache. - * - * @return PromiseInterface Returns a promise which resolves to `true` on success or `false` on error - */ - public function clear(); - - /** - * Determines whether an item is present in the cache. - * - * This method will resolve with `true` on success or `false` when no item can be found - * or when an error occurs. Similarly, an expired cache item (once the time-to-live - * is expired) is considered a cache miss. - * - * ```php - * $cache - * ->has('foo') - * ->then('var_dump'); - * ``` - * - * This example checks if the value of the key `foo` is set in the cache and passes - * the result to the `var_dump` function. You can use any of the composition provided by - * [promises](https://github.com/reactphp/promise). - * - * NOTE: It is recommended that has() is only to be used for cache warming type purposes - * and not to be used within your live applications operations for get/set, as this method - * is subject to a race condition where your has() will return true and immediately after, - * another script can remove it making the state of your app out of date. - * - * @param string $key The cache item key. - * @return PromiseInterface Returns a promise which resolves to `true` on success or `false` on error - */ - public function has($key); -} diff --git a/vendor/react/dns/src/BadServerException.php b/vendor/react/dns/src/BadServerException.php deleted file mode 100644 index 3d95213f4..000000000 --- a/vendor/react/dns/src/BadServerException.php +++ /dev/null @@ -1,7 +0,0 @@ - `fe80:1`) - if (strpos($ip, ':') !== false && ($pos = strpos($ip, '%')) !== false) { - $ip = substr($ip, 0, $pos); - } - - if (@inet_pton($ip) !== false) { - $config->nameservers[] = $ip; - } - } - - return $config; - } - - /** - * Loads the DNS configurations from Windows's WMIC (from the given command or default command) - * - * Note that this method blocks while loading the given command and should - * thus be used with care! While this should be relatively fast for normal - * WMIC commands, it remains unknown if this may block under certain - * circumstances. In particular, this method should only be executed before - * the loop starts, not while it is running. - * - * Note that this method will only try to execute the given command try to - * parse its output, irrespective of whether this command exists. In - * particular, this command is only available on Windows. Currently, this - * will only parse valid nameserver entries from the command output and will - * ignore all other output without complaining. - * - * Note that the previous section implies that this may return an empty - * `Config` object if no valid nameserver entries can be found. - * - * @param ?string $command (advanced) should not be given (NULL) unless you know what you're doing - * @return self - * @link https://ss64.com/nt/wmic.html - */ - public static function loadWmicBlocking($command = null) - { - $contents = shell_exec($command === null ? 'wmic NICCONFIG get "DNSServerSearchOrder" /format:CSV' : $command); - preg_match_all('/(?<=[{;,"])([\da-f.:]{4,})(?=[};,"])/i', $contents, $matches); - - $config = new self(); - $config->nameservers = $matches[1]; - - return $config; - } - - public $nameservers = array(); -} diff --git a/vendor/react/dns/src/Config/HostsFile.php b/vendor/react/dns/src/Config/HostsFile.php deleted file mode 100644 index 1060231a2..000000000 --- a/vendor/react/dns/src/Config/HostsFile.php +++ /dev/null @@ -1,153 +0,0 @@ -contents = $contents; - } - - /** - * Returns all IPs for the given hostname - * - * @param string $name - * @return string[] - */ - public function getIpsForHost($name) - { - $name = strtolower($name); - - $ips = array(); - foreach (preg_split('/\r?\n/', $this->contents) as $line) { - $parts = preg_split('/\s+/', $line); - $ip = array_shift($parts); - if ($parts && array_search($name, $parts) !== false) { - // remove IPv6 zone ID (`fe80::1%lo0` => `fe80:1`) - if (strpos($ip, ':') !== false && ($pos = strpos($ip, '%')) !== false) { - $ip = substr($ip, 0, $pos); - } - - if (@inet_pton($ip) !== false) { - $ips[] = $ip; - } - } - } - - return $ips; - } - - /** - * Returns all hostnames for the given IPv4 or IPv6 address - * - * @param string $ip - * @return string[] - */ - public function getHostsForIp($ip) - { - // check binary representation of IP to avoid string case and short notation - $ip = @inet_pton($ip); - if ($ip === false) { - return array(); - } - - $names = array(); - foreach (preg_split('/\r?\n/', $this->contents) as $line) { - $parts = preg_split('/\s+/', $line, -1, PREG_SPLIT_NO_EMPTY); - $addr = (string) array_shift($parts); - - // remove IPv6 zone ID (`fe80::1%lo0` => `fe80:1`) - if (strpos($addr, ':') !== false && ($pos = strpos($addr, '%')) !== false) { - $addr = substr($addr, 0, $pos); - } - - if (@inet_pton($addr) === $ip) { - foreach ($parts as $part) { - $names[] = $part; - } - } - } - - return $names; - } -} diff --git a/vendor/react/dns/src/Model/Message.php b/vendor/react/dns/src/Model/Message.php deleted file mode 100644 index bac2b10d0..000000000 --- a/vendor/react/dns/src/Model/Message.php +++ /dev/null @@ -1,230 +0,0 @@ -id = self::generateId(); - $request->rd = true; - $request->questions[] = $query; - - return $request; - } - - /** - * Creates a new response message for the given query with the given answer records - * - * @param Query $query - * @param Record[] $answers - * @return self - */ - public static function createResponseWithAnswersForQuery(Query $query, array $answers) - { - $response = new Message(); - $response->id = self::generateId(); - $response->qr = true; - $response->rd = true; - - $response->questions[] = $query; - - foreach ($answers as $record) { - $response->answers[] = $record; - } - - return $response; - } - - /** - * generates a random 16 bit message ID - * - * This uses a CSPRNG so that an outside attacker that is sending spoofed - * DNS response messages can not guess the message ID to avoid possible - * cache poisoning attacks. - * - * The `random_int()` function is only available on PHP 7+ or when - * https://github.com/paragonie/random_compat is installed. As such, using - * the latest supported PHP version is highly recommended. This currently - * falls back to a less secure random number generator on older PHP versions - * in the hope that this system is properly protected against outside - * attackers, for example by using one of the common local DNS proxy stubs. - * - * @return int - * @see self::getId() - * @codeCoverageIgnore - */ - private static function generateId() - { - if (function_exists('random_int')) { - return random_int(0, 0xffff); - } - return mt_rand(0, 0xffff); - } - - /** - * The 16 bit message ID - * - * The response message ID has to match the request message ID. This allows - * the receiver to verify this is the correct response message. An outside - * attacker may try to inject fake responses by "guessing" the message ID, - * so this should use a proper CSPRNG to avoid possible cache poisoning. - * - * @var int 16 bit message ID - * @see self::generateId() - */ - public $id = 0; - - /** - * @var bool Query/Response flag, query=false or response=true - */ - public $qr = false; - - /** - * @var int specifies the kind of query (4 bit), see self::OPCODE_* constants - * @see self::OPCODE_QUERY - */ - public $opcode = self::OPCODE_QUERY; - - /** - * - * @var bool Authoritative Answer - */ - public $aa = false; - - /** - * @var bool TrunCation - */ - public $tc = false; - - /** - * @var bool Recursion Desired - */ - public $rd = false; - - /** - * @var bool Recursion Available - */ - public $ra = false; - - /** - * @var int response code (4 bit), see self::RCODE_* constants - * @see self::RCODE_OK - */ - public $rcode = Message::RCODE_OK; - - /** - * An array of Query objects - * - * ```php - * $questions = array( - * new Query( - * 'reactphp.org', - * Message::TYPE_A, - * Message::CLASS_IN - * ) - * ); - * ``` - * - * @var Query[] - */ - public $questions = array(); - - /** - * @var Record[] - */ - public $answers = array(); - - /** - * @var Record[] - */ - public $authority = array(); - - /** - * @var Record[] - */ - public $additional = array(); -} diff --git a/vendor/react/dns/src/Model/Record.php b/vendor/react/dns/src/Model/Record.php deleted file mode 100644 index c20403f52..000000000 --- a/vendor/react/dns/src/Model/Record.php +++ /dev/null @@ -1,153 +0,0 @@ -name = $name; - $this->type = $type; - $this->class = $class; - $this->ttl = $ttl; - $this->data = $data; - } -} diff --git a/vendor/react/dns/src/Protocol/BinaryDumper.php b/vendor/react/dns/src/Protocol/BinaryDumper.php deleted file mode 100644 index 6f4030f63..000000000 --- a/vendor/react/dns/src/Protocol/BinaryDumper.php +++ /dev/null @@ -1,199 +0,0 @@ -headerToBinary($message); - $data .= $this->questionToBinary($message->questions); - $data .= $this->recordsToBinary($message->answers); - $data .= $this->recordsToBinary($message->authority); - $data .= $this->recordsToBinary($message->additional); - - return $data; - } - - /** - * @param Message $message - * @return string - */ - private function headerToBinary(Message $message) - { - $data = ''; - - $data .= pack('n', $message->id); - - $flags = 0x00; - $flags = ($flags << 1) | ($message->qr ? 1 : 0); - $flags = ($flags << 4) | $message->opcode; - $flags = ($flags << 1) | ($message->aa ? 1 : 0); - $flags = ($flags << 1) | ($message->tc ? 1 : 0); - $flags = ($flags << 1) | ($message->rd ? 1 : 0); - $flags = ($flags << 1) | ($message->ra ? 1 : 0); - $flags = ($flags << 3) | 0; // skip unused zero bit - $flags = ($flags << 4) | $message->rcode; - - $data .= pack('n', $flags); - - $data .= pack('n', count($message->questions)); - $data .= pack('n', count($message->answers)); - $data .= pack('n', count($message->authority)); - $data .= pack('n', count($message->additional)); - - return $data; - } - - /** - * @param Query[] $questions - * @return string - */ - private function questionToBinary(array $questions) - { - $data = ''; - - foreach ($questions as $question) { - $data .= $this->domainNameToBinary($question->name); - $data .= pack('n*', $question->type, $question->class); - } - - return $data; - } - - /** - * @param Record[] $records - * @return string - */ - private function recordsToBinary(array $records) - { - $data = ''; - - foreach ($records as $record) { - /* @var $record Record */ - switch ($record->type) { - case Message::TYPE_A: - case Message::TYPE_AAAA: - $binary = \inet_pton($record->data); - break; - case Message::TYPE_CNAME: - case Message::TYPE_NS: - case Message::TYPE_PTR: - $binary = $this->domainNameToBinary($record->data); - break; - case Message::TYPE_TXT: - case Message::TYPE_SPF: - $binary = $this->textsToBinary($record->data); - break; - case Message::TYPE_MX: - $binary = \pack( - 'n', - $record->data['priority'] - ); - $binary .= $this->domainNameToBinary($record->data['target']); - break; - case Message::TYPE_SRV: - $binary = \pack( - 'n*', - $record->data['priority'], - $record->data['weight'], - $record->data['port'] - ); - $binary .= $this->domainNameToBinary($record->data['target']); - break; - case Message::TYPE_SOA: - $binary = $this->domainNameToBinary($record->data['mname']); - $binary .= $this->domainNameToBinary($record->data['rname']); - $binary .= \pack( - 'N*', - $record->data['serial'], - $record->data['refresh'], - $record->data['retry'], - $record->data['expire'], - $record->data['minimum'] - ); - break; - case Message::TYPE_CAA: - $binary = \pack( - 'C*', - $record->data['flag'], - \strlen($record->data['tag']) - ); - $binary .= $record->data['tag']; - $binary .= $record->data['value']; - break; - case Message::TYPE_SSHFP: - $binary = \pack( - 'CCH*', - $record->data['algorithm'], - $record->data['type'], - $record->data['fingerprint'] - ); - break; - case Message::TYPE_OPT: - $binary = ''; - foreach ($record->data as $opt => $value) { - if ($opt === Message::OPT_TCP_KEEPALIVE && $value !== null) { - $value = \pack('n', round($value * 10)); - } - $binary .= \pack('n*', $opt, \strlen((string) $value)) . $value; - } - break; - default: - // RDATA is already stored as binary value for unknown record types - $binary = $record->data; - } - - $data .= $this->domainNameToBinary($record->name); - $data .= \pack('nnNn', $record->type, $record->class, $record->ttl, \strlen($binary)); - $data .= $binary; - } - - return $data; - } - - /** - * @param string[] $texts - * @return string - */ - private function textsToBinary(array $texts) - { - $data = ''; - foreach ($texts as $text) { - $data .= \chr(\strlen($text)) . $text; - } - return $data; - } - - /** - * @param string $host - * @return string - */ - private function domainNameToBinary($host) - { - if ($host === '') { - return "\0"; - } - - // break up domain name at each dot that is not preceeded by a backslash (escaped notation) - return $this->textsToBinary( - \array_map( - 'stripcslashes', - \preg_split( - '/(?parse($data, 0); - if ($message === null) { - throw new InvalidArgumentException('Unable to parse binary message'); - } - - return $message; - } - - /** - * @param string $data - * @param int $consumed - * @return ?Message - */ - private function parse($data, $consumed) - { - if (!isset($data[12 - 1])) { - return null; - } - - list($id, $fields, $qdCount, $anCount, $nsCount, $arCount) = array_values(unpack('n*', substr($data, 0, 12))); - - $message = new Message(); - $message->id = $id; - $message->rcode = $fields & 0xf; - $message->ra = (($fields >> 7) & 1) === 1; - $message->rd = (($fields >> 8) & 1) === 1; - $message->tc = (($fields >> 9) & 1) === 1; - $message->aa = (($fields >> 10) & 1) === 1; - $message->opcode = ($fields >> 11) & 0xf; - $message->qr = (($fields >> 15) & 1) === 1; - $consumed += 12; - - // parse all questions - for ($i = $qdCount; $i > 0; --$i) { - list($question, $consumed) = $this->parseQuestion($data, $consumed); - if ($question === null) { - return null; - } else { - $message->questions[] = $question; - } - } - - // parse all answer records - for ($i = $anCount; $i > 0; --$i) { - list($record, $consumed) = $this->parseRecord($data, $consumed); - if ($record === null) { - return null; - } else { - $message->answers[] = $record; - } - } - - // parse all authority records - for ($i = $nsCount; $i > 0; --$i) { - list($record, $consumed) = $this->parseRecord($data, $consumed); - if ($record === null) { - return null; - } else { - $message->authority[] = $record; - } - } - - // parse all additional records - for ($i = $arCount; $i > 0; --$i) { - list($record, $consumed) = $this->parseRecord($data, $consumed); - if ($record === null) { - return null; - } else { - $message->additional[] = $record; - } - } - - return $message; - } - - /** - * @param string $data - * @param int $consumed - * @return array - */ - private function parseQuestion($data, $consumed) - { - list($labels, $consumed) = $this->readLabels($data, $consumed); - - if ($labels === null || !isset($data[$consumed + 4 - 1])) { - return array(null, null); - } - - list($type, $class) = array_values(unpack('n*', substr($data, $consumed, 4))); - $consumed += 4; - - return array( - new Query( - implode('.', $labels), - $type, - $class - ), - $consumed - ); - } - - /** - * @param string $data - * @param int $consumed - * @return array An array with a parsed Record on success or array with null if data is invalid/incomplete - */ - private function parseRecord($data, $consumed) - { - list($name, $consumed) = $this->readDomain($data, $consumed); - - if ($name === null || !isset($data[$consumed + 10 - 1])) { - return array(null, null); - } - - list($type, $class) = array_values(unpack('n*', substr($data, $consumed, 4))); - $consumed += 4; - - list($ttl) = array_values(unpack('N', substr($data, $consumed, 4))); - $consumed += 4; - - // TTL is a UINT32 that must not have most significant bit set for BC reasons - if ($ttl < 0 || $ttl >= 1 << 31) { - $ttl = 0; - } - - list($rdLength) = array_values(unpack('n', substr($data, $consumed, 2))); - $consumed += 2; - - if (!isset($data[$consumed + $rdLength - 1])) { - return array(null, null); - } - - $rdata = null; - $expected = $consumed + $rdLength; - - if (Message::TYPE_A === $type) { - if ($rdLength === 4) { - $rdata = inet_ntop(substr($data, $consumed, $rdLength)); - $consumed += $rdLength; - } - } elseif (Message::TYPE_AAAA === $type) { - if ($rdLength === 16) { - $rdata = inet_ntop(substr($data, $consumed, $rdLength)); - $consumed += $rdLength; - } - } elseif (Message::TYPE_CNAME === $type || Message::TYPE_PTR === $type || Message::TYPE_NS === $type) { - list($rdata, $consumed) = $this->readDomain($data, $consumed); - } elseif (Message::TYPE_TXT === $type || Message::TYPE_SPF === $type) { - $rdata = array(); - while ($consumed < $expected) { - $len = ord($data[$consumed]); - $rdata[] = (string)substr($data, $consumed + 1, $len); - $consumed += $len + 1; - } - } elseif (Message::TYPE_MX === $type) { - if ($rdLength > 2) { - list($priority) = array_values(unpack('n', substr($data, $consumed, 2))); - list($target, $consumed) = $this->readDomain($data, $consumed + 2); - - $rdata = array( - 'priority' => $priority, - 'target' => $target - ); - } - } elseif (Message::TYPE_SRV === $type) { - if ($rdLength > 6) { - list($priority, $weight, $port) = array_values(unpack('n*', substr($data, $consumed, 6))); - list($target, $consumed) = $this->readDomain($data, $consumed + 6); - - $rdata = array( - 'priority' => $priority, - 'weight' => $weight, - 'port' => $port, - 'target' => $target - ); - } - } elseif (Message::TYPE_SSHFP === $type) { - if ($rdLength > 2) { - list($algorithm, $hash) = \array_values(\unpack('C*', \substr($data, $consumed, 2))); - $fingerprint = \bin2hex(\substr($data, $consumed + 2, $rdLength - 2)); - $consumed += $rdLength; - - $rdata = array( - 'algorithm' => $algorithm, - 'type' => $hash, - 'fingerprint' => $fingerprint - ); - } - } elseif (Message::TYPE_SOA === $type) { - list($mname, $consumed) = $this->readDomain($data, $consumed); - list($rname, $consumed) = $this->readDomain($data, $consumed); - - if ($mname !== null && $rname !== null && isset($data[$consumed + 20 - 1])) { - list($serial, $refresh, $retry, $expire, $minimum) = array_values(unpack('N*', substr($data, $consumed, 20))); - $consumed += 20; - - $rdata = array( - 'mname' => $mname, - 'rname' => $rname, - 'serial' => $serial, - 'refresh' => $refresh, - 'retry' => $retry, - 'expire' => $expire, - 'minimum' => $minimum - ); - } - } elseif (Message::TYPE_OPT === $type) { - $rdata = array(); - while (isset($data[$consumed + 4 - 1])) { - list($code, $length) = array_values(unpack('n*', substr($data, $consumed, 4))); - $value = (string) substr($data, $consumed + 4, $length); - if ($code === Message::OPT_TCP_KEEPALIVE && $value === '') { - $value = null; - } elseif ($code === Message::OPT_TCP_KEEPALIVE && $length === 2) { - list($value) = array_values(unpack('n', $value)); - $value = round($value * 0.1, 1); - } elseif ($code === Message::OPT_TCP_KEEPALIVE) { - break; - } - $rdata[$code] = $value; - $consumed += 4 + $length; - } - } elseif (Message::TYPE_CAA === $type) { - if ($rdLength > 3) { - list($flag, $tagLength) = array_values(unpack('C*', substr($data, $consumed, 2))); - - if ($tagLength > 0 && $rdLength - 2 - $tagLength > 0) { - $tag = substr($data, $consumed + 2, $tagLength); - $value = substr($data, $consumed + 2 + $tagLength, $rdLength - 2 - $tagLength); - $consumed += $rdLength; - - $rdata = array( - 'flag' => $flag, - 'tag' => $tag, - 'value' => $value - ); - } - } - } else { - // unknown types simply parse rdata as an opaque binary string - $rdata = substr($data, $consumed, $rdLength); - $consumed += $rdLength; - } - - // ensure parsing record data consumes expact number of bytes indicated in record length - if ($consumed !== $expected || $rdata === null) { - return array(null, null); - } - - return array( - new Record($name, $type, $class, $ttl, $rdata), - $consumed - ); - } - - private function readDomain($data, $consumed) - { - list ($labels, $consumed) = $this->readLabels($data, $consumed); - - if ($labels === null) { - return array(null, null); - } - - // use escaped notation for each label part, then join using dots - return array( - \implode( - '.', - \array_map( - function ($label) { - return \addcslashes($label, "\0..\40.\177"); - }, - $labels - ) - ), - $consumed - ); - } - - /** - * @param string $data - * @param int $consumed - * @param int $compressionDepth maximum depth for compressed labels to avoid unreasonable recursion - * @return array - */ - private function readLabels($data, $consumed, $compressionDepth = 127) - { - $labels = array(); - - while (true) { - if (!isset($data[$consumed])) { - return array(null, null); - } - - $length = \ord($data[$consumed]); - - // end of labels reached - if ($length === 0) { - $consumed += 1; - break; - } - - // first two bits set? this is a compressed label (14 bit pointer offset) - if (($length & 0xc0) === 0xc0 && isset($data[$consumed + 1]) && $compressionDepth) { - $offset = ($length & ~0xc0) << 8 | \ord($data[$consumed + 1]); - if ($offset >= $consumed) { - return array(null, null); - } - - $consumed += 2; - list($newLabels) = $this->readLabels($data, $offset, $compressionDepth - 1); - - if ($newLabels === null) { - return array(null, null); - } - - $labels = array_merge($labels, $newLabels); - break; - } - - // length MUST be 0-63 (6 bits only) and data has to be large enough - if ($length & 0xc0 || !isset($data[$consumed + $length - 1])) { - return array(null, null); - } - - $labels[] = substr($data, $consumed + 1, $length); - $consumed += $length + 1; - } - - return array($labels, $consumed); - } -} diff --git a/vendor/react/dns/src/Query/CachingExecutor.php b/vendor/react/dns/src/Query/CachingExecutor.php deleted file mode 100644 index e530b24c4..000000000 --- a/vendor/react/dns/src/Query/CachingExecutor.php +++ /dev/null @@ -1,88 +0,0 @@ -executor = $executor; - $this->cache = $cache; - } - - public function query(Query $query) - { - $id = $query->name . ':' . $query->type . ':' . $query->class; - $cache = $this->cache; - $that = $this; - $executor = $this->executor; - - $pending = $cache->get($id); - return new Promise(function ($resolve, $reject) use ($query, $id, $cache, $executor, &$pending, $that) { - $pending->then( - function ($message) use ($query, $id, $cache, $executor, &$pending, $that) { - // return cached response message on cache hit - if ($message !== null) { - return $message; - } - - // perform DNS lookup if not already cached - return $pending = $executor->query($query)->then( - function (Message $message) use ($cache, $id, $that) { - // DNS response message received => store in cache when not truncated and return - if (!$message->tc) { - $cache->set($id, $message, $that->ttl($message)); - } - - return $message; - } - ); - } - )->then($resolve, function ($e) use ($reject, &$pending) { - $reject($e); - $pending = null; - }); - }, function ($_, $reject) use (&$pending, $query) { - $reject(new \RuntimeException('DNS query for ' . $query->describe() . ' has been cancelled')); - $pending->cancel(); - $pending = null; - }); - } - - /** - * @param Message $message - * @return int - * @internal - */ - public function ttl(Message $message) - { - // select TTL from answers (should all be the same), use smallest value if available - // @link https://tools.ietf.org/html/rfc2181#section-5.2 - $ttl = null; - foreach ($message->answers as $answer) { - if ($ttl === null || $answer->ttl < $ttl) { - $ttl = $answer->ttl; - } - } - - if ($ttl === null) { - $ttl = self::TTL; - } - - return $ttl; - } -} diff --git a/vendor/react/dns/src/Query/CancellationException.php b/vendor/react/dns/src/Query/CancellationException.php deleted file mode 100644 index 5432b36fe..000000000 --- a/vendor/react/dns/src/Query/CancellationException.php +++ /dev/null @@ -1,7 +0,0 @@ -executor = $base; - } - - public function query(Query $query) - { - $key = $this->serializeQueryToIdentity($query); - if (isset($this->pending[$key])) { - // same query is already pending, so use shared reference to pending query - $promise = $this->pending[$key]; - ++$this->counts[$key]; - } else { - // no such query pending, so start new query and keep reference until it's fulfilled or rejected - $promise = $this->executor->query($query); - $this->pending[$key] = $promise; - $this->counts[$key] = 1; - - $pending =& $this->pending; - $counts =& $this->counts; - $promise->then(function () use ($key, &$pending, &$counts) { - unset($pending[$key], $counts[$key]); - }, function () use ($key, &$pending, &$counts) { - unset($pending[$key], $counts[$key]); - }); - } - - // Return a child promise awaiting the pending query. - // Cancelling this child promise should only cancel the pending query - // when no other child promise is awaiting the same query. - $pending =& $this->pending; - $counts =& $this->counts; - return new Promise(function ($resolve, $reject) use ($promise) { - $promise->then($resolve, $reject); - }, function () use (&$promise, $key, $query, &$pending, &$counts) { - if (--$counts[$key] < 1) { - unset($pending[$key], $counts[$key]); - $promise->cancel(); - $promise = null; - } - throw new \RuntimeException('DNS query for ' . $query->describe() . ' has been cancelled'); - }); - } - - private function serializeQueryToIdentity(Query $query) - { - return sprintf('%s:%s:%s', $query->name, $query->type, $query->class); - } -} diff --git a/vendor/react/dns/src/Query/ExecutorInterface.php b/vendor/react/dns/src/Query/ExecutorInterface.php deleted file mode 100644 index b356dc62f..000000000 --- a/vendor/react/dns/src/Query/ExecutorInterface.php +++ /dev/null @@ -1,43 +0,0 @@ -query($query)->then( - * function (React\Dns\Model\Message $response) { - * // response message successfully received - * var_dump($response->rcode, $response->answers); - * }, - * function (Exception $error) { - * // failed to query due to $error - * } - * ); - * ``` - * - * The returned Promise MUST be implemented in such a way that it can be - * cancelled when it is still pending. Cancelling a pending promise MUST - * reject its value with an Exception. It SHOULD clean up any underlying - * resources and references as applicable. - * - * ```php - * $promise = $executor->query($query); - * - * $promise->cancel(); - * ``` - * - * @param Query $query - * @return \React\Promise\PromiseInterface<\React\Dns\Model\Message,\Exception> - * resolves with response message on success or rejects with an Exception on error - */ - public function query(Query $query); -} diff --git a/vendor/react/dns/src/Query/FallbackExecutor.php b/vendor/react/dns/src/Query/FallbackExecutor.php deleted file mode 100644 index 83bd360bd..000000000 --- a/vendor/react/dns/src/Query/FallbackExecutor.php +++ /dev/null @@ -1,49 +0,0 @@ -executor = $executor; - $this->fallback = $fallback; - } - - public function query(Query $query) - { - $cancelled = false; - $fallback = $this->fallback; - $promise = $this->executor->query($query); - - return new Promise(function ($resolve, $reject) use (&$promise, $fallback, $query, &$cancelled) { - $promise->then($resolve, function (\Exception $e1) use ($fallback, $query, $resolve, $reject, &$cancelled, &$promise) { - // reject if primary resolution rejected due to cancellation - if ($cancelled) { - $reject($e1); - return; - } - - // start fallback query if primary query rejected - $promise = $fallback->query($query)->then($resolve, function (\Exception $e2) use ($e1, $reject) { - $append = $e2->getMessage(); - if (($pos = strpos($append, ':')) !== false) { - $append = substr($append, $pos + 2); - } - - // reject with combined error message if both queries fail - $reject(new \RuntimeException($e1->getMessage() . '. ' . $append)); - }); - }); - }, function () use (&$promise, &$cancelled) { - // cancel pending query (primary or fallback) - $cancelled = true; - $promise->cancel(); - }); - } -} diff --git a/vendor/react/dns/src/Query/HostsFileExecutor.php b/vendor/react/dns/src/Query/HostsFileExecutor.php deleted file mode 100644 index d6e2d9347..000000000 --- a/vendor/react/dns/src/Query/HostsFileExecutor.php +++ /dev/null @@ -1,89 +0,0 @@ -hosts = $hosts; - $this->fallback = $fallback; - } - - public function query(Query $query) - { - if ($query->class === Message::CLASS_IN && ($query->type === Message::TYPE_A || $query->type === Message::TYPE_AAAA)) { - // forward lookup for type A or AAAA - $records = array(); - $expectsColon = $query->type === Message::TYPE_AAAA; - foreach ($this->hosts->getIpsForHost($query->name) as $ip) { - // ensure this is an IPv4/IPV6 address according to query type - if ((strpos($ip, ':') !== false) === $expectsColon) { - $records[] = new Record($query->name, $query->type, $query->class, 0, $ip); - } - } - - if ($records) { - return Promise\resolve( - Message::createResponseWithAnswersForQuery($query, $records) - ); - } - } elseif ($query->class === Message::CLASS_IN && $query->type === Message::TYPE_PTR) { - // reverse lookup: extract IPv4 or IPv6 from special `.arpa` domain - $ip = $this->getIpFromHost($query->name); - - if ($ip !== null) { - $records = array(); - foreach ($this->hosts->getHostsForIp($ip) as $host) { - $records[] = new Record($query->name, $query->type, $query->class, 0, $host); - } - - if ($records) { - return Promise\resolve( - Message::createResponseWithAnswersForQuery($query, $records) - ); - } - } - } - - return $this->fallback->query($query); - } - - private function getIpFromHost($host) - { - if (substr($host, -13) === '.in-addr.arpa') { - // IPv4: read as IP and reverse bytes - $ip = @inet_pton(substr($host, 0, -13)); - if ($ip === false || isset($ip[4])) { - return null; - } - - return inet_ntop(strrev($ip)); - } elseif (substr($host, -9) === '.ip6.arpa') { - // IPv6: replace dots, reverse nibbles and interpret as hexadecimal string - $ip = @inet_ntop(pack('H*', strrev(str_replace('.', '', substr($host, 0, -9))))); - if ($ip === false) { - return null; - } - - return $ip; - } else { - return null; - } - } -} diff --git a/vendor/react/dns/src/Query/Query.php b/vendor/react/dns/src/Query/Query.php deleted file mode 100644 index a3dcfb582..000000000 --- a/vendor/react/dns/src/Query/Query.php +++ /dev/null @@ -1,69 +0,0 @@ -name = $name; - $this->type = $type; - $this->class = $class; - } - - /** - * Describes the hostname and query type/class for this query - * - * The output format is supposed to be human readable and is subject to change. - * The format is inspired by RFC 3597 when handling unkown types/classes. - * - * @return string "example.com (A)" or "example.com (CLASS0 TYPE1234)" - * @link https://tools.ietf.org/html/rfc3597 - */ - public function describe() - { - $class = $this->class !== Message::CLASS_IN ? 'CLASS' . $this->class . ' ' : ''; - - $type = 'TYPE' . $this->type; - $ref = new \ReflectionClass('React\Dns\Model\Message'); - foreach ($ref->getConstants() as $name => $value) { - if ($value === $this->type && \strpos($name, 'TYPE_') === 0) { - $type = \substr($name, 5); - break; - } - } - - return $this->name . ' (' . $class . $type . ')'; - } -} diff --git a/vendor/react/dns/src/Query/RetryExecutor.php b/vendor/react/dns/src/Query/RetryExecutor.php deleted file mode 100644 index 7efcacc8c..000000000 --- a/vendor/react/dns/src/Query/RetryExecutor.php +++ /dev/null @@ -1,86 +0,0 @@ -executor = $executor; - $this->retries = $retries; - } - - public function query(Query $query) - { - return $this->tryQuery($query, $this->retries); - } - - public function tryQuery(Query $query, $retries) - { - $deferred = new Deferred(function () use (&$promise) { - if ($promise instanceof CancellablePromiseInterface || (!\interface_exists('React\Promise\CancellablePromiseInterface') && \method_exists($promise, 'cancel'))) { - $promise->cancel(); - } - }); - - $success = function ($value) use ($deferred, &$errorback) { - $errorback = null; - $deferred->resolve($value); - }; - - $executor = $this->executor; - $errorback = function ($e) use ($deferred, &$promise, $query, $success, &$errorback, &$retries, $executor) { - if (!$e instanceof TimeoutException) { - $errorback = null; - $deferred->reject($e); - } elseif ($retries <= 0) { - $errorback = null; - $deferred->reject($e = new \RuntimeException( - 'DNS query for ' . $query->describe() . ' failed: too many retries', - 0, - $e - )); - - // avoid garbage references by replacing all closures in call stack. - // what a lovely piece of code! - $r = new \ReflectionProperty('Exception', 'trace'); - $r->setAccessible(true); - $trace = $r->getValue($e); - - // Exception trace arguments are not available on some PHP 7.4 installs - // @codeCoverageIgnoreStart - foreach ($trace as &$one) { - if (isset($one['args'])) { - foreach ($one['args'] as &$arg) { - if ($arg instanceof \Closure) { - $arg = 'Object(' . \get_class($arg) . ')'; - } - } - } - } - // @codeCoverageIgnoreEnd - $r->setValue($e, $trace); - } else { - --$retries; - $promise = $executor->query($query)->then( - $success, - $errorback - ); - } - }; - - $promise = $this->executor->query($query)->then( - $success, - $errorback - ); - - return $deferred->promise(); - } -} diff --git a/vendor/react/dns/src/Query/SelectiveTransportExecutor.php b/vendor/react/dns/src/Query/SelectiveTransportExecutor.php deleted file mode 100644 index 0f0ca5d08..000000000 --- a/vendor/react/dns/src/Query/SelectiveTransportExecutor.php +++ /dev/null @@ -1,85 +0,0 @@ -query( - * new Query($name, Message::TYPE_AAAA, Message::CLASS_IN) - * )->then(function (Message $message) { - * foreach ($message->answers as $answer) { - * echo 'IPv6: ' . $answer->data . PHP_EOL; - * } - * }, 'printf'); - * ``` - * - * Note that this executor only implements the logic to select the correct - * transport for the given DNS query. Implementing the correct transport logic, - * implementing timeouts and any retry logic is left up to the given executors, - * see also [`UdpTransportExecutor`](#udptransportexecutor) and - * [`TcpTransportExecutor`](#tcptransportexecutor) for more details. - * - * Note that this executor is entirely async and as such allows you to execute - * any number of queries concurrently. You should probably limit the number of - * concurrent queries in your application or you're very likely going to face - * rate limitations and bans on the resolver end. For many common applications, - * you may want to avoid sending the same query multiple times when the first - * one is still pending, so you will likely want to use this in combination with - * a `CoopExecutor` like this: - * - * ```php - * $executor = new CoopExecutor( - * new SelectiveTransportExecutor( - * $datagramExecutor, - * $streamExecutor - * ) - * ); - * ``` - */ -class SelectiveTransportExecutor implements ExecutorInterface -{ - private $datagramExecutor; - private $streamExecutor; - - public function __construct(ExecutorInterface $datagramExecutor, ExecutorInterface $streamExecutor) - { - $this->datagramExecutor = $datagramExecutor; - $this->streamExecutor = $streamExecutor; - } - - public function query(Query $query) - { - $stream = $this->streamExecutor; - $pending = $this->datagramExecutor->query($query); - - return new Promise(function ($resolve, $reject) use (&$pending, $stream, $query) { - $pending->then( - $resolve, - function ($e) use (&$pending, $stream, $query, $resolve, $reject) { - if ($e->getCode() === (\defined('SOCKET_EMSGSIZE') ? \SOCKET_EMSGSIZE : 90)) { - $pending = $stream->query($query)->then($resolve, $reject); - } else { - $reject($e); - } - } - ); - }, function () use (&$pending) { - $pending->cancel(); - $pending = null; - }); - } -} diff --git a/vendor/react/dns/src/Query/TcpTransportExecutor.php b/vendor/react/dns/src/Query/TcpTransportExecutor.php deleted file mode 100644 index 6644e16ad..000000000 --- a/vendor/react/dns/src/Query/TcpTransportExecutor.php +++ /dev/null @@ -1,367 +0,0 @@ -query( - * new Query($name, Message::TYPE_AAAA, Message::CLASS_IN) - * )->then(function (Message $message) { - * foreach ($message->answers as $answer) { - * echo 'IPv6: ' . $answer->data . PHP_EOL; - * } - * }, 'printf'); - * ``` - * - * See also [example #92](examples). - * - * Note that this executor does not implement a timeout, so you will very likely - * want to use this in combination with a `TimeoutExecutor` like this: - * - * ```php - * $executor = new TimeoutExecutor( - * new TcpTransportExecutor($nameserver), - * 3.0 - * ); - * ``` - * - * Unlike the `UdpTransportExecutor`, this class uses a reliable TCP/IP - * transport, so you do not necessarily have to implement any retry logic. - * - * Note that this executor is entirely async and as such allows you to execute - * queries concurrently. The first query will establish a TCP/IP socket - * connection to the DNS server which will be kept open for a short period. - * Additional queries will automatically reuse this existing socket connection - * to the DNS server, will pipeline multiple requests over this single - * connection and will keep an idle connection open for a short period. The - * initial TCP/IP connection overhead may incur a slight delay if you only send - * occasional queries – when sending a larger number of concurrent queries over - * an existing connection, it becomes increasingly more efficient and avoids - * creating many concurrent sockets like the UDP-based executor. You may still - * want to limit the number of (concurrent) queries in your application or you - * may be facing rate limitations and bans on the resolver end. For many common - * applications, you may want to avoid sending the same query multiple times - * when the first one is still pending, so you will likely want to use this in - * combination with a `CoopExecutor` like this: - * - * ```php - * $executor = new CoopExecutor( - * new TimeoutExecutor( - * new TcpTransportExecutor($nameserver), - * 3.0 - * ) - * ); - * ``` - * - * > Internally, this class uses PHP's TCP/IP sockets and does not take advantage - * of [react/socket](https://github.com/reactphp/socket) purely for - * organizational reasons to avoid a cyclic dependency between the two - * packages. Higher-level components should take advantage of the Socket - * component instead of reimplementing this socket logic from scratch. - */ -class TcpTransportExecutor implements ExecutorInterface -{ - private $nameserver; - private $loop; - private $parser; - private $dumper; - - /** - * @var ?resource - */ - private $socket; - - /** - * @var Deferred[] - */ - private $pending = array(); - - /** - * @var string[] - */ - private $names = array(); - - /** - * Maximum idle time when socket is current unused (i.e. no pending queries outstanding) - * - * If a new query is to be sent during the idle period, we can reuse the - * existing socket without having to wait for a new socket connection. - * This uses a rather small, hard-coded value to not keep any unneeded - * sockets open and to not keep the loop busy longer than needed. - * - * A future implementation may take advantage of `edns-tcp-keepalive` to keep - * the socket open for longer periods. This will likely require explicit - * configuration because this may consume additional resources and also keep - * the loop busy for longer than expected in some applications. - * - * @var float - * @link https://tools.ietf.org/html/rfc7766#section-6.2.1 - * @link https://tools.ietf.org/html/rfc7828 - */ - private $idlePeriod = 0.001; - - /** - * @var ?\React\EventLoop\TimerInterface - */ - private $idleTimer; - - private $writeBuffer = ''; - private $writePending = false; - - private $readBuffer = ''; - private $readPending = false; - - /** @var string */ - private $readChunk = 0xffff; - - /** - * @param string $nameserver - * @param ?LoopInterface $loop - */ - public function __construct($nameserver, LoopInterface $loop = null) - { - if (\strpos($nameserver, '[') === false && \substr_count($nameserver, ':') >= 2 && \strpos($nameserver, '://') === false) { - // several colons, but not enclosed in square brackets => enclose IPv6 address in square brackets - $nameserver = '[' . $nameserver . ']'; - } - - $parts = \parse_url((\strpos($nameserver, '://') === false ? 'tcp://' : '') . $nameserver); - if (!isset($parts['scheme'], $parts['host']) || $parts['scheme'] !== 'tcp' || @\inet_pton(\trim($parts['host'], '[]')) === false) { - throw new \InvalidArgumentException('Invalid nameserver address given'); - } - - $this->nameserver = 'tcp://' . $parts['host'] . ':' . (isset($parts['port']) ? $parts['port'] : 53); - $this->loop = $loop ?: Loop::get(); - $this->parser = new Parser(); - $this->dumper = new BinaryDumper(); - } - - public function query(Query $query) - { - $request = Message::createRequestForQuery($query); - - // keep shuffing message ID to avoid using the same message ID for two pending queries at the same time - while (isset($this->pending[$request->id])) { - $request->id = \mt_rand(0, 0xffff); // @codeCoverageIgnore - } - - $queryData = $this->dumper->toBinary($request); - $length = \strlen($queryData); - if ($length > 0xffff) { - return \React\Promise\reject(new \RuntimeException( - 'DNS query for ' . $query->describe() . ' failed: Query too large for TCP transport' - )); - } - - $queryData = \pack('n', $length) . $queryData; - - if ($this->socket === null) { - // create async TCP/IP connection (may take a while) - $socket = @\stream_socket_client($this->nameserver, $errno, $errstr, 0, \STREAM_CLIENT_CONNECT | \STREAM_CLIENT_ASYNC_CONNECT); - if ($socket === false) { - return \React\Promise\reject(new \RuntimeException( - 'DNS query for ' . $query->describe() . ' failed: Unable to connect to DNS server ' . $this->nameserver . ' (' . $errstr . ')', - $errno - )); - } - - // set socket to non-blocking and wait for it to become writable (connection success/rejected) - \stream_set_blocking($socket, false); - if (\function_exists('stream_set_chunk_size')) { - \stream_set_chunk_size($socket, $this->readChunk); // @codeCoverageIgnore - } - $this->socket = $socket; - } - - if ($this->idleTimer !== null) { - $this->loop->cancelTimer($this->idleTimer); - $this->idleTimer = null; - } - - // wait for socket to become writable to actually write out data - $this->writeBuffer .= $queryData; - if (!$this->writePending) { - $this->writePending = true; - $this->loop->addWriteStream($this->socket, array($this, 'handleWritable')); - } - - $names =& $this->names; - $that = $this; - $deferred = new Deferred(function () use ($that, &$names, $request) { - // remove from list of pending names, but remember pending query - $name = $names[$request->id]; - unset($names[$request->id]); - $that->checkIdle(); - - throw new CancellationException('DNS query for ' . $name . ' has been cancelled'); - }); - - $this->pending[$request->id] = $deferred; - $this->names[$request->id] = $query->describe(); - - return $deferred->promise(); - } - - /** - * @internal - */ - public function handleWritable() - { - if ($this->readPending === false) { - $name = @\stream_socket_get_name($this->socket, true); - if ($name === false) { - // Connection failed? Check socket error if available for underlying errno/errstr. - // @codeCoverageIgnoreStart - if (\function_exists('socket_import_stream')) { - $socket = \socket_import_stream($this->socket); - $errno = \socket_get_option($socket, \SOL_SOCKET, \SO_ERROR); - $errstr = \socket_strerror($errno); - } else { - $errno = \defined('SOCKET_ECONNREFUSED') ? \SOCKET_ECONNREFUSED : 111; - $errstr = 'Connection refused'; - } - // @codeCoverageIgnoreEnd - - $this->closeError('Unable to connect to DNS server ' . $this->nameserver . ' (' . $errstr . ')', $errno); - return; - } - - $this->readPending = true; - $this->loop->addReadStream($this->socket, array($this, 'handleRead')); - } - - $written = @\fwrite($this->socket, $this->writeBuffer); - if ($written === false || $written === 0) { - $error = \error_get_last(); - \preg_match('/errno=(\d+) (.+)/', $error['message'], $m); - $this->closeError( - 'Unable to send query to DNS server ' . $this->nameserver . ' (' . (isset($m[2]) ? $m[2] : $error['message']) . ')', - isset($m[1]) ? (int) $m[1] : 0 - ); - return; - } - - if (isset($this->writeBuffer[$written])) { - $this->writeBuffer = \substr($this->writeBuffer, $written); - } else { - $this->loop->removeWriteStream($this->socket); - $this->writePending = false; - $this->writeBuffer = ''; - } - } - - /** - * @internal - */ - public function handleRead() - { - // read one chunk of data from the DNS server - // any error is fatal, this is a stream of TCP/IP data - $chunk = @\fread($this->socket, $this->readChunk); - if ($chunk === false || $chunk === '') { - $this->closeError('Connection to DNS server ' . $this->nameserver . ' lost'); - return; - } - - // reassemble complete message by concatenating all chunks. - $this->readBuffer .= $chunk; - - // response message header contains at least 12 bytes - while (isset($this->readBuffer[11])) { - // read response message length from first 2 bytes and ensure we have length + data in buffer - list(, $length) = \unpack('n', $this->readBuffer); - if (!isset($this->readBuffer[$length + 1])) { - return; - } - - $data = \substr($this->readBuffer, 2, $length); - $this->readBuffer = (string)substr($this->readBuffer, $length + 2); - - try { - $response = $this->parser->parseMessage($data); - } catch (\Exception $e) { - // reject all pending queries if we received an invalid message from remote server - $this->closeError('Invalid message received from DNS server ' . $this->nameserver); - return; - } - - // reject all pending queries if we received an unexpected response ID or truncated response - if (!isset($this->pending[$response->id]) || $response->tc) { - $this->closeError('Invalid response message received from DNS server ' . $this->nameserver); - return; - } - - $deferred = $this->pending[$response->id]; - unset($this->pending[$response->id], $this->names[$response->id]); - - $deferred->resolve($response); - - $this->checkIdle(); - } - } - - /** - * @internal - * @param string $reason - * @param int $code - */ - public function closeError($reason, $code = 0) - { - $this->readBuffer = ''; - if ($this->readPending) { - $this->loop->removeReadStream($this->socket); - $this->readPending = false; - } - - $this->writeBuffer = ''; - if ($this->writePending) { - $this->loop->removeWriteStream($this->socket); - $this->writePending = false; - } - - if ($this->idleTimer !== null) { - $this->loop->cancelTimer($this->idleTimer); - $this->idleTimer = null; - } - - @\fclose($this->socket); - $this->socket = null; - - foreach ($this->names as $id => $name) { - $this->pending[$id]->reject(new \RuntimeException( - 'DNS query for ' . $name . ' failed: ' . $reason, - $code - )); - } - $this->pending = $this->names = array(); - } - - /** - * @internal - */ - public function checkIdle() - { - if ($this->idleTimer === null && !$this->names) { - $that = $this; - $this->idleTimer = $this->loop->addTimer($this->idlePeriod, function () use ($that) { - $that->closeError('Idle timeout'); - }); - } - } -} diff --git a/vendor/react/dns/src/Query/TimeoutException.php b/vendor/react/dns/src/Query/TimeoutException.php deleted file mode 100644 index 109b0a9d0..000000000 --- a/vendor/react/dns/src/Query/TimeoutException.php +++ /dev/null @@ -1,7 +0,0 @@ -executor = $executor; - $this->loop = $loop ?: Loop::get(); - $this->timeout = $timeout; - } - - public function query(Query $query) - { - return Timer\timeout($this->executor->query($query), $this->timeout, $this->loop)->then(null, function ($e) use ($query) { - if ($e instanceof Timer\TimeoutException) { - $e = new TimeoutException(sprintf("DNS query for %s timed out", $query->describe()), 0, $e); - } - throw $e; - }); - } -} diff --git a/vendor/react/dns/src/Query/UdpTransportExecutor.php b/vendor/react/dns/src/Query/UdpTransportExecutor.php deleted file mode 100644 index 4c995a86d..000000000 --- a/vendor/react/dns/src/Query/UdpTransportExecutor.php +++ /dev/null @@ -1,208 +0,0 @@ -query( - * new Query($name, Message::TYPE_AAAA, Message::CLASS_IN) - * )->then(function (Message $message) { - * foreach ($message->answers as $answer) { - * echo 'IPv6: ' . $answer->data . PHP_EOL; - * } - * }, 'printf'); - * ``` - * - * See also the [fourth example](examples). - * - * Note that this executor does not implement a timeout, so you will very likely - * want to use this in combination with a `TimeoutExecutor` like this: - * - * ```php - * $executor = new TimeoutExecutor( - * new UdpTransportExecutor($nameserver), - * 3.0 - * ); - * ``` - * - * Also note that this executor uses an unreliable UDP transport and that it - * does not implement any retry logic, so you will likely want to use this in - * combination with a `RetryExecutor` like this: - * - * ```php - * $executor = new RetryExecutor( - * new TimeoutExecutor( - * new UdpTransportExecutor($nameserver), - * 3.0 - * ) - * ); - * ``` - * - * Note that this executor is entirely async and as such allows you to execute - * any number of queries concurrently. You should probably limit the number of - * concurrent queries in your application or you're very likely going to face - * rate limitations and bans on the resolver end. For many common applications, - * you may want to avoid sending the same query multiple times when the first - * one is still pending, so you will likely want to use this in combination with - * a `CoopExecutor` like this: - * - * ```php - * $executor = new CoopExecutor( - * new RetryExecutor( - * new TimeoutExecutor( - * new UdpTransportExecutor($nameserver), - * 3.0 - * ) - * ) - * ); - * ``` - * - * > Internally, this class uses PHP's UDP sockets and does not take advantage - * of [react/datagram](https://github.com/reactphp/datagram) purely for - * organizational reasons to avoid a cyclic dependency between the two - * packages. Higher-level components should take advantage of the Datagram - * component instead of reimplementing this socket logic from scratch. - */ -final class UdpTransportExecutor implements ExecutorInterface -{ - private $nameserver; - private $loop; - private $parser; - private $dumper; - - /** - * maximum UDP packet size to send and receive - * - * @var int - */ - private $maxPacketSize = 512; - - /** - * @param string $nameserver - * @param ?LoopInterface $loop - */ - public function __construct($nameserver, LoopInterface $loop = null) - { - if (\strpos($nameserver, '[') === false && \substr_count($nameserver, ':') >= 2 && \strpos($nameserver, '://') === false) { - // several colons, but not enclosed in square brackets => enclose IPv6 address in square brackets - $nameserver = '[' . $nameserver . ']'; - } - - $parts = \parse_url((\strpos($nameserver, '://') === false ? 'udp://' : '') . $nameserver); - if (!isset($parts['scheme'], $parts['host']) || $parts['scheme'] !== 'udp' || @\inet_pton(\trim($parts['host'], '[]')) === false) { - throw new \InvalidArgumentException('Invalid nameserver address given'); - } - - $this->nameserver = 'udp://' . $parts['host'] . ':' . (isset($parts['port']) ? $parts['port'] : 53); - $this->loop = $loop ?: Loop::get(); - $this->parser = new Parser(); - $this->dumper = new BinaryDumper(); - } - - public function query(Query $query) - { - $request = Message::createRequestForQuery($query); - - $queryData = $this->dumper->toBinary($request); - if (isset($queryData[$this->maxPacketSize])) { - return \React\Promise\reject(new \RuntimeException( - 'DNS query for ' . $query->describe() . ' failed: Query too large for UDP transport', - \defined('SOCKET_EMSGSIZE') ? \SOCKET_EMSGSIZE : 90 - )); - } - - // UDP connections are instant, so try connection without a loop or timeout - $socket = @\stream_socket_client($this->nameserver, $errno, $errstr, 0); - if ($socket === false) { - return \React\Promise\reject(new \RuntimeException( - 'DNS query for ' . $query->describe() . ' failed: Unable to connect to DNS server ' . $this->nameserver . ' (' . $errstr . ')', - $errno - )); - } - - // set socket to non-blocking and immediately try to send (fill write buffer) - \stream_set_blocking($socket, false); - $written = @\fwrite($socket, $queryData); - - if ($written !== \strlen($queryData)) { - // Write may potentially fail, but most common errors are already caught by connection check above. - // Among others, macOS is known to report here when trying to send to broadcast address. - // This can also be reproduced by writing data exceeding `stream_set_chunk_size()` to a server refusing UDP data. - // fwrite(): send of 8192 bytes failed with errno=111 Connection refused - $error = \error_get_last(); - \preg_match('/errno=(\d+) (.+)/', $error['message'], $m); - return \React\Promise\reject(new \RuntimeException( - 'DNS query for ' . $query->describe() . ' failed: Unable to send query to DNS server ' . $this->nameserver . ' (' . (isset($m[2]) ? $m[2] : $error['message']) . ')', - isset($m[1]) ? (int) $m[1] : 0 - )); - } - - $loop = $this->loop; - $deferred = new Deferred(function () use ($loop, $socket, $query) { - // cancellation should remove socket from loop and close socket - $loop->removeReadStream($socket); - \fclose($socket); - - throw new CancellationException('DNS query for ' . $query->describe() . ' has been cancelled'); - }); - - $max = $this->maxPacketSize; - $parser = $this->parser; - $nameserver = $this->nameserver; - $loop->addReadStream($socket, function ($socket) use ($loop, $deferred, $query, $parser, $request, $max, $nameserver) { - // try to read a single data packet from the DNS server - // ignoring any errors, this is uses UDP packets and not a stream of data - $data = @\fread($socket, $max); - if ($data === false) { - return; - } - - try { - $response = $parser->parseMessage($data); - } catch (\Exception $e) { - // ignore and await next if we received an invalid message from remote server - // this may as well be a fake response from an attacker (possible DOS) - return; - } - - // ignore and await next if we received an unexpected response ID - // this may as well be a fake response from an attacker (possible cache poisoning) - if ($response->id !== $request->id) { - return; - } - - // we only react to the first valid message, so remove socket from loop and close - $loop->removeReadStream($socket); - \fclose($socket); - - if ($response->tc) { - $deferred->reject(new \RuntimeException( - 'DNS query for ' . $query->describe() . ' failed: The DNS server ' . $nameserver . ' returned a truncated result for a UDP query', - \defined('SOCKET_EMSGSIZE') ? \SOCKET_EMSGSIZE : 90 - )); - return; - } - - $deferred->resolve($response); - }); - - return $deferred->promise(); - } -} diff --git a/vendor/react/dns/src/RecordNotFoundException.php b/vendor/react/dns/src/RecordNotFoundException.php deleted file mode 100644 index 3b7027428..000000000 --- a/vendor/react/dns/src/RecordNotFoundException.php +++ /dev/null @@ -1,7 +0,0 @@ -decorateHostsFileExecutor($this->createExecutor($config, $loop ?: Loop::get())); - - return new Resolver($executor); - } - - /** - * Creates a cached DNS resolver instance for the given DNS config and cache - * - * As of v1.7.0 it's recommended to pass a `Config` object instead of a - * single nameserver address. If the given config contains more than one DNS - * nameserver, all DNS nameservers will be used in order. The primary DNS - * server will always be used first before falling back to the secondary or - * tertiary DNS server. - * - * @param Config|string $config DNS Config object (recommended) or single nameserver address - * @param ?LoopInterface $loop - * @param ?CacheInterface $cache - * @return \React\Dns\Resolver\ResolverInterface - * @throws \InvalidArgumentException for invalid DNS server address - * @throws \UnderflowException when given DNS Config object has an empty list of nameservers - */ - public function createCached($config, LoopInterface $loop = null, CacheInterface $cache = null) - { - // default to keeping maximum of 256 responses in cache unless explicitly given - if (!($cache instanceof CacheInterface)) { - $cache = new ArrayCache(256); - } - - $executor = $this->createExecutor($config, $loop ?: Loop::get()); - $executor = new CachingExecutor($executor, $cache); - $executor = $this->decorateHostsFileExecutor($executor); - - return new Resolver($executor); - } - - /** - * Tries to load the hosts file and decorates the given executor on success - * - * @param ExecutorInterface $executor - * @return ExecutorInterface - * @codeCoverageIgnore - */ - private function decorateHostsFileExecutor(ExecutorInterface $executor) - { - try { - $executor = new HostsFileExecutor( - HostsFile::loadFromPathBlocking(), - $executor - ); - } catch (\RuntimeException $e) { - // ignore this file if it can not be loaded - } - - // Windows does not store localhost in hosts file by default but handles this internally - // To compensate for this, we explicitly use hard-coded defaults for localhost - if (DIRECTORY_SEPARATOR === '\\') { - $executor = new HostsFileExecutor( - new HostsFile("127.0.0.1 localhost\n::1 localhost"), - $executor - ); - } - - return $executor; - } - - /** - * @param Config|string $nameserver - * @param LoopInterface $loop - * @return CoopExecutor - * @throws \InvalidArgumentException for invalid DNS server address - * @throws \UnderflowException when given DNS Config object has an empty list of nameservers - */ - private function createExecutor($nameserver, LoopInterface $loop) - { - if ($nameserver instanceof Config) { - if (!$nameserver->nameservers) { - throw new \UnderflowException('Empty config with no DNS servers'); - } - - // Hard-coded to check up to 3 DNS servers to match default limits in place in most systems (see MAXNS config). - // Note to future self: Recursion isn't too hard, but how deep do we really want to go? - $primary = reset($nameserver->nameservers); - $secondary = next($nameserver->nameservers); - $tertiary = next($nameserver->nameservers); - - if ($tertiary !== false) { - // 3 DNS servers given => nest first with fallback for second and third - return new CoopExecutor( - new RetryExecutor( - new FallbackExecutor( - $this->createSingleExecutor($primary, $loop), - new FallbackExecutor( - $this->createSingleExecutor($secondary, $loop), - $this->createSingleExecutor($tertiary, $loop) - ) - ) - ) - ); - } elseif ($secondary !== false) { - // 2 DNS servers given => fallback from first to second - return new CoopExecutor( - new RetryExecutor( - new FallbackExecutor( - $this->createSingleExecutor($primary, $loop), - $this->createSingleExecutor($secondary, $loop) - ) - ) - ); - } else { - // 1 DNS server given => use single executor - $nameserver = $primary; - } - } - - return new CoopExecutor(new RetryExecutor($this->createSingleExecutor($nameserver, $loop))); - } - - /** - * @param string $nameserver - * @param LoopInterface $loop - * @return ExecutorInterface - * @throws \InvalidArgumentException for invalid DNS server address - */ - private function createSingleExecutor($nameserver, LoopInterface $loop) - { - $parts = \parse_url($nameserver); - - if (isset($parts['scheme']) && $parts['scheme'] === 'tcp') { - $executor = $this->createTcpExecutor($nameserver, $loop); - } elseif (isset($parts['scheme']) && $parts['scheme'] === 'udp') { - $executor = $this->createUdpExecutor($nameserver, $loop); - } else { - $executor = new SelectiveTransportExecutor( - $this->createUdpExecutor($nameserver, $loop), - $this->createTcpExecutor($nameserver, $loop) - ); - } - - return $executor; - } - - /** - * @param string $nameserver - * @param LoopInterface $loop - * @return TimeoutExecutor - * @throws \InvalidArgumentException for invalid DNS server address - */ - private function createTcpExecutor($nameserver, LoopInterface $loop) - { - return new TimeoutExecutor( - new TcpTransportExecutor($nameserver, $loop), - 5.0, - $loop - ); - } - - /** - * @param string $nameserver - * @param LoopInterface $loop - * @return TimeoutExecutor - * @throws \InvalidArgumentException for invalid DNS server address - */ - private function createUdpExecutor($nameserver, LoopInterface $loop) - { - return new TimeoutExecutor( - new UdpTransportExecutor( - $nameserver, - $loop - ), - 5.0, - $loop - ); - } -} diff --git a/vendor/react/dns/src/Resolver/Resolver.php b/vendor/react/dns/src/Resolver/Resolver.php deleted file mode 100644 index 92926f3f1..000000000 --- a/vendor/react/dns/src/Resolver/Resolver.php +++ /dev/null @@ -1,147 +0,0 @@ -executor = $executor; - } - - public function resolve($domain) - { - return $this->resolveAll($domain, Message::TYPE_A)->then(function (array $ips) { - return $ips[array_rand($ips)]; - }); - } - - public function resolveAll($domain, $type) - { - $query = new Query($domain, $type, Message::CLASS_IN); - $that = $this; - - return $this->executor->query( - $query - )->then(function (Message $response) use ($query, $that) { - return $that->extractValues($query, $response); - }); - } - - /** - * [Internal] extract all resource record values from response for this query - * - * @param Query $query - * @param Message $response - * @return array - * @throws RecordNotFoundException when response indicates an error or contains no data - * @internal - */ - public function extractValues(Query $query, Message $response) - { - // reject if response code indicates this is an error response message - $code = $response->rcode; - if ($code !== Message::RCODE_OK) { - switch ($code) { - case Message::RCODE_FORMAT_ERROR: - $message = 'Format Error'; - break; - case Message::RCODE_SERVER_FAILURE: - $message = 'Server Failure'; - break; - case Message::RCODE_NAME_ERROR: - $message = 'Non-Existent Domain / NXDOMAIN'; - break; - case Message::RCODE_NOT_IMPLEMENTED: - $message = 'Not Implemented'; - break; - case Message::RCODE_REFUSED: - $message = 'Refused'; - break; - default: - $message = 'Unknown error response code ' . $code; - } - throw new RecordNotFoundException( - 'DNS query for ' . $query->describe() . ' returned an error response (' . $message . ')', - $code - ); - } - - $answers = $response->answers; - $addresses = $this->valuesByNameAndType($answers, $query->name, $query->type); - - // reject if we did not receive a valid answer (domain is valid, but no record for this type could be found) - if (0 === count($addresses)) { - throw new RecordNotFoundException( - 'DNS query for ' . $query->describe() . ' did not return a valid answer (NOERROR / NODATA)' - ); - } - - return array_values($addresses); - } - - /** - * @param \React\Dns\Model\Record[] $answers - * @param string $name - * @param int $type - * @return array - */ - private function valuesByNameAndType(array $answers, $name, $type) - { - // return all record values for this name and type (if any) - $named = $this->filterByName($answers, $name); - $records = $this->filterByType($named, $type); - if ($records) { - return $this->mapRecordData($records); - } - - // no matching records found? check if there are any matching CNAMEs instead - $cnameRecords = $this->filterByType($named, Message::TYPE_CNAME); - if ($cnameRecords) { - $cnames = $this->mapRecordData($cnameRecords); - foreach ($cnames as $cname) { - $records = array_merge( - $records, - $this->valuesByNameAndType($answers, $cname, $type) - ); - } - } - - return $records; - } - - private function filterByName(array $answers, $name) - { - return $this->filterByField($answers, 'name', $name); - } - - private function filterByType(array $answers, $type) - { - return $this->filterByField($answers, 'type', $type); - } - - private function filterByField(array $answers, $field, $value) - { - $value = strtolower($value); - return array_filter($answers, function ($answer) use ($field, $value) { - return $value === strtolower($answer->$field); - }); - } - - private function mapRecordData(array $records) - { - return array_map(function ($record) { - return $record->data; - }, $records); - } -} diff --git a/vendor/react/dns/src/Resolver/ResolverInterface.php b/vendor/react/dns/src/Resolver/ResolverInterface.php deleted file mode 100644 index fe937dc7a..000000000 --- a/vendor/react/dns/src/Resolver/ResolverInterface.php +++ /dev/null @@ -1,94 +0,0 @@ -resolve('reactphp.org')->then(function ($ip) { - * echo 'IP for reactphp.org is ' . $ip . PHP_EOL; - * }); - * ``` - * - * This is one of the main methods in this package. It sends a DNS query - * for the given $domain name to your DNS server and returns a single IP - * address on success. - * - * If the DNS server sends a DNS response message that contains more than - * one IP address for this query, it will randomly pick one of the IP - * addresses from the response. If you want the full list of IP addresses - * or want to send a different type of query, you should use the - * [`resolveAll()`](#resolveall) method instead. - * - * If the DNS server sends a DNS response message that indicates an error - * code, this method will reject with a `RecordNotFoundException`. Its - * message and code can be used to check for the response code. - * - * If the DNS communication fails and the server does not respond with a - * valid response message, this message will reject with an `Exception`. - * - * Pending DNS queries can be cancelled by cancelling its pending promise like so: - * - * ```php - * $promise = $resolver->resolve('reactphp.org'); - * - * $promise->cancel(); - * ``` - * - * @param string $domain - * @return \React\Promise\PromiseInterface - * resolves with a single IP address on success or rejects with an Exception on error. - */ - public function resolve($domain); - - /** - * Resolves all record values for the given $domain name and query $type. - * - * ```php - * $resolver->resolveAll('reactphp.org', Message::TYPE_A)->then(function ($ips) { - * echo 'IPv4 addresses for reactphp.org ' . implode(', ', $ips) . PHP_EOL; - * }); - * - * $resolver->resolveAll('reactphp.org', Message::TYPE_AAAA)->then(function ($ips) { - * echo 'IPv6 addresses for reactphp.org ' . implode(', ', $ips) . PHP_EOL; - * }); - * ``` - * - * This is one of the main methods in this package. It sends a DNS query - * for the given $domain name to your DNS server and returns a list with all - * record values on success. - * - * If the DNS server sends a DNS response message that contains one or more - * records for this query, it will return a list with all record values - * from the response. You can use the `Message::TYPE_*` constants to control - * which type of query will be sent. Note that this method always returns a - * list of record values, but each record value type depends on the query - * type. For example, it returns the IPv4 addresses for type `A` queries, - * the IPv6 addresses for type `AAAA` queries, the hostname for type `NS`, - * `CNAME` and `PTR` queries and structured data for other queries. See also - * the `Record` documentation for more details. - * - * If the DNS server sends a DNS response message that indicates an error - * code, this method will reject with a `RecordNotFoundException`. Its - * message and code can be used to check for the response code. - * - * If the DNS communication fails and the server does not respond with a - * valid response message, this message will reject with an `Exception`. - * - * Pending DNS queries can be cancelled by cancelling its pending promise like so: - * - * ```php - * $promise = $resolver->resolveAll('reactphp.org', Message::TYPE_AAAA); - * - * $promise->cancel(); - * ``` - * - * @param string $domain - * @return \React\Promise\PromiseInterface - * Resolves with all record values on success or rejects with an Exception on error. - */ - public function resolveAll($domain, $type); -} diff --git a/vendor/react/event-loop/src/ExtEvLoop.php b/vendor/react/event-loop/src/ExtEvLoop.php deleted file mode 100644 index 7fcc29aff..000000000 --- a/vendor/react/event-loop/src/ExtEvLoop.php +++ /dev/null @@ -1,253 +0,0 @@ -loop = new EvLoop(); - $this->futureTickQueue = new FutureTickQueue(); - $this->timers = new SplObjectStorage(); - $this->signals = new SignalsHandler(); - } - - public function addReadStream($stream, $listener) - { - $key = (int)$stream; - - if (isset($this->readStreams[$key])) { - return; - } - - $callback = $this->getStreamListenerClosure($stream, $listener); - $event = $this->loop->io($stream, Ev::READ, $callback); - $this->readStreams[$key] = $event; - } - - /** - * @param resource $stream - * @param callable $listener - * - * @return \Closure - */ - private function getStreamListenerClosure($stream, $listener) - { - return function () use ($stream, $listener) { - \call_user_func($listener, $stream); - }; - } - - public function addWriteStream($stream, $listener) - { - $key = (int)$stream; - - if (isset($this->writeStreams[$key])) { - return; - } - - $callback = $this->getStreamListenerClosure($stream, $listener); - $event = $this->loop->io($stream, Ev::WRITE, $callback); - $this->writeStreams[$key] = $event; - } - - public function removeReadStream($stream) - { - $key = (int)$stream; - - if (!isset($this->readStreams[$key])) { - return; - } - - $this->readStreams[$key]->stop(); - unset($this->readStreams[$key]); - } - - public function removeWriteStream($stream) - { - $key = (int)$stream; - - if (!isset($this->writeStreams[$key])) { - return; - } - - $this->writeStreams[$key]->stop(); - unset($this->writeStreams[$key]); - } - - public function addTimer($interval, $callback) - { - $timer = new Timer($interval, $callback, false); - - $that = $this; - $timers = $this->timers; - $callback = function () use ($timer, $timers, $that) { - \call_user_func($timer->getCallback(), $timer); - - if ($timers->contains($timer)) { - $that->cancelTimer($timer); - } - }; - - $event = $this->loop->timer($timer->getInterval(), 0.0, $callback); - $this->timers->attach($timer, $event); - - return $timer; - } - - public function addPeriodicTimer($interval, $callback) - { - $timer = new Timer($interval, $callback, true); - - $callback = function () use ($timer) { - \call_user_func($timer->getCallback(), $timer); - }; - - $event = $this->loop->timer($interval, $interval, $callback); - $this->timers->attach($timer, $event); - - return $timer; - } - - public function cancelTimer(TimerInterface $timer) - { - if (!isset($this->timers[$timer])) { - return; - } - - $event = $this->timers[$timer]; - $event->stop(); - $this->timers->detach($timer); - } - - public function futureTick($listener) - { - $this->futureTickQueue->add($listener); - } - - public function run() - { - $this->running = true; - - while ($this->running) { - $this->futureTickQueue->tick(); - - $hasPendingCallbacks = !$this->futureTickQueue->isEmpty(); - $wasJustStopped = !$this->running; - $nothingLeftToDo = !$this->readStreams - && !$this->writeStreams - && !$this->timers->count() - && $this->signals->isEmpty(); - - $flags = Ev::RUN_ONCE; - if ($wasJustStopped || $hasPendingCallbacks) { - $flags |= Ev::RUN_NOWAIT; - } elseif ($nothingLeftToDo) { - break; - } - - $this->loop->run($flags); - } - } - - public function stop() - { - $this->running = false; - } - - public function __destruct() - { - /** @var TimerInterface $timer */ - foreach ($this->timers as $timer) { - $this->cancelTimer($timer); - } - - foreach ($this->readStreams as $key => $stream) { - $this->removeReadStream($key); - } - - foreach ($this->writeStreams as $key => $stream) { - $this->removeWriteStream($key); - } - } - - public function addSignal($signal, $listener) - { - $this->signals->add($signal, $listener); - - if (!isset($this->signalEvents[$signal])) { - $this->signalEvents[$signal] = $this->loop->signal($signal, function() use ($signal) { - $this->signals->call($signal); - }); - } - } - - public function removeSignal($signal, $listener) - { - $this->signals->remove($signal, $listener); - - if (isset($this->signalEvents[$signal])) { - $this->signalEvents[$signal]->stop(); - unset($this->signalEvents[$signal]); - } - } -} diff --git a/vendor/react/event-loop/src/ExtEventLoop.php b/vendor/react/event-loop/src/ExtEventLoop.php deleted file mode 100644 index 7ce500106..000000000 --- a/vendor/react/event-loop/src/ExtEventLoop.php +++ /dev/null @@ -1,275 +0,0 @@ -requireFeatures(\EventConfig::FEATURE_FDS); - } - - $this->eventBase = new EventBase($config); - $this->futureTickQueue = new FutureTickQueue(); - $this->timerEvents = new SplObjectStorage(); - $this->signals = new SignalsHandler(); - - $this->createTimerCallback(); - $this->createStreamCallback(); - } - - public function __destruct() - { - // explicitly clear all references to Event objects to prevent SEGFAULTs on Windows - foreach ($this->timerEvents as $timer) { - $this->timerEvents->detach($timer); - } - - $this->readEvents = array(); - $this->writeEvents = array(); - } - - public function addReadStream($stream, $listener) - { - $key = (int) $stream; - if (isset($this->readListeners[$key])) { - return; - } - - $event = new Event($this->eventBase, $stream, Event::PERSIST | Event::READ, $this->streamCallback); - $event->add(); - $this->readEvents[$key] = $event; - $this->readListeners[$key] = $listener; - - // ext-event does not increase refcount on stream resources for PHP 7+ - // manually keep track of stream resource to prevent premature garbage collection - if (\PHP_VERSION_ID >= 70000) { - $this->readRefs[$key] = $stream; - } - } - - public function addWriteStream($stream, $listener) - { - $key = (int) $stream; - if (isset($this->writeListeners[$key])) { - return; - } - - $event = new Event($this->eventBase, $stream, Event::PERSIST | Event::WRITE, $this->streamCallback); - $event->add(); - $this->writeEvents[$key] = $event; - $this->writeListeners[$key] = $listener; - - // ext-event does not increase refcount on stream resources for PHP 7+ - // manually keep track of stream resource to prevent premature garbage collection - if (\PHP_VERSION_ID >= 70000) { - $this->writeRefs[$key] = $stream; - } - } - - public function removeReadStream($stream) - { - $key = (int) $stream; - - if (isset($this->readEvents[$key])) { - $this->readEvents[$key]->free(); - unset( - $this->readEvents[$key], - $this->readListeners[$key], - $this->readRefs[$key] - ); - } - } - - public function removeWriteStream($stream) - { - $key = (int) $stream; - - if (isset($this->writeEvents[$key])) { - $this->writeEvents[$key]->free(); - unset( - $this->writeEvents[$key], - $this->writeListeners[$key], - $this->writeRefs[$key] - ); - } - } - - public function addTimer($interval, $callback) - { - $timer = new Timer($interval, $callback, false); - - $this->scheduleTimer($timer); - - return $timer; - } - - public function addPeriodicTimer($interval, $callback) - { - $timer = new Timer($interval, $callback, true); - - $this->scheduleTimer($timer); - - return $timer; - } - - public function cancelTimer(TimerInterface $timer) - { - if ($this->timerEvents->contains($timer)) { - $this->timerEvents[$timer]->free(); - $this->timerEvents->detach($timer); - } - } - - public function futureTick($listener) - { - $this->futureTickQueue->add($listener); - } - - public function addSignal($signal, $listener) - { - $this->signals->add($signal, $listener); - - if (!isset($this->signalEvents[$signal])) { - $this->signalEvents[$signal] = Event::signal($this->eventBase, $signal, array($this->signals, 'call')); - $this->signalEvents[$signal]->add(); - } - } - - public function removeSignal($signal, $listener) - { - $this->signals->remove($signal, $listener); - - if (isset($this->signalEvents[$signal]) && $this->signals->count($signal) === 0) { - $this->signalEvents[$signal]->free(); - unset($this->signalEvents[$signal]); - } - } - - public function run() - { - $this->running = true; - - while ($this->running) { - $this->futureTickQueue->tick(); - - $flags = EventBase::LOOP_ONCE; - if (!$this->running || !$this->futureTickQueue->isEmpty()) { - $flags |= EventBase::LOOP_NONBLOCK; - } elseif (!$this->readEvents && !$this->writeEvents && !$this->timerEvents->count() && $this->signals->isEmpty()) { - break; - } - - $this->eventBase->loop($flags); - } - } - - public function stop() - { - $this->running = false; - } - - /** - * Schedule a timer for execution. - * - * @param TimerInterface $timer - */ - private function scheduleTimer(TimerInterface $timer) - { - $flags = Event::TIMEOUT; - - if ($timer->isPeriodic()) { - $flags |= Event::PERSIST; - } - - $event = new Event($this->eventBase, -1, $flags, $this->timerCallback, $timer); - $this->timerEvents[$timer] = $event; - - $event->add($timer->getInterval()); - } - - /** - * Create a callback used as the target of timer events. - * - * A reference is kept to the callback for the lifetime of the loop - * to prevent "Cannot destroy active lambda function" fatal error from - * the event extension. - */ - private function createTimerCallback() - { - $timers = $this->timerEvents; - $this->timerCallback = function ($_, $__, $timer) use ($timers) { - \call_user_func($timer->getCallback(), $timer); - - if (!$timer->isPeriodic() && $timers->contains($timer)) { - $this->cancelTimer($timer); - } - }; - } - - /** - * Create a callback used as the target of stream events. - * - * A reference is kept to the callback for the lifetime of the loop - * to prevent "Cannot destroy active lambda function" fatal error from - * the event extension. - */ - private function createStreamCallback() - { - $read =& $this->readListeners; - $write =& $this->writeListeners; - $this->streamCallback = function ($stream, $flags) use (&$read, &$write) { - $key = (int) $stream; - - if (Event::READ === (Event::READ & $flags) && isset($read[$key])) { - \call_user_func($read[$key], $stream); - } - - if (Event::WRITE === (Event::WRITE & $flags) && isset($write[$key])) { - \call_user_func($write[$key], $stream); - } - }; - } -} diff --git a/vendor/react/event-loop/src/ExtLibevLoop.php b/vendor/react/event-loop/src/ExtLibevLoop.php deleted file mode 100644 index 2cf1ad54a..000000000 --- a/vendor/react/event-loop/src/ExtLibevLoop.php +++ /dev/null @@ -1,201 +0,0 @@ -loop = new EventLoop(); - $this->futureTickQueue = new FutureTickQueue(); - $this->timerEvents = new SplObjectStorage(); - $this->signals = new SignalsHandler(); - } - - public function addReadStream($stream, $listener) - { - if (isset($this->readEvents[(int) $stream])) { - return; - } - - $callback = function () use ($stream, $listener) { - \call_user_func($listener, $stream); - }; - - $event = new IOEvent($callback, $stream, IOEvent::READ); - $this->loop->add($event); - - $this->readEvents[(int) $stream] = $event; - } - - public function addWriteStream($stream, $listener) - { - if (isset($this->writeEvents[(int) $stream])) { - return; - } - - $callback = function () use ($stream, $listener) { - \call_user_func($listener, $stream); - }; - - $event = new IOEvent($callback, $stream, IOEvent::WRITE); - $this->loop->add($event); - - $this->writeEvents[(int) $stream] = $event; - } - - public function removeReadStream($stream) - { - $key = (int) $stream; - - if (isset($this->readEvents[$key])) { - $this->readEvents[$key]->stop(); - $this->loop->remove($this->readEvents[$key]); - unset($this->readEvents[$key]); - } - } - - public function removeWriteStream($stream) - { - $key = (int) $stream; - - if (isset($this->writeEvents[$key])) { - $this->writeEvents[$key]->stop(); - $this->loop->remove($this->writeEvents[$key]); - unset($this->writeEvents[$key]); - } - } - - public function addTimer($interval, $callback) - { - $timer = new Timer( $interval, $callback, false); - - $that = $this; - $timers = $this->timerEvents; - $callback = function () use ($timer, $timers, $that) { - \call_user_func($timer->getCallback(), $timer); - - if ($timers->contains($timer)) { - $that->cancelTimer($timer); - } - }; - - $event = new TimerEvent($callback, $timer->getInterval()); - $this->timerEvents->attach($timer, $event); - $this->loop->add($event); - - return $timer; - } - - public function addPeriodicTimer($interval, $callback) - { - $timer = new Timer($interval, $callback, true); - - $callback = function () use ($timer) { - \call_user_func($timer->getCallback(), $timer); - }; - - $event = new TimerEvent($callback, $interval, $interval); - $this->timerEvents->attach($timer, $event); - $this->loop->add($event); - - return $timer; - } - - public function cancelTimer(TimerInterface $timer) - { - if (isset($this->timerEvents[$timer])) { - $this->loop->remove($this->timerEvents[$timer]); - $this->timerEvents->detach($timer); - } - } - - public function futureTick($listener) - { - $this->futureTickQueue->add($listener); - } - - public function addSignal($signal, $listener) - { - $this->signals->add($signal, $listener); - - if (!isset($this->signalEvents[$signal])) { - $signals = $this->signals; - $this->signalEvents[$signal] = new SignalEvent(function () use ($signals, $signal) { - $signals->call($signal); - }, $signal); - $this->loop->add($this->signalEvents[$signal]); - } - } - - public function removeSignal($signal, $listener) - { - $this->signals->remove($signal, $listener); - - if (isset($this->signalEvents[$signal]) && $this->signals->count($signal) === 0) { - $this->signalEvents[$signal]->stop(); - $this->loop->remove($this->signalEvents[$signal]); - unset($this->signalEvents[$signal]); - } - } - - public function run() - { - $this->running = true; - - while ($this->running) { - $this->futureTickQueue->tick(); - - $flags = EventLoop::RUN_ONCE; - if (!$this->running || !$this->futureTickQueue->isEmpty()) { - $flags |= EventLoop::RUN_NOWAIT; - } elseif (!$this->readEvents && !$this->writeEvents && !$this->timerEvents->count() && $this->signals->isEmpty()) { - break; - } - - $this->loop->run($flags); - } - } - - public function stop() - { - $this->running = false; - } -} diff --git a/vendor/react/event-loop/src/ExtLibeventLoop.php b/vendor/react/event-loop/src/ExtLibeventLoop.php deleted file mode 100644 index 2ea7ffa5d..000000000 --- a/vendor/react/event-loop/src/ExtLibeventLoop.php +++ /dev/null @@ -1,285 +0,0 @@ -eventBase = \event_base_new(); - $this->futureTickQueue = new FutureTickQueue(); - $this->timerEvents = new SplObjectStorage(); - $this->signals = new SignalsHandler(); - - $this->createTimerCallback(); - $this->createStreamCallback(); - } - - public function addReadStream($stream, $listener) - { - $key = (int) $stream; - if (isset($this->readListeners[$key])) { - return; - } - - $event = \event_new(); - \event_set($event, $stream, \EV_PERSIST | \EV_READ, $this->streamCallback); - \event_base_set($event, $this->eventBase); - \event_add($event); - - $this->readEvents[$key] = $event; - $this->readListeners[$key] = $listener; - } - - public function addWriteStream($stream, $listener) - { - $key = (int) $stream; - if (isset($this->writeListeners[$key])) { - return; - } - - $event = \event_new(); - \event_set($event, $stream, \EV_PERSIST | \EV_WRITE, $this->streamCallback); - \event_base_set($event, $this->eventBase); - \event_add($event); - - $this->writeEvents[$key] = $event; - $this->writeListeners[$key] = $listener; - } - - public function removeReadStream($stream) - { - $key = (int) $stream; - - if (isset($this->readListeners[$key])) { - $event = $this->readEvents[$key]; - \event_del($event); - \event_free($event); - - unset( - $this->readEvents[$key], - $this->readListeners[$key] - ); - } - } - - public function removeWriteStream($stream) - { - $key = (int) $stream; - - if (isset($this->writeListeners[$key])) { - $event = $this->writeEvents[$key]; - \event_del($event); - \event_free($event); - - unset( - $this->writeEvents[$key], - $this->writeListeners[$key] - ); - } - } - - public function addTimer($interval, $callback) - { - $timer = new Timer($interval, $callback, false); - - $this->scheduleTimer($timer); - - return $timer; - } - - public function addPeriodicTimer($interval, $callback) - { - $timer = new Timer($interval, $callback, true); - - $this->scheduleTimer($timer); - - return $timer; - } - - public function cancelTimer(TimerInterface $timer) - { - if ($this->timerEvents->contains($timer)) { - $event = $this->timerEvents[$timer]; - \event_del($event); - \event_free($event); - - $this->timerEvents->detach($timer); - } - } - - public function futureTick($listener) - { - $this->futureTickQueue->add($listener); - } - - public function addSignal($signal, $listener) - { - $this->signals->add($signal, $listener); - - if (!isset($this->signalEvents[$signal])) { - $this->signalEvents[$signal] = \event_new(); - \event_set($this->signalEvents[$signal], $signal, \EV_PERSIST | \EV_SIGNAL, array($this->signals, 'call')); - \event_base_set($this->signalEvents[$signal], $this->eventBase); - \event_add($this->signalEvents[$signal]); - } - } - - public function removeSignal($signal, $listener) - { - $this->signals->remove($signal, $listener); - - if (isset($this->signalEvents[$signal]) && $this->signals->count($signal) === 0) { - \event_del($this->signalEvents[$signal]); - \event_free($this->signalEvents[$signal]); - unset($this->signalEvents[$signal]); - } - } - - public function run() - { - $this->running = true; - - while ($this->running) { - $this->futureTickQueue->tick(); - - $flags = \EVLOOP_ONCE; - if (!$this->running || !$this->futureTickQueue->isEmpty()) { - $flags |= \EVLOOP_NONBLOCK; - } elseif (!$this->readEvents && !$this->writeEvents && !$this->timerEvents->count() && $this->signals->isEmpty()) { - break; - } - - \event_base_loop($this->eventBase, $flags); - } - } - - public function stop() - { - $this->running = false; - } - - /** - * Schedule a timer for execution. - * - * @param TimerInterface $timer - */ - private function scheduleTimer(TimerInterface $timer) - { - $this->timerEvents[$timer] = $event = \event_timer_new(); - - \event_timer_set($event, $this->timerCallback, $timer); - \event_base_set($event, $this->eventBase); - \event_add($event, $timer->getInterval() * self::MICROSECONDS_PER_SECOND); - } - - /** - * Create a callback used as the target of timer events. - * - * A reference is kept to the callback for the lifetime of the loop - * to prevent "Cannot destroy active lambda function" fatal error from - * the event extension. - */ - private function createTimerCallback() - { - $that = $this; - $timers = $this->timerEvents; - $this->timerCallback = function ($_, $__, $timer) use ($timers, $that) { - \call_user_func($timer->getCallback(), $timer); - - // Timer already cancelled ... - if (!$timers->contains($timer)) { - return; - } - - // Reschedule periodic timers ... - if ($timer->isPeriodic()) { - \event_add( - $timers[$timer], - $timer->getInterval() * ExtLibeventLoop::MICROSECONDS_PER_SECOND - ); - - // Clean-up one shot timers ... - } else { - $that->cancelTimer($timer); - } - }; - } - - /** - * Create a callback used as the target of stream events. - * - * A reference is kept to the callback for the lifetime of the loop - * to prevent "Cannot destroy active lambda function" fatal error from - * the event extension. - */ - private function createStreamCallback() - { - $read =& $this->readListeners; - $write =& $this->writeListeners; - $this->streamCallback = function ($stream, $flags) use (&$read, &$write) { - $key = (int) $stream; - - if (\EV_READ === (\EV_READ & $flags) && isset($read[$key])) { - \call_user_func($read[$key], $stream); - } - - if (\EV_WRITE === (\EV_WRITE & $flags) && isset($write[$key])) { - \call_user_func($write[$key], $stream); - } - }; - } -} diff --git a/vendor/react/event-loop/src/ExtUvLoop.php b/vendor/react/event-loop/src/ExtUvLoop.php deleted file mode 100644 index 4434720df..000000000 --- a/vendor/react/event-loop/src/ExtUvLoop.php +++ /dev/null @@ -1,342 +0,0 @@ -uv = \uv_loop_new(); - $this->futureTickQueue = new FutureTickQueue(); - $this->timers = new SplObjectStorage(); - $this->streamListener = $this->createStreamListener(); - $this->signals = new SignalsHandler(); - } - - /** - * Returns the underlying ext-uv event loop. (Internal ReactPHP use only.) - * - * @internal - * - * @return resource - */ - public function getUvLoop() - { - return $this->uv; - } - - /** - * {@inheritdoc} - */ - public function addReadStream($stream, $listener) - { - if (isset($this->readStreams[(int) $stream])) { - return; - } - - $this->readStreams[(int) $stream] = $listener; - $this->addStream($stream); - } - - /** - * {@inheritdoc} - */ - public function addWriteStream($stream, $listener) - { - if (isset($this->writeStreams[(int) $stream])) { - return; - } - - $this->writeStreams[(int) $stream] = $listener; - $this->addStream($stream); - } - - /** - * {@inheritdoc} - */ - public function removeReadStream($stream) - { - if (!isset($this->streamEvents[(int) $stream])) { - return; - } - - unset($this->readStreams[(int) $stream]); - $this->removeStream($stream); - } - - /** - * {@inheritdoc} - */ - public function removeWriteStream($stream) - { - if (!isset($this->streamEvents[(int) $stream])) { - return; - } - - unset($this->writeStreams[(int) $stream]); - $this->removeStream($stream); - } - - /** - * {@inheritdoc} - */ - public function addTimer($interval, $callback) - { - $timer = new Timer($interval, $callback, false); - - $that = $this; - $timers = $this->timers; - $callback = function () use ($timer, $timers, $that) { - \call_user_func($timer->getCallback(), $timer); - - if ($timers->contains($timer)) { - $that->cancelTimer($timer); - } - }; - - $event = \uv_timer_init($this->uv); - $this->timers->attach($timer, $event); - \uv_timer_start( - $event, - $this->convertFloatSecondsToMilliseconds($interval), - 0, - $callback - ); - - return $timer; - } - - /** - * {@inheritdoc} - */ - public function addPeriodicTimer($interval, $callback) - { - $timer = new Timer($interval, $callback, true); - - $callback = function () use ($timer) { - \call_user_func($timer->getCallback(), $timer); - }; - - $interval = $this->convertFloatSecondsToMilliseconds($interval); - $event = \uv_timer_init($this->uv); - $this->timers->attach($timer, $event); - \uv_timer_start( - $event, - $interval, - (int) $interval === 0 ? 1 : $interval, - $callback - ); - - return $timer; - } - - /** - * {@inheritdoc} - */ - public function cancelTimer(TimerInterface $timer) - { - if (isset($this->timers[$timer])) { - @\uv_timer_stop($this->timers[$timer]); - $this->timers->detach($timer); - } - } - - /** - * {@inheritdoc} - */ - public function futureTick($listener) - { - $this->futureTickQueue->add($listener); - } - - public function addSignal($signal, $listener) - { - $this->signals->add($signal, $listener); - - if (!isset($this->signalEvents[$signal])) { - $signals = $this->signals; - $this->signalEvents[$signal] = \uv_signal_init($this->uv); - \uv_signal_start($this->signalEvents[$signal], function () use ($signals, $signal) { - $signals->call($signal); - }, $signal); - } - } - - public function removeSignal($signal, $listener) - { - $this->signals->remove($signal, $listener); - - if (isset($this->signalEvents[$signal]) && $this->signals->count($signal) === 0) { - \uv_signal_stop($this->signalEvents[$signal]); - unset($this->signalEvents[$signal]); - } - } - - /** - * {@inheritdoc} - */ - public function run() - { - $this->running = true; - - while ($this->running) { - $this->futureTickQueue->tick(); - - $hasPendingCallbacks = !$this->futureTickQueue->isEmpty(); - $wasJustStopped = !$this->running; - $nothingLeftToDo = !$this->readStreams - && !$this->writeStreams - && !$this->timers->count() - && $this->signals->isEmpty(); - - // Use UV::RUN_ONCE when there are only I/O events active in the loop and block until one of those triggers, - // otherwise use UV::RUN_NOWAIT. - // @link http://docs.libuv.org/en/v1.x/loop.html#c.uv_run - $flags = \UV::RUN_ONCE; - if ($wasJustStopped || $hasPendingCallbacks) { - $flags = \UV::RUN_NOWAIT; - } elseif ($nothingLeftToDo) { - break; - } - - \uv_run($this->uv, $flags); - } - } - - /** - * {@inheritdoc} - */ - public function stop() - { - $this->running = false; - } - - private function addStream($stream) - { - if (!isset($this->streamEvents[(int) $stream])) { - $this->streamEvents[(int)$stream] = \uv_poll_init_socket($this->uv, $stream); - } - - if ($this->streamEvents[(int) $stream] !== false) { - $this->pollStream($stream); - } - } - - private function removeStream($stream) - { - if (!isset($this->streamEvents[(int) $stream])) { - return; - } - - if (!isset($this->readStreams[(int) $stream]) - && !isset($this->writeStreams[(int) $stream])) { - \uv_poll_stop($this->streamEvents[(int) $stream]); - \uv_close($this->streamEvents[(int) $stream]); - unset($this->streamEvents[(int) $stream]); - return; - } - - $this->pollStream($stream); - } - - private function pollStream($stream) - { - if (!isset($this->streamEvents[(int) $stream])) { - return; - } - - $flags = 0; - if (isset($this->readStreams[(int) $stream])) { - $flags |= \UV::READABLE; - } - - if (isset($this->writeStreams[(int) $stream])) { - $flags |= \UV::WRITABLE; - } - - \uv_poll_start($this->streamEvents[(int) $stream], $flags, $this->streamListener); - } - - /** - * Create a stream listener - * - * @return callable Returns a callback - */ - private function createStreamListener() - { - $callback = function ($event, $status, $events, $stream) { - // libuv automatically stops polling on error, re-enable polling to match other loop implementations - if ($status !== 0) { - $this->pollStream($stream); - - // libuv may report no events on error, but this should still invoke stream listeners to report closed connections - // re-enable both readable and writable, correct listeners will be checked below anyway - if ($events === 0) { - $events = \UV::READABLE | \UV::WRITABLE; - } - } - - if (isset($this->readStreams[(int) $stream]) && ($events & \UV::READABLE)) { - \call_user_func($this->readStreams[(int) $stream], $stream); - } - - if (isset($this->writeStreams[(int) $stream]) && ($events & \UV::WRITABLE)) { - \call_user_func($this->writeStreams[(int) $stream], $stream); - } - }; - - return $callback; - } - - /** - * @param float $interval - * @return int - */ - private function convertFloatSecondsToMilliseconds($interval) - { - if ($interval < 0) { - return 0; - } - - $maxValue = (int) (\PHP_INT_MAX / 1000); - $intInterval = (int) $interval; - - if (($intInterval <= 0 && $interval > 1) || $intInterval >= $maxValue) { - throw new \InvalidArgumentException( - "Interval overflow, value must be lower than '{$maxValue}', but '{$interval}' passed." - ); - } - - return (int) \floor($interval * 1000); - } -} diff --git a/vendor/react/event-loop/src/Factory.php b/vendor/react/event-loop/src/Factory.php deleted file mode 100644 index 30bbfd7c8..000000000 --- a/vendor/react/event-loop/src/Factory.php +++ /dev/null @@ -1,75 +0,0 @@ -futureTick(function () use (&$hasRun) { - $hasRun = true; - }); - - $stopped =& self::$stopped; - register_shutdown_function(function () use ($loop, &$hasRun, &$stopped) { - // Don't run if we're coming from a fatal error (uncaught exception). - $error = error_get_last(); - if ((isset($error['type']) ? $error['type'] : 0) & (E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR)) { - return; - } - - if (!$hasRun && !$stopped) { - $loop->run(); - } - }); - // @codeCoverageIgnoreEnd - - return self::$instance; - } - - /** - * Internal undocumented method, behavior might change or throw in the - * future. Use with caution and at your own risk. - * - * @internal - * @return void - */ - public static function set(LoopInterface $loop) - { - self::$instance = $loop; - } - - /** - * [Advanced] Register a listener to be notified when a stream is ready to read. - * - * @param resource $stream - * @param callable $listener - * @return void - * @throws \Exception - * @see LoopInterface::addReadStream() - */ - public static function addReadStream($stream, $listener) - { - self::get()->addReadStream($stream, $listener); - } - - /** - * [Advanced] Register a listener to be notified when a stream is ready to write. - * - * @param resource $stream - * @param callable $listener - * @return void - * @throws \Exception - * @see LoopInterface::addWriteStream() - */ - public static function addWriteStream($stream, $listener) - { - self::get()->addWriteStream($stream, $listener); - } - - /** - * Remove the read event listener for the given stream. - * - * @param resource $stream - * @return void - * @see LoopInterface::removeReadStream() - */ - public static function removeReadStream($stream) - { - self::get()->removeReadStream($stream); - } - - /** - * Remove the write event listener for the given stream. - * - * @param resource $stream - * @return void - * @see LoopInterface::removeWriteStream() - */ - public static function removeWriteStream($stream) - { - self::get()->removeWriteStream($stream); - } - - /** - * Enqueue a callback to be invoked once after the given interval. - * - * @param float $interval - * @param callable $callback - * @return TimerInterface - * @see LoopInterface::addTimer() - */ - public static function addTimer($interval, $callback) - { - return self::get()->addTimer($interval, $callback); - } - - /** - * Enqueue a callback to be invoked repeatedly after the given interval. - * - * @param float $interval - * @param callable $callback - * @return TimerInterface - * @see LoopInterface::addPeriodicTimer() - */ - public static function addPeriodicTimer($interval, $callback) - { - return self::get()->addPeriodicTimer($interval, $callback); - } - - /** - * Cancel a pending timer. - * - * @param TimerInterface $timer - * @return void - * @see LoopInterface::cancelTimer() - */ - public static function cancelTimer(TimerInterface $timer) - { - return self::get()->cancelTimer($timer); - } - - /** - * Schedule a callback to be invoked on a future tick of the event loop. - * - * @param callable $listener - * @return void - * @see LoopInterface::futureTick() - */ - public static function futureTick($listener) - { - self::get()->futureTick($listener); - } - - /** - * Register a listener to be notified when a signal has been caught by this process. - * - * @param int $signal - * @param callable $listener - * @return void - * @see LoopInterface::addSignal() - */ - public static function addSignal($signal, $listener) - { - self::get()->addSignal($signal, $listener); - } - - /** - * Removes a previously added signal listener. - * - * @param int $signal - * @param callable $listener - * @return void - * @see LoopInterface::removeSignal() - */ - public static function removeSignal($signal, $listener) - { - self::get()->removeSignal($signal, $listener); - } - - /** - * Run the event loop until there are no more tasks to perform. - * - * @return void - * @see LoopInterface::run() - */ - public static function run() - { - self::get()->run(); - } - - /** - * Instruct a running event loop to stop. - * - * @return void - * @see LoopInterface::stop() - */ - public static function stop() - { - self::$stopped = true; - self::get()->stop(); - } -} diff --git a/vendor/react/event-loop/src/LoopInterface.php b/vendor/react/event-loop/src/LoopInterface.php deleted file mode 100644 index 8146757a7..000000000 --- a/vendor/react/event-loop/src/LoopInterface.php +++ /dev/null @@ -1,463 +0,0 @@ -addReadStream($stream, function ($stream) use ($name) { - * echo $name . ' said: ' . fread($stream); - * }); - * ``` - * - * See also [example #11](examples). - * - * You can invoke [`removeReadStream()`](#removereadstream) to remove the - * read event listener for this stream. - * - * The execution order of listeners when multiple streams become ready at - * the same time is not guaranteed. - * - * @param resource $stream The PHP stream resource to check. - * @param callable $listener Invoked when the stream is ready. - * @throws \Exception if the given resource type is not supported by this loop implementation - * @see self::removeReadStream() - */ - public function addReadStream($stream, $listener); - - /** - * [Advanced] Register a listener to be notified when a stream is ready to write. - * - * Note that this low-level API is considered advanced usage. - * Most use cases should probably use the higher-level - * [writable Stream API](https://github.com/reactphp/stream#writablestreaminterface) - * instead. - * - * The first parameter MUST be a valid stream resource that supports - * checking whether it is ready to write by this loop implementation. - * A single stream resource MUST NOT be added more than once. - * Instead, either call [`removeWriteStream()`](#removewritestream) first or - * react to this event with a single listener and then dispatch from this - * listener. This method MAY throw an `Exception` if the given resource type - * is not supported by this loop implementation. - * - * The listener callback function MUST be able to accept a single parameter, - * the stream resource added by this method or you MAY use a function which - * has no parameters at all. - * - * The listener callback function MUST NOT throw an `Exception`. - * The return value of the listener callback function will be ignored and has - * no effect, so for performance reasons you're recommended to not return - * any excessive data structures. - * - * If you want to access any variables within your callback function, you - * can bind arbitrary data to a callback closure like this: - * - * ```php - * $loop->addWriteStream($stream, function ($stream) use ($name) { - * fwrite($stream, 'Hello ' . $name); - * }); - * ``` - * - * See also [example #12](examples). - * - * You can invoke [`removeWriteStream()`](#removewritestream) to remove the - * write event listener for this stream. - * - * The execution order of listeners when multiple streams become ready at - * the same time is not guaranteed. - * - * Some event loop implementations are known to only trigger the listener if - * the stream *becomes* readable (edge-triggered) and may not trigger if the - * stream has already been readable from the beginning. - * This also implies that a stream may not be recognized as readable when data - * is still left in PHP's internal stream buffers. - * As such, it's recommended to use `stream_set_read_buffer($stream, 0);` - * to disable PHP's internal read buffer in this case. - * - * @param resource $stream The PHP stream resource to check. - * @param callable $listener Invoked when the stream is ready. - * @throws \Exception if the given resource type is not supported by this loop implementation - * @see self::removeWriteStream() - */ - public function addWriteStream($stream, $listener); - - /** - * Remove the read event listener for the given stream. - * - * Removing a stream from the loop that has already been removed or trying - * to remove a stream that was never added or is invalid has no effect. - * - * @param resource $stream The PHP stream resource. - */ - public function removeReadStream($stream); - - /** - * Remove the write event listener for the given stream. - * - * Removing a stream from the loop that has already been removed or trying - * to remove a stream that was never added or is invalid has no effect. - * - * @param resource $stream The PHP stream resource. - */ - public function removeWriteStream($stream); - - /** - * Enqueue a callback to be invoked once after the given interval. - * - * The timer callback function MUST be able to accept a single parameter, - * the timer instance as also returned by this method or you MAY use a - * function which has no parameters at all. - * - * The timer callback function MUST NOT throw an `Exception`. - * The return value of the timer callback function will be ignored and has - * no effect, so for performance reasons you're recommended to not return - * any excessive data structures. - * - * Unlike [`addPeriodicTimer()`](#addperiodictimer), this method will ensure - * the callback will be invoked only once after the given interval. - * You can invoke [`cancelTimer`](#canceltimer) to cancel a pending timer. - * - * ```php - * $loop->addTimer(0.8, function () { - * echo 'world!' . PHP_EOL; - * }); - * - * $loop->addTimer(0.3, function () { - * echo 'hello '; - * }); - * ``` - * - * See also [example #1](examples). - * - * If you want to access any variables within your callback function, you - * can bind arbitrary data to a callback closure like this: - * - * ```php - * function hello($name, LoopInterface $loop) - * { - * $loop->addTimer(1.0, function () use ($name) { - * echo "hello $name\n"; - * }); - * } - * - * hello('Tester', $loop); - * ``` - * - * This interface does not enforce any particular timer resolution, so - * special care may have to be taken if you rely on very high precision with - * millisecond accuracy or below. Event loop implementations SHOULD work on - * a best effort basis and SHOULD provide at least millisecond accuracy - * unless otherwise noted. Many existing event loop implementations are - * known to provide microsecond accuracy, but it's generally not recommended - * to rely on this high precision. - * - * Similarly, the execution order of timers scheduled to execute at the - * same time (within its possible accuracy) is not guaranteed. - * - * This interface suggests that event loop implementations SHOULD use a - * monotonic time source if available. Given that a monotonic time source is - * only available as of PHP 7.3 by default, event loop implementations MAY - * fall back to using wall-clock time. - * While this does not affect many common use cases, this is an important - * distinction for programs that rely on a high time precision or on systems - * that are subject to discontinuous time adjustments (time jumps). - * This means that if you schedule a timer to trigger in 30s and then adjust - * your system time forward by 20s, the timer SHOULD still trigger in 30s. - * See also [event loop implementations](#loop-implementations) for more details. - * - * @param int|float $interval The number of seconds to wait before execution. - * @param callable $callback The callback to invoke. - * - * @return TimerInterface - */ - public function addTimer($interval, $callback); - - /** - * Enqueue a callback to be invoked repeatedly after the given interval. - * - * The timer callback function MUST be able to accept a single parameter, - * the timer instance as also returned by this method or you MAY use a - * function which has no parameters at all. - * - * The timer callback function MUST NOT throw an `Exception`. - * The return value of the timer callback function will be ignored and has - * no effect, so for performance reasons you're recommended to not return - * any excessive data structures. - * - * Unlike [`addTimer()`](#addtimer), this method will ensure the the - * callback will be invoked infinitely after the given interval or until you - * invoke [`cancelTimer`](#canceltimer). - * - * ```php - * $timer = $loop->addPeriodicTimer(0.1, function () { - * echo 'tick!' . PHP_EOL; - * }); - * - * $loop->addTimer(1.0, function () use ($loop, $timer) { - * $loop->cancelTimer($timer); - * echo 'Done' . PHP_EOL; - * }); - * ``` - * - * See also [example #2](examples). - * - * If you want to limit the number of executions, you can bind - * arbitrary data to a callback closure like this: - * - * ```php - * function hello($name, LoopInterface $loop) - * { - * $n = 3; - * $loop->addPeriodicTimer(1.0, function ($timer) use ($name, $loop, &$n) { - * if ($n > 0) { - * --$n; - * echo "hello $name\n"; - * } else { - * $loop->cancelTimer($timer); - * } - * }); - * } - * - * hello('Tester', $loop); - * ``` - * - * This interface does not enforce any particular timer resolution, so - * special care may have to be taken if you rely on very high precision with - * millisecond accuracy or below. Event loop implementations SHOULD work on - * a best effort basis and SHOULD provide at least millisecond accuracy - * unless otherwise noted. Many existing event loop implementations are - * known to provide microsecond accuracy, but it's generally not recommended - * to rely on this high precision. - * - * Similarly, the execution order of timers scheduled to execute at the - * same time (within its possible accuracy) is not guaranteed. - * - * This interface suggests that event loop implementations SHOULD use a - * monotonic time source if available. Given that a monotonic time source is - * only available as of PHP 7.3 by default, event loop implementations MAY - * fall back to using wall-clock time. - * While this does not affect many common use cases, this is an important - * distinction for programs that rely on a high time precision or on systems - * that are subject to discontinuous time adjustments (time jumps). - * This means that if you schedule a timer to trigger in 30s and then adjust - * your system time forward by 20s, the timer SHOULD still trigger in 30s. - * See also [event loop implementations](#loop-implementations) for more details. - * - * Additionally, periodic timers may be subject to timer drift due to - * re-scheduling after each invocation. As such, it's generally not - * recommended to rely on this for high precision intervals with millisecond - * accuracy or below. - * - * @param int|float $interval The number of seconds to wait before execution. - * @param callable $callback The callback to invoke. - * - * @return TimerInterface - */ - public function addPeriodicTimer($interval, $callback); - - /** - * Cancel a pending timer. - * - * See also [`addPeriodicTimer()`](#addperiodictimer) and [example #2](examples). - * - * Calling this method on a timer instance that has not been added to this - * loop instance or on a timer that has already been cancelled has no effect. - * - * @param TimerInterface $timer The timer to cancel. - * - * @return void - */ - public function cancelTimer(TimerInterface $timer); - - /** - * Schedule a callback to be invoked on a future tick of the event loop. - * - * This works very much similar to timers with an interval of zero seconds, - * but does not require the overhead of scheduling a timer queue. - * - * The tick callback function MUST be able to accept zero parameters. - * - * The tick callback function MUST NOT throw an `Exception`. - * The return value of the tick callback function will be ignored and has - * no effect, so for performance reasons you're recommended to not return - * any excessive data structures. - * - * If you want to access any variables within your callback function, you - * can bind arbitrary data to a callback closure like this: - * - * ```php - * function hello($name, LoopInterface $loop) - * { - * $loop->futureTick(function () use ($name) { - * echo "hello $name\n"; - * }); - * } - * - * hello('Tester', $loop); - * ``` - * - * Unlike timers, tick callbacks are guaranteed to be executed in the order - * they are enqueued. - * Also, once a callback is enqueued, there's no way to cancel this operation. - * - * This is often used to break down bigger tasks into smaller steps (a form - * of cooperative multitasking). - * - * ```php - * $loop->futureTick(function () { - * echo 'b'; - * }); - * $loop->futureTick(function () { - * echo 'c'; - * }); - * echo 'a'; - * ``` - * - * See also [example #3](examples). - * - * @param callable $listener The callback to invoke. - * - * @return void - */ - public function futureTick($listener); - - /** - * Register a listener to be notified when a signal has been caught by this process. - * - * This is useful to catch user interrupt signals or shutdown signals from - * tools like `supervisor` or `systemd`. - * - * The listener callback function MUST be able to accept a single parameter, - * the signal added by this method or you MAY use a function which - * has no parameters at all. - * - * The listener callback function MUST NOT throw an `Exception`. - * The return value of the listener callback function will be ignored and has - * no effect, so for performance reasons you're recommended to not return - * any excessive data structures. - * - * ```php - * $loop->addSignal(SIGINT, function (int $signal) { - * echo 'Caught user interrupt signal' . PHP_EOL; - * }); - * ``` - * - * See also [example #4](examples). - * - * Signaling is only available on Unix-like platform, Windows isn't - * supported due to operating system limitations. - * This method may throw a `BadMethodCallException` if signals aren't - * supported on this platform, for example when required extensions are - * missing. - * - * **Note: A listener can only be added once to the same signal, any - * attempts to add it more then once will be ignored.** - * - * @param int $signal - * @param callable $listener - * - * @throws \BadMethodCallException when signals aren't supported on this - * platform, for example when required extensions are missing. - * - * @return void - */ - public function addSignal($signal, $listener); - - /** - * Removes a previously added signal listener. - * - * ```php - * $loop->removeSignal(SIGINT, $listener); - * ``` - * - * Any attempts to remove listeners that aren't registered will be ignored. - * - * @param int $signal - * @param callable $listener - * - * @return void - */ - public function removeSignal($signal, $listener); - - /** - * Run the event loop until there are no more tasks to perform. - * - * For many applications, this method is the only directly visible - * invocation on the event loop. - * As a rule of thumb, it is usally recommended to attach everything to the - * same loop instance and then run the loop once at the bottom end of the - * application. - * - * ```php - * $loop->run(); - * ``` - * - * This method will keep the loop running until there are no more tasks - * to perform. In other words: This method will block until the last - * timer, stream and/or signal has been removed. - * - * Likewise, it is imperative to ensure the application actually invokes - * this method once. Adding listeners to the loop and missing to actually - * run it will result in the application exiting without actually waiting - * for any of the attached listeners. - * - * This method MUST NOT be called while the loop is already running. - * This method MAY be called more than once after it has explicity been - * [`stop()`ped](#stop) or after it automatically stopped because it - * previously did no longer have anything to do. - * - * @return void - */ - public function run(); - - /** - * Instruct a running event loop to stop. - * - * This method is considered advanced usage and should be used with care. - * As a rule of thumb, it is usually recommended to let the loop stop - * only automatically when it no longer has anything to do. - * - * This method can be used to explicitly instruct the event loop to stop: - * - * ```php - * $loop->addTimer(3.0, function () use ($loop) { - * $loop->stop(); - * }); - * ``` - * - * Calling this method on a loop instance that is not currently running or - * on a loop instance that has already been stopped has no effect. - * - * @return void - */ - public function stop(); -} diff --git a/vendor/react/event-loop/src/SignalsHandler.php b/vendor/react/event-loop/src/SignalsHandler.php deleted file mode 100644 index 10d125df8..000000000 --- a/vendor/react/event-loop/src/SignalsHandler.php +++ /dev/null @@ -1,63 +0,0 @@ -signals[$signal])) { - $this->signals[$signal] = array(); - } - - if (\in_array($listener, $this->signals[$signal])) { - return; - } - - $this->signals[$signal][] = $listener; - } - - public function remove($signal, $listener) - { - if (!isset($this->signals[$signal])) { - return; - } - - $index = \array_search($listener, $this->signals[$signal], true); - unset($this->signals[$signal][$index]); - - if (isset($this->signals[$signal]) && \count($this->signals[$signal]) === 0) { - unset($this->signals[$signal]); - } - } - - public function call($signal) - { - if (!isset($this->signals[$signal])) { - return; - } - - foreach ($this->signals[$signal] as $listener) { - \call_user_func($listener, $signal); - } - } - - public function count($signal) - { - if (!isset($this->signals[$signal])) { - return 0; - } - - return \count($this->signals[$signal]); - } - - public function isEmpty() - { - return !$this->signals; - } -} diff --git a/vendor/react/event-loop/src/StreamSelectLoop.php b/vendor/react/event-loop/src/StreamSelectLoop.php deleted file mode 100644 index b89d80005..000000000 --- a/vendor/react/event-loop/src/StreamSelectLoop.php +++ /dev/null @@ -1,308 +0,0 @@ -futureTickQueue = new FutureTickQueue(); - $this->timers = new Timers(); - $this->pcntl = \function_exists('pcntl_signal') && \function_exists('pcntl_signal_dispatch'); - $this->pcntlPoll = $this->pcntl && !\function_exists('pcntl_async_signals'); - $this->signals = new SignalsHandler(); - - // prefer async signals if available (PHP 7.1+) or fall back to dispatching on each tick - if ($this->pcntl && !$this->pcntlPoll) { - \pcntl_async_signals(true); - } - } - - public function addReadStream($stream, $listener) - { - $key = (int) $stream; - - if (!isset($this->readStreams[$key])) { - $this->readStreams[$key] = $stream; - $this->readListeners[$key] = $listener; - } - } - - public function addWriteStream($stream, $listener) - { - $key = (int) $stream; - - if (!isset($this->writeStreams[$key])) { - $this->writeStreams[$key] = $stream; - $this->writeListeners[$key] = $listener; - } - } - - public function removeReadStream($stream) - { - $key = (int) $stream; - - unset( - $this->readStreams[$key], - $this->readListeners[$key] - ); - } - - public function removeWriteStream($stream) - { - $key = (int) $stream; - - unset( - $this->writeStreams[$key], - $this->writeListeners[$key] - ); - } - - public function addTimer($interval, $callback) - { - $timer = new Timer($interval, $callback, false); - - $this->timers->add($timer); - - return $timer; - } - - public function addPeriodicTimer($interval, $callback) - { - $timer = new Timer($interval, $callback, true); - - $this->timers->add($timer); - - return $timer; - } - - public function cancelTimer(TimerInterface $timer) - { - $this->timers->cancel($timer); - } - - public function futureTick($listener) - { - $this->futureTickQueue->add($listener); - } - - public function addSignal($signal, $listener) - { - if ($this->pcntl === false) { - throw new \BadMethodCallException('Event loop feature "signals" isn\'t supported by the "StreamSelectLoop"'); - } - - $first = $this->signals->count($signal) === 0; - $this->signals->add($signal, $listener); - - if ($first) { - \pcntl_signal($signal, array($this->signals, 'call')); - } - } - - public function removeSignal($signal, $listener) - { - if (!$this->signals->count($signal)) { - return; - } - - $this->signals->remove($signal, $listener); - - if ($this->signals->count($signal) === 0) { - \pcntl_signal($signal, \SIG_DFL); - } - } - - public function run() - { - $this->running = true; - - while ($this->running) { - $this->futureTickQueue->tick(); - - $this->timers->tick(); - - // Future-tick queue has pending callbacks ... - if (!$this->running || !$this->futureTickQueue->isEmpty()) { - $timeout = 0; - - // There is a pending timer, only block until it is due ... - } elseif ($scheduledAt = $this->timers->getFirst()) { - $timeout = $scheduledAt - $this->timers->getTime(); - if ($timeout < 0) { - $timeout = 0; - } else { - // Convert float seconds to int microseconds. - // Ensure we do not exceed maximum integer size, which may - // cause the loop to tick once every ~35min on 32bit systems. - $timeout *= self::MICROSECONDS_PER_SECOND; - $timeout = $timeout > \PHP_INT_MAX ? \PHP_INT_MAX : (int)$timeout; - } - - // The only possible event is stream or signal activity, so wait forever ... - } elseif ($this->readStreams || $this->writeStreams || !$this->signals->isEmpty()) { - $timeout = null; - - // There's nothing left to do ... - } else { - break; - } - - $this->waitForStreamActivity($timeout); - } - } - - public function stop() - { - $this->running = false; - } - - /** - * Wait/check for stream activity, or until the next timer is due. - * - * @param integer|null $timeout Activity timeout in microseconds, or null to wait forever. - */ - private function waitForStreamActivity($timeout) - { - $read = $this->readStreams; - $write = $this->writeStreams; - - $available = $this->streamSelect($read, $write, $timeout); - if ($this->pcntlPoll) { - \pcntl_signal_dispatch(); - } - if (false === $available) { - // if a system call has been interrupted, - // we cannot rely on it's outcome - return; - } - - foreach ($read as $stream) { - $key = (int) $stream; - - if (isset($this->readListeners[$key])) { - \call_user_func($this->readListeners[$key], $stream); - } - } - - foreach ($write as $stream) { - $key = (int) $stream; - - if (isset($this->writeListeners[$key])) { - \call_user_func($this->writeListeners[$key], $stream); - } - } - } - - /** - * Emulate a stream_select() implementation that does not break when passed - * empty stream arrays. - * - * @param array $read An array of read streams to select upon. - * @param array $write An array of write streams to select upon. - * @param int|null $timeout Activity timeout in microseconds, or null to wait forever. - * - * @return int|false The total number of streams that are ready for read/write. - * Can return false if stream_select() is interrupted by a signal. - */ - private function streamSelect(array &$read, array &$write, $timeout) - { - if ($read || $write) { - // We do not usually use or expose the `exceptfds` parameter passed to the underlying `select`. - // However, Windows does not report failed connection attempts in `writefds` passed to `select` like most other platforms. - // Instead, it uses `writefds` only for successful connection attempts and `exceptfds` for failed connection attempts. - // We work around this by adding all sockets that look like a pending connection attempt to `exceptfds` automatically on Windows and merge it back later. - // This ensures the public API matches other loop implementations across all platforms (see also test suite or rather test matrix). - // Lacking better APIs, every write-only socket that has not yet read any data is assumed to be in a pending connection attempt state. - // @link https://docs.microsoft.com/de-de/windows/win32/api/winsock2/nf-winsock2-select - $except = null; - if (\DIRECTORY_SEPARATOR === '\\') { - $except = array(); - foreach ($write as $key => $socket) { - if (!isset($read[$key]) && @\ftell($socket) === 0) { - $except[$key] = $socket; - } - } - } - - // suppress warnings that occur, when stream_select is interrupted by a signal - $ret = @\stream_select($read, $write, $except, $timeout === null ? null : 0, $timeout); - - if ($except) { - $write = \array_merge($write, $except); - } - return $ret; - } - - if ($timeout > 0) { - \usleep($timeout); - } elseif ($timeout === null) { - // wait forever (we only reach this if we're only awaiting signals) - // this may be interrupted and return earlier when a signal is received - \sleep(PHP_INT_MAX); - } - - return 0; - } -} diff --git a/vendor/react/event-loop/src/Tick/FutureTickQueue.php b/vendor/react/event-loop/src/Tick/FutureTickQueue.php deleted file mode 100644 index efabcbc54..000000000 --- a/vendor/react/event-loop/src/Tick/FutureTickQueue.php +++ /dev/null @@ -1,60 +0,0 @@ -queue = new SplQueue(); - } - - /** - * Add a callback to be invoked on a future tick of the event loop. - * - * Callbacks are guaranteed to be executed in the order they are enqueued. - * - * @param callable $listener The callback to invoke. - */ - public function add($listener) - { - $this->queue->enqueue($listener); - } - - /** - * Flush the callback queue. - */ - public function tick() - { - // Only invoke as many callbacks as were on the queue when tick() was called. - $count = $this->queue->count(); - - while ($count--) { - \call_user_func( - $this->queue->dequeue() - ); - } - } - - /** - * Check if the next tick queue is empty. - * - * @return boolean - */ - public function isEmpty() - { - return $this->queue->isEmpty(); - } -} diff --git a/vendor/react/event-loop/src/Timer/Timer.php b/vendor/react/event-loop/src/Timer/Timer.php deleted file mode 100644 index da3602a31..000000000 --- a/vendor/react/event-loop/src/Timer/Timer.php +++ /dev/null @@ -1,55 +0,0 @@ -interval = (float) $interval; - $this->callback = $callback; - $this->periodic = (bool) $periodic; - } - - public function getInterval() - { - return $this->interval; - } - - public function getCallback() - { - return $this->callback; - } - - public function isPeriodic() - { - return $this->periodic; - } -} diff --git a/vendor/react/event-loop/src/Timer/Timers.php b/vendor/react/event-loop/src/Timer/Timers.php deleted file mode 100644 index 70adc1324..000000000 --- a/vendor/react/event-loop/src/Timer/Timers.php +++ /dev/null @@ -1,107 +0,0 @@ -useHighResolution = \function_exists('hrtime'); - } - - public function updateTime() - { - return $this->time = $this->useHighResolution ? \hrtime(true) * 1e-9 : \microtime(true); - } - - public function getTime() - { - return $this->time ?: $this->updateTime(); - } - - public function add(TimerInterface $timer) - { - $id = \spl_object_hash($timer); - $this->timers[$id] = $timer; - $this->schedule[$id] = $timer->getInterval() + $this->updateTime(); - $this->sorted = false; - } - - public function contains(TimerInterface $timer) - { - return isset($this->timers[\spl_object_hash($timer)]); - } - - public function cancel(TimerInterface $timer) - { - $id = \spl_object_hash($timer); - unset($this->timers[$id], $this->schedule[$id]); - } - - public function getFirst() - { - // ensure timers are sorted to simply accessing next (first) one - if (!$this->sorted) { - $this->sorted = true; - \asort($this->schedule); - } - - return \reset($this->schedule); - } - - public function isEmpty() - { - return \count($this->timers) === 0; - } - - public function tick() - { - // ensure timers are sorted so we can execute in order - if (!$this->sorted) { - $this->sorted = true; - \asort($this->schedule); - } - - $time = $this->updateTime(); - - foreach ($this->schedule as $id => $scheduled) { - // schedule is ordered, so loop until first timer that is not scheduled for execution now - if ($scheduled >= $time) { - break; - } - - // skip any timers that are removed while we process the current schedule - if (!isset($this->schedule[$id]) || $this->schedule[$id] !== $scheduled) { - continue; - } - - $timer = $this->timers[$id]; - \call_user_func($timer->getCallback(), $timer); - - // re-schedule if this is a periodic timer and it has not been cancelled explicitly already - if ($timer->isPeriodic() && isset($this->timers[$id])) { - $this->schedule[$id] = $timer->getInterval() + $time; - $this->sorted = false; - } else { - unset($this->timers[$id], $this->schedule[$id]); - } - } - } -} diff --git a/vendor/react/event-loop/src/TimerInterface.php b/vendor/react/event-loop/src/TimerInterface.php deleted file mode 100644 index cdcf7732d..000000000 --- a/vendor/react/event-loop/src/TimerInterface.php +++ /dev/null @@ -1,27 +0,0 @@ - '127.0.0.1', - * 'tcp' => array( - * 'bindto' => '192.168.10.1:0' - * ), - * 'tls' => array( - * 'verify_peer' => false, - * 'verify_peer_name' => false - * ) - * )); - * - * $browser = new React\Http\Browser($connector); - * ``` - * - * This class takes an optional `LoopInterface|null $loop` parameter that can be used to - * pass the event loop instance to use for this object. You can use a `null` value - * here in order to use the [default loop](https://github.com/reactphp/event-loop#loop). - * This value SHOULD NOT be given unless you're sure you want to explicitly use a - * given event loop instance. - * - * @param null|ConnectorInterface|LoopInterface $connector - * @param null|LoopInterface|ConnectorInterface $loop - * @throws \InvalidArgumentException for invalid arguments - */ - public function __construct($connector = null, $loop = null) - { - // swap arguments for legacy constructor signature - if (($connector instanceof LoopInterface || $connector === null) && ($loop instanceof ConnectorInterface || $loop === null)) { - $swap = $loop; - $loop = $connector; - $connector = $swap; - } - - if (($connector !== null && !$connector instanceof ConnectorInterface) || ($loop !== null && !$loop instanceof LoopInterface)) { - throw new \InvalidArgumentException('Expected "?ConnectorInterface $connector" and "?LoopInterface $loop" arguments'); - } - - $loop = $loop ?: Loop::get(); - $this->transaction = new Transaction( - Sender::createFromLoop($loop, $connector), - $loop - ); - } - - /** - * Sends an HTTP GET request - * - * ```php - * $browser->get($url)->then(function (Psr\Http\Message\ResponseInterface $response) { - * var_dump((string)$response->getBody()); - * }, function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * See also [GET request client example](../examples/01-client-get-request.php). - * - * @param string $url URL for the request. - * @param array $headers - * @return PromiseInterface - */ - public function get($url, array $headers = array()) - { - return $this->requestMayBeStreaming('GET', $url, $headers); - } - - /** - * Sends an HTTP POST request - * - * ```php - * $browser->post( - * $url, - * [ - * 'Content-Type' => 'application/json' - * ], - * json_encode($data) - * )->then(function (Psr\Http\Message\ResponseInterface $response) { - * var_dump(json_decode((string)$response->getBody())); - * }, function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * See also [POST JSON client example](../examples/04-client-post-json.php). - * - * This method is also commonly used to submit HTML form data: - * - * ```php - * $data = [ - * 'user' => 'Alice', - * 'password' => 'secret' - * ]; - * - * $browser->post( - * $url, - * [ - * 'Content-Type' => 'application/x-www-form-urlencoded' - * ], - * http_build_query($data) - * ); - * ``` - * - * This method will automatically add a matching `Content-Length` request - * header if the outgoing request body is a `string`. If you're using a - * streaming request body (`ReadableStreamInterface`), it will default to - * using `Transfer-Encoding: chunked` or you have to explicitly pass in a - * matching `Content-Length` request header like so: - * - * ```php - * $body = new React\Stream\ThroughStream(); - * Loop::addTimer(1.0, function () use ($body) { - * $body->end("hello world"); - * }); - * - * $browser->post($url, array('Content-Length' => '11'), $body); - * ``` - * - * @param string $url URL for the request. - * @param array $headers - * @param string|ReadableStreamInterface $body - * @return PromiseInterface - */ - public function post($url, array $headers = array(), $body = '') - { - return $this->requestMayBeStreaming('POST', $url, $headers, $body); - } - - /** - * Sends an HTTP HEAD request - * - * ```php - * $browser->head($url)->then(function (Psr\Http\Message\ResponseInterface $response) { - * var_dump($response->getHeaders()); - * }, function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * @param string $url URL for the request. - * @param array $headers - * @return PromiseInterface - */ - public function head($url, array $headers = array()) - { - return $this->requestMayBeStreaming('HEAD', $url, $headers); - } - - /** - * Sends an HTTP PATCH request - * - * ```php - * $browser->patch( - * $url, - * [ - * 'Content-Type' => 'application/json' - * ], - * json_encode($data) - * )->then(function (Psr\Http\Message\ResponseInterface $response) { - * var_dump(json_decode((string)$response->getBody())); - * }, function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * This method will automatically add a matching `Content-Length` request - * header if the outgoing request body is a `string`. If you're using a - * streaming request body (`ReadableStreamInterface`), it will default to - * using `Transfer-Encoding: chunked` or you have to explicitly pass in a - * matching `Content-Length` request header like so: - * - * ```php - * $body = new React\Stream\ThroughStream(); - * Loop::addTimer(1.0, function () use ($body) { - * $body->end("hello world"); - * }); - * - * $browser->patch($url, array('Content-Length' => '11'), $body); - * ``` - * - * @param string $url URL for the request. - * @param array $headers - * @param string|ReadableStreamInterface $body - * @return PromiseInterface - */ - public function patch($url, array $headers = array(), $body = '') - { - return $this->requestMayBeStreaming('PATCH', $url , $headers, $body); - } - - /** - * Sends an HTTP PUT request - * - * ```php - * $browser->put( - * $url, - * [ - * 'Content-Type' => 'text/xml' - * ], - * $xml->asXML() - * )->then(function (Psr\Http\Message\ResponseInterface $response) { - * var_dump((string)$response->getBody()); - * }, function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * See also [PUT XML client example](../examples/05-client-put-xml.php). - * - * This method will automatically add a matching `Content-Length` request - * header if the outgoing request body is a `string`. If you're using a - * streaming request body (`ReadableStreamInterface`), it will default to - * using `Transfer-Encoding: chunked` or you have to explicitly pass in a - * matching `Content-Length` request header like so: - * - * ```php - * $body = new React\Stream\ThroughStream(); - * Loop::addTimer(1.0, function () use ($body) { - * $body->end("hello world"); - * }); - * - * $browser->put($url, array('Content-Length' => '11'), $body); - * ``` - * - * @param string $url URL for the request. - * @param array $headers - * @param string|ReadableStreamInterface $body - * @return PromiseInterface - */ - public function put($url, array $headers = array(), $body = '') - { - return $this->requestMayBeStreaming('PUT', $url, $headers, $body); - } - - /** - * Sends an HTTP DELETE request - * - * ```php - * $browser->delete($url)->then(function (Psr\Http\Message\ResponseInterface $response) { - * var_dump((string)$response->getBody()); - * }, function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * @param string $url URL for the request. - * @param array $headers - * @param string|ReadableStreamInterface $body - * @return PromiseInterface - */ - public function delete($url, array $headers = array(), $body = '') - { - return $this->requestMayBeStreaming('DELETE', $url, $headers, $body); - } - - /** - * Sends an arbitrary HTTP request. - * - * The preferred way to send an HTTP request is by using the above - * [request methods](#request-methods), for example the [`get()`](#get) - * method to send an HTTP `GET` request. - * - * As an alternative, if you want to use a custom HTTP request method, you - * can use this method: - * - * ```php - * $browser->request('OPTIONS', $url)->then(function (Psr\Http\Message\ResponseInterface $response) { - * var_dump((string)$response->getBody()); - * }, function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * This method will automatically add a matching `Content-Length` request - * header if the size of the outgoing request body is known and non-empty. - * For an empty request body, if will only include a `Content-Length: 0` - * request header if the request method usually expects a request body (only - * applies to `POST`, `PUT` and `PATCH`). - * - * If you're using a streaming request body (`ReadableStreamInterface`), it - * will default to using `Transfer-Encoding: chunked` or you have to - * explicitly pass in a matching `Content-Length` request header like so: - * - * ```php - * $body = new React\Stream\ThroughStream(); - * Loop::addTimer(1.0, function () use ($body) { - * $body->end("hello world"); - * }); - * - * $browser->request('POST', $url, array('Content-Length' => '11'), $body); - * ``` - * - * @param string $method HTTP request method, e.g. GET/HEAD/POST etc. - * @param string $url URL for the request - * @param array $headers Additional request headers - * @param string|ReadableStreamInterface $body HTTP request body contents - * @return PromiseInterface - */ - public function request($method, $url, array $headers = array(), $body = '') - { - return $this->withOptions(array('streaming' => false))->requestMayBeStreaming($method, $url, $headers, $body); - } - - /** - * Sends an arbitrary HTTP request and receives a streaming response without buffering the response body. - * - * The preferred way to send an HTTP request is by using the above - * [request methods](#request-methods), for example the [`get()`](#get) - * method to send an HTTP `GET` request. Each of these methods will buffer - * the whole response body in memory by default. This is easy to get started - * and works reasonably well for smaller responses. - * - * In some situations, it's a better idea to use a streaming approach, where - * only small chunks have to be kept in memory. You can use this method to - * send an arbitrary HTTP request and receive a streaming response. It uses - * the same HTTP message API, but does not buffer the response body in - * memory. It only processes the response body in small chunks as data is - * received and forwards this data through [ReactPHP's Stream API](https://github.com/reactphp/stream). - * This works for (any number of) responses of arbitrary sizes. - * - * ```php - * $browser->requestStreaming('GET', $url)->then(function (Psr\Http\Message\ResponseInterface $response) { - * $body = $response->getBody(); - * assert($body instanceof Psr\Http\Message\StreamInterface); - * assert($body instanceof React\Stream\ReadableStreamInterface); - * - * $body->on('data', function ($chunk) { - * echo $chunk; - * }); - * - * $body->on('error', function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * - * $body->on('close', function () { - * echo '[DONE]' . PHP_EOL; - * }); - * }, function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * See also [`ReadableStreamInterface`](https://github.com/reactphp/stream#readablestreaminterface) - * and the [streaming response](#streaming-response) for more details, - * examples and possible use-cases. - * - * This method will automatically add a matching `Content-Length` request - * header if the size of the outgoing request body is known and non-empty. - * For an empty request body, if will only include a `Content-Length: 0` - * request header if the request method usually expects a request body (only - * applies to `POST`, `PUT` and `PATCH`). - * - * If you're using a streaming request body (`ReadableStreamInterface`), it - * will default to using `Transfer-Encoding: chunked` or you have to - * explicitly pass in a matching `Content-Length` request header like so: - * - * ```php - * $body = new React\Stream\ThroughStream(); - * Loop::addTimer(1.0, function () use ($body) { - * $body->end("hello world"); - * }); - * - * $browser->requestStreaming('POST', $url, array('Content-Length' => '11'), $body); - * ``` - * - * @param string $method HTTP request method, e.g. GET/HEAD/POST etc. - * @param string $url URL for the request - * @param array $headers Additional request headers - * @param string|ReadableStreamInterface $body HTTP request body contents - * @return PromiseInterface - */ - public function requestStreaming($method, $url, $headers = array(), $body = '') - { - return $this->withOptions(array('streaming' => true))->requestMayBeStreaming($method, $url, $headers, $body); - } - - /** - * Changes the maximum timeout used for waiting for pending requests. - * - * You can pass in the number of seconds to use as a new timeout value: - * - * ```php - * $browser = $browser->withTimeout(10.0); - * ``` - * - * You can pass in a bool `false` to disable any timeouts. In this case, - * requests can stay pending forever: - * - * ```php - * $browser = $browser->withTimeout(false); - * ``` - * - * You can pass in a bool `true` to re-enable default timeout handling. This - * will respects PHP's `default_socket_timeout` setting (default 60s): - * - * ```php - * $browser = $browser->withTimeout(true); - * ``` - * - * See also [timeouts](#timeouts) for more details about timeout handling. - * - * Notice that the [`Browser`](#browser) is an immutable object, i.e. this - * method actually returns a *new* [`Browser`](#browser) instance with the - * given timeout value applied. - * - * @param bool|number $timeout - * @return self - */ - public function withTimeout($timeout) - { - if ($timeout === true) { - $timeout = null; - } elseif ($timeout === false) { - $timeout = -1; - } elseif ($timeout < 0) { - $timeout = 0; - } - - return $this->withOptions(array( - 'timeout' => $timeout, - )); - } - - /** - * Changes how HTTP redirects will be followed. - * - * You can pass in the maximum number of redirects to follow: - * - * ```php - * $browser = $browser->withFollowRedirects(5); - * ``` - * - * The request will automatically be rejected when the number of redirects - * is exceeded. You can pass in a `0` to reject the request for any - * redirects encountered: - * - * ```php - * $browser = $browser->withFollowRedirects(0); - * - * $browser->get($url)->then(function (Psr\Http\Message\ResponseInterface $response) { - * // only non-redirected responses will now end up here - * var_dump($response->getHeaders()); - * }, function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * You can pass in a bool `false` to disable following any redirects. In - * this case, requests will resolve with the redirection response instead - * of following the `Location` response header: - * - * ```php - * $browser = $browser->withFollowRedirects(false); - * - * $browser->get($url)->then(function (Psr\Http\Message\ResponseInterface $response) { - * // any redirects will now end up here - * var_dump($response->getHeaderLine('Location')); - * }, function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * You can pass in a bool `true` to re-enable default redirect handling. - * This defaults to following a maximum of 10 redirects: - * - * ```php - * $browser = $browser->withFollowRedirects(true); - * ``` - * - * See also [redirects](#redirects) for more details about redirect handling. - * - * Notice that the [`Browser`](#browser) is an immutable object, i.e. this - * method actually returns a *new* [`Browser`](#browser) instance with the - * given redirect setting applied. - * - * @param bool|int $followRedirects - * @return self - */ - public function withFollowRedirects($followRedirects) - { - return $this->withOptions(array( - 'followRedirects' => $followRedirects !== false, - 'maxRedirects' => \is_bool($followRedirects) ? null : $followRedirects - )); - } - - /** - * Changes whether non-successful HTTP response status codes (4xx and 5xx) will be rejected. - * - * You can pass in a bool `false` to disable rejecting incoming responses - * that use a 4xx or 5xx response status code. In this case, requests will - * resolve with the response message indicating an error condition: - * - * ```php - * $browser = $browser->withRejectErrorResponse(false); - * - * $browser->get($url)->then(function (Psr\Http\Message\ResponseInterface $response) { - * // any HTTP response will now end up here - * var_dump($response->getStatusCode(), $response->getReasonPhrase()); - * }, function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * You can pass in a bool `true` to re-enable default status code handling. - * This defaults to rejecting any response status codes in the 4xx or 5xx - * range: - * - * ```php - * $browser = $browser->withRejectErrorResponse(true); - * - * $browser->get($url)->then(function (Psr\Http\Message\ResponseInterface $response) { - * // any successful HTTP response will now end up here - * var_dump($response->getStatusCode(), $response->getReasonPhrase()); - * }, function (Exception $e) { - * if ($e instanceof React\Http\Message\ResponseException) { - * // any HTTP response error message will now end up here - * $response = $e->getResponse(); - * var_dump($response->getStatusCode(), $response->getReasonPhrase()); - * } else { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * } - * }); - * ``` - * - * Notice that the [`Browser`](#browser) is an immutable object, i.e. this - * method actually returns a *new* [`Browser`](#browser) instance with the - * given setting applied. - * - * @param bool $obeySuccessCode - * @return self - */ - public function withRejectErrorResponse($obeySuccessCode) - { - return $this->withOptions(array( - 'obeySuccessCode' => $obeySuccessCode, - )); - } - - /** - * Changes the base URL used to resolve relative URLs to. - * - * If you configure a base URL, any requests to relative URLs will be - * processed by first resolving this relative to the given absolute base - * URL. This supports resolving relative path references (like `../` etc.). - * This is particularly useful for (RESTful) API calls where all endpoints - * (URLs) are located under a common base URL. - * - * ```php - * $browser = $browser->withBase('http://api.example.com/v3/'); - * - * // will request http://api.example.com/v3/users - * $browser->get('users')->then(…); - * ``` - * - * You can pass in a `null` base URL to return a new instance that does not - * use a base URL: - * - * ```php - * $browser = $browser->withBase(null); - * ``` - * - * Accordingly, any requests using relative URLs to a browser that does not - * use a base URL can not be completed and will be rejected without sending - * a request. - * - * This method will throw an `InvalidArgumentException` if the given - * `$baseUrl` argument is not a valid URL. - * - * Notice that the [`Browser`](#browser) is an immutable object, i.e. the `withBase()` method - * actually returns a *new* [`Browser`](#browser) instance with the given base URL applied. - * - * @param string|null $baseUrl absolute base URL - * @return self - * @throws InvalidArgumentException if the given $baseUrl is not a valid absolute URL - * @see self::withoutBase() - */ - public function withBase($baseUrl) - { - $browser = clone $this; - if ($baseUrl === null) { - $browser->baseUrl = null; - return $browser; - } - - $browser->baseUrl = new Uri($baseUrl); - if (!\in_array($browser->baseUrl->getScheme(), array('http', 'https')) || $browser->baseUrl->getHost() === '') { - throw new \InvalidArgumentException('Base URL must be absolute'); - } - - return $browser; - } - - /** - * Changes the HTTP protocol version that will be used for all subsequent requests. - * - * All the above [request methods](#request-methods) default to sending - * requests as HTTP/1.1. This is the preferred HTTP protocol version which - * also provides decent backwards-compatibility with legacy HTTP/1.0 - * servers. As such, there should rarely be a need to explicitly change this - * protocol version. - * - * If you want to explicitly use the legacy HTTP/1.0 protocol version, you - * can use this method: - * - * ```php - * $browser = $browser->withProtocolVersion('1.0'); - * - * $browser->get($url)->then(…); - * ``` - * - * Notice that the [`Browser`](#browser) is an immutable object, i.e. this - * method actually returns a *new* [`Browser`](#browser) instance with the - * new protocol version applied. - * - * @param string $protocolVersion HTTP protocol version to use, must be one of "1.1" or "1.0" - * @return self - * @throws InvalidArgumentException - */ - public function withProtocolVersion($protocolVersion) - { - if (!\in_array($protocolVersion, array('1.0', '1.1'), true)) { - throw new InvalidArgumentException('Invalid HTTP protocol version, must be one of "1.1" or "1.0"'); - } - - $browser = clone $this; - $browser->protocolVersion = (string) $protocolVersion; - - return $browser; - } - - /** - * Changes the maximum size for buffering a response body. - * - * The preferred way to send an HTTP request is by using the above - * [request methods](#request-methods), for example the [`get()`](#get) - * method to send an HTTP `GET` request. Each of these methods will buffer - * the whole response body in memory by default. This is easy to get started - * and works reasonably well for smaller responses. - * - * By default, the response body buffer will be limited to 16 MiB. If the - * response body exceeds this maximum size, the request will be rejected. - * - * You can pass in the maximum number of bytes to buffer: - * - * ```php - * $browser = $browser->withResponseBuffer(1024 * 1024); - * - * $browser->get($url)->then(function (Psr\Http\Message\ResponseInterface $response) { - * // response body will not exceed 1 MiB - * var_dump($response->getHeaders(), (string) $response->getBody()); - * }, function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * Note that the response body buffer has to be kept in memory for each - * pending request until its transfer is completed and it will only be freed - * after a pending request is fulfilled. As such, increasing this maximum - * buffer size to allow larger response bodies is usually not recommended. - * Instead, you can use the [`requestStreaming()` method](#requeststreaming) - * to receive responses with arbitrary sizes without buffering. Accordingly, - * this maximum buffer size setting has no effect on streaming responses. - * - * Notice that the [`Browser`](#browser) is an immutable object, i.e. this - * method actually returns a *new* [`Browser`](#browser) instance with the - * given setting applied. - * - * @param int $maximumSize - * @return self - * @see self::requestStreaming() - */ - public function withResponseBuffer($maximumSize) - { - return $this->withOptions(array( - 'maximumSize' => $maximumSize - )); - } - - /** - * Changes the [options](#options) to use: - * - * The [`Browser`](#browser) class exposes several options for the handling of - * HTTP transactions. These options resemble some of PHP's - * [HTTP context options](http://php.net/manual/en/context.http.php) and - * can be controlled via the following API (and their defaults): - * - * ```php - * // deprecated - * $newBrowser = $browser->withOptions(array( - * 'timeout' => null, // see withTimeout() instead - * 'followRedirects' => true, // see withFollowRedirects() instead - * 'maxRedirects' => 10, // see withFollowRedirects() instead - * 'obeySuccessCode' => true, // see withRejectErrorResponse() instead - * 'streaming' => false, // deprecated, see requestStreaming() instead - * )); - * ``` - * - * See also [timeouts](#timeouts), [redirects](#redirects) and - * [streaming](#streaming) for more details. - * - * Notice that the [`Browser`](#browser) is an immutable object, i.e. this - * method actually returns a *new* [`Browser`](#browser) instance with the - * options applied. - * - * @param array $options - * @return self - * @see self::withTimeout() - * @see self::withFollowRedirects() - * @see self::withRejectErrorResponse() - */ - private function withOptions(array $options) - { - $browser = clone $this; - $browser->transaction = $this->transaction->withOptions($options); - - return $browser; - } - - /** - * @param string $method - * @param string $url - * @param array $headers - * @param string|ReadableStreamInterface $body - * @return PromiseInterface - */ - private function requestMayBeStreaming($method, $url, array $headers = array(), $body = '') - { - if ($this->baseUrl !== null) { - // ensure we're actually below the base URL - $url = Uri::resolve($this->baseUrl, $url); - } - - if ($body instanceof ReadableStreamInterface) { - $body = new ReadableBodyStream($body); - } - - return $this->transaction->send( - new Request($method, $url, $headers, $body, $this->protocolVersion) - ); - } -} diff --git a/vendor/react/http/src/Client/Client.php b/vendor/react/http/src/Client/Client.php deleted file mode 100644 index 7a97349c1..000000000 --- a/vendor/react/http/src/Client/Client.php +++ /dev/null @@ -1,31 +0,0 @@ -connector = $connector; - } - - public function request($method, $url, array $headers = array(), $protocolVersion = '1.0') - { - $requestData = new RequestData($method, $url, $headers, $protocolVersion); - - return new Request($this->connector, $requestData); - } -} diff --git a/vendor/react/http/src/Client/Request.php b/vendor/react/http/src/Client/Request.php deleted file mode 100644 index 51e033133..000000000 --- a/vendor/react/http/src/Client/Request.php +++ /dev/null @@ -1,237 +0,0 @@ -connector = $connector; - $this->requestData = $requestData; - } - - public function isWritable() - { - return self::STATE_END > $this->state && !$this->ended; - } - - private function writeHead() - { - $this->state = self::STATE_WRITING_HEAD; - - $requestData = $this->requestData; - $streamRef = &$this->stream; - $stateRef = &$this->state; - $pendingWrites = &$this->pendingWrites; - $that = $this; - - $promise = $this->connect(); - $promise->then( - function (ConnectionInterface $stream) use ($requestData, &$streamRef, &$stateRef, &$pendingWrites, $that) { - $streamRef = $stream; - - $stream->on('drain', array($that, 'handleDrain')); - $stream->on('data', array($that, 'handleData')); - $stream->on('end', array($that, 'handleEnd')); - $stream->on('error', array($that, 'handleError')); - $stream->on('close', array($that, 'handleClose')); - - $headers = (string) $requestData; - - $more = $stream->write($headers . $pendingWrites); - - $stateRef = Request::STATE_HEAD_WRITTEN; - - // clear pending writes if non-empty - if ($pendingWrites !== '') { - $pendingWrites = ''; - - if ($more) { - $that->emit('drain'); - } - } - }, - array($this, 'closeError') - ); - - $this->on('close', function() use ($promise) { - $promise->cancel(); - }); - } - - public function write($data) - { - if (!$this->isWritable()) { - return false; - } - - // write directly to connection stream if already available - if (self::STATE_HEAD_WRITTEN <= $this->state) { - return $this->stream->write($data); - } - - // otherwise buffer and try to establish connection - $this->pendingWrites .= $data; - if (self::STATE_WRITING_HEAD > $this->state) { - $this->writeHead(); - } - - return false; - } - - public function end($data = null) - { - if (!$this->isWritable()) { - return; - } - - if (null !== $data) { - $this->write($data); - } else if (self::STATE_WRITING_HEAD > $this->state) { - $this->writeHead(); - } - - $this->ended = true; - } - - /** @internal */ - public function handleDrain() - { - $this->emit('drain'); - } - - /** @internal */ - public function handleData($data) - { - $this->buffer .= $data; - - // buffer until double CRLF (or double LF for compatibility with legacy servers) - if (false !== strpos($this->buffer, "\r\n\r\n") || false !== strpos($this->buffer, "\n\n")) { - try { - $response = gPsr\parse_response($this->buffer); - $bodyChunk = (string) $response->getBody(); - } catch (\InvalidArgumentException $exception) { - $this->emit('error', array($exception)); - } - - $this->buffer = null; - - $this->stream->removeListener('drain', array($this, 'handleDrain')); - $this->stream->removeListener('data', array($this, 'handleData')); - $this->stream->removeListener('end', array($this, 'handleEnd')); - $this->stream->removeListener('error', array($this, 'handleError')); - $this->stream->removeListener('close', array($this, 'handleClose')); - - if (!isset($response)) { - return; - } - - $this->stream->on('close', array($this, 'handleClose')); - - $this->emit('response', array($response, $this->stream)); - - $this->stream->emit('data', array($bodyChunk)); - } - } - - /** @internal */ - public function handleEnd() - { - $this->closeError(new \RuntimeException( - "Connection ended before receiving response" - )); - } - - /** @internal */ - public function handleError(\Exception $error) - { - $this->closeError(new \RuntimeException( - "An error occurred in the underlying stream", - 0, - $error - )); - } - - /** @internal */ - public function handleClose() - { - $this->close(); - } - - /** @internal */ - public function closeError(\Exception $error) - { - if (self::STATE_END <= $this->state) { - return; - } - $this->emit('error', array($error)); - $this->close(); - } - - public function close() - { - if (self::STATE_END <= $this->state) { - return; - } - - $this->state = self::STATE_END; - $this->pendingWrites = ''; - - if ($this->stream) { - $this->stream->close(); - } - - $this->emit('close'); - $this->removeAllListeners(); - } - - protected function connect() - { - $scheme = $this->requestData->getScheme(); - if ($scheme !== 'https' && $scheme !== 'http') { - return Promise\reject( - new \InvalidArgumentException('Invalid request URL given') - ); - } - - $host = $this->requestData->getHost(); - $port = $this->requestData->getPort(); - - if ($scheme === 'https') { - $host = 'tls://' . $host; - } - - return $this->connector - ->connect($host . ':' . $port); - } -} diff --git a/vendor/react/http/src/Client/RequestData.php b/vendor/react/http/src/Client/RequestData.php deleted file mode 100644 index a5908a085..000000000 --- a/vendor/react/http/src/Client/RequestData.php +++ /dev/null @@ -1,128 +0,0 @@ -method = $method; - $this->url = $url; - $this->headers = $headers; - $this->protocolVersion = $protocolVersion; - } - - private function mergeDefaultheaders(array $headers) - { - $port = ($this->getDefaultPort() === $this->getPort()) ? '' : ":{$this->getPort()}"; - $connectionHeaders = ('1.1' === $this->protocolVersion) ? array('Connection' => 'close') : array(); - $authHeaders = $this->getAuthHeaders(); - - $defaults = array_merge( - array( - 'Host' => $this->getHost().$port, - 'User-Agent' => 'ReactPHP/1', - ), - $connectionHeaders, - $authHeaders - ); - - // remove all defaults that already exist in $headers - $lower = array_change_key_case($headers, CASE_LOWER); - foreach ($defaults as $key => $_) { - if (isset($lower[strtolower($key)])) { - unset($defaults[$key]); - } - } - - return array_merge($defaults, $headers); - } - - public function getScheme() - { - return parse_url($this->url, PHP_URL_SCHEME); - } - - public function getHost() - { - return parse_url($this->url, PHP_URL_HOST); - } - - public function getPort() - { - return (int) parse_url($this->url, PHP_URL_PORT) ?: $this->getDefaultPort(); - } - - public function getDefaultPort() - { - return ('https' === $this->getScheme()) ? 443 : 80; - } - - public function getPath() - { - $path = parse_url($this->url, PHP_URL_PATH); - $queryString = parse_url($this->url, PHP_URL_QUERY); - - // assume "/" path by default, but allow "OPTIONS *" - if ($path === null) { - $path = ($this->method === 'OPTIONS' && $queryString === null) ? '*': '/'; - } - if ($queryString !== null) { - $path .= '?' . $queryString; - } - - return $path; - } - - public function setProtocolVersion($version) - { - $this->protocolVersion = $version; - } - - public function __toString() - { - $headers = $this->mergeDefaultheaders($this->headers); - - $data = ''; - $data .= "{$this->method} {$this->getPath()} HTTP/{$this->protocolVersion}\r\n"; - foreach ($headers as $name => $values) { - foreach ((array)$values as $value) { - $data .= "$name: $value\r\n"; - } - } - $data .= "\r\n"; - - return $data; - } - - private function getUrlUserPass() - { - $components = parse_url($this->url); - - if (isset($components['user'])) { - return array( - 'user' => $components['user'], - 'pass' => isset($components['pass']) ? $components['pass'] : null, - ); - } - } - - private function getAuthHeaders() - { - if (null !== $auth = $this->getUrlUserPass()) { - return array( - 'Authorization' => 'Basic ' . base64_encode($auth['user'].':'.$auth['pass']), - ); - } - - return array(); - } -} diff --git a/vendor/react/http/src/HttpServer.php b/vendor/react/http/src/HttpServer.php deleted file mode 100644 index f23347332..000000000 --- a/vendor/react/http/src/HttpServer.php +++ /dev/null @@ -1,351 +0,0 @@ - 'text/plain' - * ), - * "Hello World!\n" - * ); - * }); - * ``` - * - * Each incoming HTTP request message is always represented by the - * [PSR-7 `ServerRequestInterface`](https://www.php-fig.org/psr/psr-7/#321-psrhttpmessageserverrequestinterface), - * see also following [request](#server-request) chapter for more details. - * - * Each outgoing HTTP response message is always represented by the - * [PSR-7 `ResponseInterface`](https://www.php-fig.org/psr/psr-7/#33-psrhttpmessageresponseinterface), - * see also following [response](#server-response) chapter for more details. - * - * This class takes an optional `LoopInterface|null $loop` parameter that can be used to - * pass the event loop instance to use for this object. You can use a `null` value - * here in order to use the [default loop](https://github.com/reactphp/event-loop#loop). - * This value SHOULD NOT be given unless you're sure you want to explicitly use a - * given event loop instance. - * - * In order to start listening for any incoming connections, the `HttpServer` needs - * to be attached to an instance of - * [`React\Socket\ServerInterface`](https://github.com/reactphp/socket#serverinterface) - * through the [`listen()`](#listen) method as described in the following - * chapter. In its most simple form, you can attach this to a - * [`React\Socket\SocketServer`](https://github.com/reactphp/socket#socketserver) - * in order to start a plaintext HTTP server like this: - * - * ```php - * $http = new React\Http\HttpServer($handler); - * - * $socket = new React\Socket\SocketServer('0.0.0.0:8080'); - * $http->listen($socket); - * ``` - * - * See also the [`listen()`](#listen) method and - * [hello world server example](../examples/51-server-hello-world.php) - * for more details. - * - * By default, the `HttpServer` buffers and parses the complete incoming HTTP - * request in memory. It will invoke the given request handler function when the - * complete request headers and request body has been received. This means the - * [request](#server-request) object passed to your request handler function will be - * fully compatible with PSR-7 (http-message). This provides sane defaults for - * 80% of the use cases and is the recommended way to use this library unless - * you're sure you know what you're doing. - * - * On the other hand, buffering complete HTTP requests in memory until they can - * be processed by your request handler function means that this class has to - * employ a number of limits to avoid consuming too much memory. In order to - * take the more advanced configuration out your hand, it respects setting from - * your [`php.ini`](https://www.php.net/manual/en/ini.core.php) to apply its - * default settings. This is a list of PHP settings this class respects with - * their respective default values: - * - * ``` - * memory_limit 128M - * post_max_size 8M // capped at 64K - * - * enable_post_data_reading 1 - * max_input_nesting_level 64 - * max_input_vars 1000 - * - * file_uploads 1 - * upload_max_filesize 2M - * max_file_uploads 20 - * ``` - * - * In particular, the `post_max_size` setting limits how much memory a single - * HTTP request is allowed to consume while buffering its request body. This - * needs to be limited because the server can process a large number of requests - * concurrently, so the server may potentially consume a large amount of memory - * otherwise. To support higher concurrency by default, this value is capped - * at `64K`. If you assign a higher value, it will only allow `64K` by default. - * If a request exceeds this limit, its request body will be ignored and it will - * be processed like a request with no request body at all. See below for - * explicit configuration to override this setting. - * - * By default, this class will try to avoid consuming more than half of your - * `memory_limit` for buffering multiple concurrent HTTP requests. As such, with - * the above default settings of `128M` max, it will try to consume no more than - * `64M` for buffering multiple concurrent HTTP requests. As a consequence, it - * will limit the concurrency to `1024` HTTP requests with the above defaults. - * - * It is imperative that you assign reasonable values to your PHP ini settings. - * It is usually recommended to not support buffering incoming HTTP requests - * with a large HTTP request body (e.g. large file uploads). If you want to - * increase this buffer size, you will have to also increase the total memory - * limit to allow for more concurrent requests (set `memory_limit 512M` or more) - * or explicitly limit concurrency. - * - * In order to override the above buffering defaults, you can configure the - * `HttpServer` explicitly. You can use the - * [`LimitConcurrentRequestsMiddleware`](#limitconcurrentrequestsmiddleware) and - * [`RequestBodyBufferMiddleware`](#requestbodybuffermiddleware) (see below) - * to explicitly configure the total number of requests that can be handled at - * once like this: - * - * ```php - * $http = new React\Http\HttpServer( - * new React\Http\Middleware\StreamingRequestMiddleware(), - * new React\Http\Middleware\LimitConcurrentRequestsMiddleware(100), // 100 concurrent buffering handlers - * new React\Http\Middleware\RequestBodyBufferMiddleware(2 * 1024 * 1024), // 2 MiB per request - * new React\Http\Middleware\RequestBodyParserMiddleware(), - * $handler - * )); - * ``` - * - * In this example, we allow processing up to 100 concurrent requests at once - * and each request can buffer up to `2M`. This means you may have to keep a - * maximum of `200M` of memory for incoming request body buffers. Accordingly, - * you need to adjust the `memory_limit` ini setting to allow for these buffers - * plus your actual application logic memory requirements (think `512M` or more). - * - * > Internally, this class automatically assigns these middleware handlers - * automatically when no [`StreamingRequestMiddleware`](#streamingrequestmiddleware) - * is given. Accordingly, you can use this example to override all default - * settings to implement custom limits. - * - * As an alternative to buffering the complete request body in memory, you can - * also use a streaming approach where only small chunks of data have to be kept - * in memory: - * - * ```php - * $http = new React\Http\HttpServer( - * new React\Http\Middleware\StreamingRequestMiddleware(), - * $handler - * ); - * ``` - * - * In this case, it will invoke the request handler function once the HTTP - * request headers have been received, i.e. before receiving the potentially - * much larger HTTP request body. This means the [request](#server-request) passed to - * your request handler function may not be fully compatible with PSR-7. This is - * specifically designed to help with more advanced use cases where you want to - * have full control over consuming the incoming HTTP request body and - * concurrency settings. See also [streaming incoming request](#streaming-incoming-request) - * below for more details. - * - * > Changelog v1.5.0: This class has been renamed to `HttpServer` from the - * previous `Server` class in order to avoid any ambiguities. - * The previous name has been deprecated and should not be used anymore. - */ -final class HttpServer extends EventEmitter -{ - /** - * The maximum buffer size used for each request. - * - * This needs to be limited because the server can process a large number of - * requests concurrently, so the server may potentially consume a large - * amount of memory otherwise. - * - * See `RequestBodyBufferMiddleware` to override this setting. - * - * @internal - */ - const MAXIMUM_BUFFER_SIZE = 65536; // 64 KiB - - /** - * @var StreamingServer - */ - private $streamingServer; - - /** - * Creates an HTTP server that invokes the given callback for each incoming HTTP request - * - * In order to process any connections, the server needs to be attached to an - * instance of `React\Socket\ServerInterface` which emits underlying streaming - * connections in order to then parse incoming data as HTTP. - * See also [listen()](#listen) for more details. - * - * @param callable|LoopInterface $requestHandlerOrLoop - * @param callable[] ...$requestHandler - * @see self::listen() - */ - public function __construct($requestHandlerOrLoop) - { - $requestHandlers = \func_get_args(); - if (reset($requestHandlers) instanceof LoopInterface) { - $loop = \array_shift($requestHandlers); - } else { - $loop = Loop::get(); - } - - $requestHandlersCount = \count($requestHandlers); - if ($requestHandlersCount === 0 || \count(\array_filter($requestHandlers, 'is_callable')) < $requestHandlersCount) { - throw new \InvalidArgumentException('Invalid request handler given'); - } - - $streaming = false; - foreach ((array) $requestHandlers as $handler) { - if ($handler instanceof StreamingRequestMiddleware) { - $streaming = true; - break; - } - } - - $middleware = array(); - if (!$streaming) { - $maxSize = $this->getMaxRequestSize(); - $concurrency = $this->getConcurrentRequestsLimit(\ini_get('memory_limit'), $maxSize); - if ($concurrency !== null) { - $middleware[] = new LimitConcurrentRequestsMiddleware($concurrency); - } - $middleware[] = new RequestBodyBufferMiddleware($maxSize); - // Checking for an empty string because that is what a boolean - // false is returned as by ini_get depending on the PHP version. - // @link http://php.net/manual/en/ini.core.php#ini.enable-post-data-reading - // @link http://php.net/manual/en/function.ini-get.php#refsect1-function.ini-get-notes - // @link https://3v4l.org/qJtsa - $enablePostDataReading = \ini_get('enable_post_data_reading'); - if ($enablePostDataReading !== '') { - $middleware[] = new RequestBodyParserMiddleware(); - } - } - - $middleware = \array_merge($middleware, $requestHandlers); - - /** - * Filter out any configuration middleware, no need to run requests through something that isn't - * doing anything with the request. - */ - $middleware = \array_filter($middleware, function ($handler) { - return !($handler instanceof StreamingRequestMiddleware); - }); - - $this->streamingServer = new StreamingServer($loop, new MiddlewareRunner($middleware)); - - $that = $this; - $this->streamingServer->on('error', function ($error) use ($that) { - $that->emit('error', array($error)); - }); - } - - /** - * Starts listening for HTTP requests on the given socket server instance - * - * The given [`React\Socket\ServerInterface`](https://github.com/reactphp/socket#serverinterface) - * is responsible for emitting the underlying streaming connections. This - * HTTP server needs to be attached to it in order to process any - * connections and pase incoming streaming data as incoming HTTP request - * messages. In its most common form, you can attach this to a - * [`React\Socket\SocketServer`](https://github.com/reactphp/socket#socketserver) - * in order to start a plaintext HTTP server like this: - * - * ```php - * $http = new React\Http\HttpServer($handler); - * - * $socket = new React\Socket\SocketServer('0.0.0.0:8080'); - * $http->listen($socket); - * ``` - * - * See also [hello world server example](../examples/51-server-hello-world.php) - * for more details. - * - * This example will start listening for HTTP requests on the alternative - * HTTP port `8080` on all interfaces (publicly). As an alternative, it is - * very common to use a reverse proxy and let this HTTP server listen on the - * localhost (loopback) interface only by using the listen address - * `127.0.0.1:8080` instead. This way, you host your application(s) on the - * default HTTP port `80` and only route specific requests to this HTTP - * server. - * - * Likewise, it's usually recommended to use a reverse proxy setup to accept - * secure HTTPS requests on default HTTPS port `443` (TLS termination) and - * only route plaintext requests to this HTTP server. As an alternative, you - * can also accept secure HTTPS requests with this HTTP server by attaching - * this to a [`React\Socket\SocketServer`](https://github.com/reactphp/socket#socketserver) - * using a secure TLS listen address, a certificate file and optional - * `passphrase` like this: - * - * ```php - * $http = new React\Http\HttpServer($handler); - * - * $socket = new React\Socket\SocketServer('tls://0.0.0.0:8443', array( - * 'tls' => array( - * 'local_cert' => __DIR__ . '/localhost.pem' - * ) - * )); - * $http->listen($socket); - * ``` - * - * See also [hello world HTTPS example](../examples/61-server-hello-world-https.php) - * for more details. - * - * @param ServerInterface $socket - */ - public function listen(ServerInterface $socket) - { - $this->streamingServer->listen($socket); - } - - /** - * @param string $memory_limit - * @param string $post_max_size - * @return ?int - */ - private function getConcurrentRequestsLimit($memory_limit, $post_max_size) - { - if ($memory_limit == -1) { - return null; - } - - $availableMemory = IniUtil::iniSizeToBytes($memory_limit) / 2; - $concurrentRequests = (int) \ceil($availableMemory / IniUtil::iniSizeToBytes($post_max_size)); - - return $concurrentRequests; - } - - /** - * @param ?string $post_max_size - * @return int - */ - private function getMaxRequestSize($post_max_size = null) - { - $maxSize = IniUtil::iniSizeToBytes($post_max_size === null ? \ini_get('post_max_size') : $post_max_size); - - return ($maxSize === 0 || $maxSize >= self::MAXIMUM_BUFFER_SIZE) ? self::MAXIMUM_BUFFER_SIZE : $maxSize; - } -} diff --git a/vendor/react/http/src/Io/BufferedBody.php b/vendor/react/http/src/Io/BufferedBody.php deleted file mode 100644 index 4a4d83933..000000000 --- a/vendor/react/http/src/Io/BufferedBody.php +++ /dev/null @@ -1,179 +0,0 @@ -buffer = $buffer; - } - - public function __toString() - { - if ($this->closed) { - return ''; - } - - $this->seek(0); - - return $this->getContents(); - } - - public function close() - { - $this->buffer = ''; - $this->position = 0; - $this->closed = true; - } - - public function detach() - { - $this->close(); - - return null; - } - - public function getSize() - { - return $this->closed ? null : \strlen($this->buffer); - } - - public function tell() - { - if ($this->closed) { - throw new \RuntimeException('Unable to tell position of closed stream'); - } - - return $this->position; - } - - public function eof() - { - return $this->position >= \strlen($this->buffer); - } - - public function isSeekable() - { - return !$this->closed; - } - - public function seek($offset, $whence = \SEEK_SET) - { - if ($this->closed) { - throw new \RuntimeException('Unable to seek on closed stream'); - } - - $old = $this->position; - - if ($whence === \SEEK_SET) { - $this->position = $offset; - } elseif ($whence === \SEEK_CUR) { - $this->position += $offset; - } elseif ($whence === \SEEK_END) { - $this->position = \strlen($this->buffer) + $offset; - } else { - throw new \InvalidArgumentException('Invalid seek mode given'); - } - - if (!\is_int($this->position) || $this->position < 0) { - $this->position = $old; - throw new \RuntimeException('Unable to seek to position'); - } - } - - public function rewind() - { - $this->seek(0); - } - - public function isWritable() - { - return !$this->closed; - } - - public function write($string) - { - if ($this->closed) { - throw new \RuntimeException('Unable to write to closed stream'); - } - - if ($string === '') { - return 0; - } - - if ($this->position > 0 && !isset($this->buffer[$this->position - 1])) { - $this->buffer = \str_pad($this->buffer, $this->position, "\0"); - } - - $len = \strlen($string); - $this->buffer = \substr($this->buffer, 0, $this->position) . $string . \substr($this->buffer, $this->position + $len); - $this->position += $len; - - return $len; - } - - public function isReadable() - { - return !$this->closed; - } - - public function read($length) - { - if ($this->closed) { - throw new \RuntimeException('Unable to read from closed stream'); - } - - if ($length < 1) { - throw new \InvalidArgumentException('Invalid read length given'); - } - - if ($this->position + $length > \strlen($this->buffer)) { - $length = \strlen($this->buffer) - $this->position; - } - - if (!isset($this->buffer[$this->position])) { - return ''; - } - - $pos = $this->position; - $this->position += $length; - - return \substr($this->buffer, $pos, $length); - } - - public function getContents() - { - if ($this->closed) { - throw new \RuntimeException('Unable to read from closed stream'); - } - - if (!isset($this->buffer[$this->position])) { - return ''; - } - - $pos = $this->position; - $this->position = \strlen($this->buffer); - - return \substr($this->buffer, $pos); - } - - public function getMetadata($key = null) - { - return $key === null ? array() : null; - } -} diff --git a/vendor/react/http/src/Io/ChunkedDecoder.php b/vendor/react/http/src/Io/ChunkedDecoder.php deleted file mode 100644 index 2f58f42b1..000000000 --- a/vendor/react/http/src/Io/ChunkedDecoder.php +++ /dev/null @@ -1,175 +0,0 @@ -input = $input; - - $this->input->on('data', array($this, 'handleData')); - $this->input->on('end', array($this, 'handleEnd')); - $this->input->on('error', array($this, 'handleError')); - $this->input->on('close', array($this, 'close')); - } - - public function isReadable() - { - return !$this->closed && $this->input->isReadable(); - } - - public function pause() - { - $this->input->pause(); - } - - public function resume() - { - $this->input->resume(); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - Util::pipe($this, $dest, $options); - - return $dest; - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->buffer = ''; - - $this->closed = true; - - $this->input->close(); - - $this->emit('close'); - $this->removeAllListeners(); - } - - /** @internal */ - public function handleEnd() - { - if (!$this->closed) { - $this->handleError(new Exception('Unexpected end event')); - } - } - - /** @internal */ - public function handleError(Exception $e) - { - $this->emit('error', array($e)); - $this->close(); - } - - /** @internal */ - public function handleData($data) - { - $this->buffer .= $data; - - while ($this->buffer !== '') { - if (!$this->headerCompleted) { - $positionCrlf = \strpos($this->buffer, static::CRLF); - - if ($positionCrlf === false) { - // Header shouldn't be bigger than 1024 bytes - if (isset($this->buffer[static::MAX_CHUNK_HEADER_SIZE])) { - $this->handleError(new Exception('Chunk header size inclusive extension bigger than' . static::MAX_CHUNK_HEADER_SIZE. ' bytes')); - } - return; - } - - $header = \strtolower((string)\substr($this->buffer, 0, $positionCrlf)); - $hexValue = $header; - - if (\strpos($header, ';') !== false) { - $array = \explode(';', $header); - $hexValue = $array[0]; - } - - if ($hexValue !== '') { - $hexValue = \ltrim(\trim($hexValue), "0"); - if ($hexValue === '') { - $hexValue = "0"; - } - } - - $this->chunkSize = @\hexdec($hexValue); - if (!\is_int($this->chunkSize) || \dechex($this->chunkSize) !== $hexValue) { - $this->handleError(new Exception($hexValue . ' is not a valid hexadecimal number')); - return; - } - - $this->buffer = (string)\substr($this->buffer, $positionCrlf + 2); - $this->headerCompleted = true; - if ($this->buffer === '') { - return; - } - } - - $chunk = (string)\substr($this->buffer, 0, $this->chunkSize - $this->transferredSize); - - if ($chunk !== '') { - $this->transferredSize += \strlen($chunk); - $this->emit('data', array($chunk)); - $this->buffer = (string)\substr($this->buffer, \strlen($chunk)); - } - - $positionCrlf = \strpos($this->buffer, static::CRLF); - - if ($positionCrlf === 0) { - if ($this->chunkSize === 0) { - $this->emit('end'); - $this->close(); - return; - } - $this->chunkSize = 0; - $this->headerCompleted = false; - $this->transferredSize = 0; - $this->buffer = (string)\substr($this->buffer, 2); - } elseif ($this->chunkSize === 0) { - // end chunk received, skip all trailer data - $this->buffer = (string)\substr($this->buffer, $positionCrlf); - } - - if ($positionCrlf !== 0 && $this->chunkSize !== 0 && $this->chunkSize === $this->transferredSize && \strlen($this->buffer) > 2) { - // the first 2 characters are not CRLF, send error event - $this->handleError(new Exception('Chunk does not end with a CRLF')); - return; - } - - if ($positionCrlf !== 0 && \strlen($this->buffer) < 2) { - // No CRLF found, wait for additional data which could be a CRLF - return; - } - } - } -} diff --git a/vendor/react/http/src/Io/ChunkedEncoder.php b/vendor/react/http/src/Io/ChunkedEncoder.php deleted file mode 100644 index c84ef54fe..000000000 --- a/vendor/react/http/src/Io/ChunkedEncoder.php +++ /dev/null @@ -1,92 +0,0 @@ -input = $input; - - $this->input->on('data', array($this, 'handleData')); - $this->input->on('end', array($this, 'handleEnd')); - $this->input->on('error', array($this, 'handleError')); - $this->input->on('close', array($this, 'close')); - } - - public function isReadable() - { - return !$this->closed && $this->input->isReadable(); - } - - public function pause() - { - $this->input->pause(); - } - - public function resume() - { - $this->input->resume(); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - return Util::pipe($this, $dest, $options); - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->closed = true; - $this->input->close(); - - $this->emit('close'); - $this->removeAllListeners(); - } - - /** @internal */ - public function handleData($data) - { - if ($data !== '') { - $this->emit('data', array( - \dechex(\strlen($data)) . "\r\n" . $data . "\r\n" - )); - } - } - - /** @internal */ - public function handleError(\Exception $e) - { - $this->emit('error', array($e)); - $this->close(); - } - - /** @internal */ - public function handleEnd() - { - $this->emit('data', array("0\r\n\r\n")); - - if (!$this->closed) { - $this->emit('end'); - $this->close(); - } - } -} diff --git a/vendor/react/http/src/Io/CloseProtectionStream.php b/vendor/react/http/src/Io/CloseProtectionStream.php deleted file mode 100644 index 2e1ed6e46..000000000 --- a/vendor/react/http/src/Io/CloseProtectionStream.php +++ /dev/null @@ -1,111 +0,0 @@ -input = $input; - - $this->input->on('data', array($this, 'handleData')); - $this->input->on('end', array($this, 'handleEnd')); - $this->input->on('error', array($this, 'handleError')); - $this->input->on('close', array($this, 'close')); - } - - public function isReadable() - { - return !$this->closed && $this->input->isReadable(); - } - - public function pause() - { - if ($this->closed) { - return; - } - - $this->paused = true; - $this->input->pause(); - } - - public function resume() - { - if ($this->closed) { - return; - } - - $this->paused = false; - $this->input->resume(); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - Util::pipe($this, $dest, $options); - - return $dest; - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->closed = true; - - // stop listening for incoming events - $this->input->removeListener('data', array($this, 'handleData')); - $this->input->removeListener('error', array($this, 'handleError')); - $this->input->removeListener('end', array($this, 'handleEnd')); - $this->input->removeListener('close', array($this, 'close')); - - // resume the stream to ensure we discard everything from incoming connection - if ($this->paused) { - $this->paused = false; - $this->input->resume(); - } - - $this->emit('close'); - $this->removeAllListeners(); - } - - /** @internal */ - public function handleData($data) - { - $this->emit('data', array($data)); - } - - /** @internal */ - public function handleEnd() - { - $this->emit('end'); - $this->close(); - } - - /** @internal */ - public function handleError(\Exception $e) - { - $this->emit('error', array($e)); - } -} diff --git a/vendor/react/http/src/Io/EmptyBodyStream.php b/vendor/react/http/src/Io/EmptyBodyStream.php deleted file mode 100644 index 5056219c1..000000000 --- a/vendor/react/http/src/Io/EmptyBodyStream.php +++ /dev/null @@ -1,142 +0,0 @@ -closed; - } - - public function pause() - { - // NOOP - } - - public function resume() - { - // NOOP - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - Util::pipe($this, $dest, $options); - - return $dest; - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->closed = true; - - $this->emit('close'); - $this->removeAllListeners(); - } - - public function getSize() - { - return 0; - } - - /** @ignore */ - public function __toString() - { - return ''; - } - - /** @ignore */ - public function detach() - { - return null; - } - - /** @ignore */ - public function tell() - { - throw new \BadMethodCallException(); - } - - /** @ignore */ - public function eof() - { - throw new \BadMethodCallException(); - } - - /** @ignore */ - public function isSeekable() - { - return false; - } - - /** @ignore */ - public function seek($offset, $whence = SEEK_SET) - { - throw new \BadMethodCallException(); - } - - /** @ignore */ - public function rewind() - { - throw new \BadMethodCallException(); - } - - /** @ignore */ - public function isWritable() - { - return false; - } - - /** @ignore */ - public function write($string) - { - throw new \BadMethodCallException(); - } - - /** @ignore */ - public function read($length) - { - throw new \BadMethodCallException(); - } - - /** @ignore */ - public function getContents() - { - return ''; - } - - /** @ignore */ - public function getMetadata($key = null) - { - return ($key === null) ? array() : null; - } -} diff --git a/vendor/react/http/src/Io/HttpBodyStream.php b/vendor/react/http/src/Io/HttpBodyStream.php deleted file mode 100644 index 25d15a18f..000000000 --- a/vendor/react/http/src/Io/HttpBodyStream.php +++ /dev/null @@ -1,182 +0,0 @@ -input = $input; - $this->size = $size; - - $this->input->on('data', array($this, 'handleData')); - $this->input->on('end', array($this, 'handleEnd')); - $this->input->on('error', array($this, 'handleError')); - $this->input->on('close', array($this, 'close')); - } - - public function isReadable() - { - return !$this->closed && $this->input->isReadable(); - } - - public function pause() - { - $this->input->pause(); - } - - public function resume() - { - $this->input->resume(); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - Util::pipe($this, $dest, $options); - - return $dest; - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->closed = true; - - $this->input->close(); - - $this->emit('close'); - $this->removeAllListeners(); - } - - public function getSize() - { - return $this->size; - } - - /** @ignore */ - public function __toString() - { - return ''; - } - - /** @ignore */ - public function detach() - { - return null; - } - - /** @ignore */ - public function tell() - { - throw new \BadMethodCallException(); - } - - /** @ignore */ - public function eof() - { - throw new \BadMethodCallException(); - } - - /** @ignore */ - public function isSeekable() - { - return false; - } - - /** @ignore */ - public function seek($offset, $whence = SEEK_SET) - { - throw new \BadMethodCallException(); - } - - /** @ignore */ - public function rewind() - { - throw new \BadMethodCallException(); - } - - /** @ignore */ - public function isWritable() - { - return false; - } - - /** @ignore */ - public function write($string) - { - throw new \BadMethodCallException(); - } - - /** @ignore */ - public function read($length) - { - throw new \BadMethodCallException(); - } - - /** @ignore */ - public function getContents() - { - return ''; - } - - /** @ignore */ - public function getMetadata($key = null) - { - return null; - } - - /** @internal */ - public function handleData($data) - { - $this->emit('data', array($data)); - } - - /** @internal */ - public function handleError(\Exception $e) - { - $this->emit('error', array($e)); - $this->close(); - } - - /** @internal */ - public function handleEnd() - { - if (!$this->closed) { - $this->emit('end'); - $this->close(); - } - } -} diff --git a/vendor/react/http/src/Io/IniUtil.php b/vendor/react/http/src/Io/IniUtil.php deleted file mode 100644 index 612aae295..000000000 --- a/vendor/react/http/src/Io/IniUtil.php +++ /dev/null @@ -1,48 +0,0 @@ -stream = $stream; - $this->maxLength = $maxLength; - - $this->stream->on('data', array($this, 'handleData')); - $this->stream->on('end', array($this, 'handleEnd')); - $this->stream->on('error', array($this, 'handleError')); - $this->stream->on('close', array($this, 'close')); - } - - public function isReadable() - { - return !$this->closed && $this->stream->isReadable(); - } - - public function pause() - { - $this->stream->pause(); - } - - public function resume() - { - $this->stream->resume(); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - Util::pipe($this, $dest, $options); - - return $dest; - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->closed = true; - - $this->stream->close(); - - $this->emit('close'); - $this->removeAllListeners(); - } - - /** @internal */ - public function handleData($data) - { - if (($this->transferredLength + \strlen($data)) > $this->maxLength) { - // Only emit data until the value of 'Content-Length' is reached, the rest will be ignored - $data = (string)\substr($data, 0, $this->maxLength - $this->transferredLength); - } - - if ($data !== '') { - $this->transferredLength += \strlen($data); - $this->emit('data', array($data)); - } - - if ($this->transferredLength === $this->maxLength) { - // 'Content-Length' reached, stream will end - $this->emit('end'); - $this->close(); - $this->stream->removeListener('data', array($this, 'handleData')); - } - } - - /** @internal */ - public function handleError(\Exception $e) - { - $this->emit('error', array($e)); - $this->close(); - } - - /** @internal */ - public function handleEnd() - { - if (!$this->closed) { - $this->handleError(new \Exception('Unexpected end event')); - } - } - -} diff --git a/vendor/react/http/src/Io/MiddlewareRunner.php b/vendor/react/http/src/Io/MiddlewareRunner.php deleted file mode 100644 index dedf6ff1d..000000000 --- a/vendor/react/http/src/Io/MiddlewareRunner.php +++ /dev/null @@ -1,61 +0,0 @@ -middleware = \array_values($middleware); - } - - /** - * @param ServerRequestInterface $request - * @return ResponseInterface|PromiseInterface - * @throws \Exception - */ - public function __invoke(ServerRequestInterface $request) - { - if (empty($this->middleware)) { - throw new \RuntimeException('No middleware to run'); - } - - return $this->call($request, 0); - } - - /** @internal */ - public function call(ServerRequestInterface $request, $position) - { - // final request handler will be invoked without a next handler - if (!isset($this->middleware[$position + 1])) { - $handler = $this->middleware[$position]; - return $handler($request); - } - - $that = $this; - $next = function (ServerRequestInterface $request) use ($that, $position) { - return $that->call($request, $position + 1); - }; - - // invoke middleware request handler with next handler - $handler = $this->middleware[$position]; - return $handler($request, $next); - } -} diff --git a/vendor/react/http/src/Io/MultipartParser.php b/vendor/react/http/src/Io/MultipartParser.php deleted file mode 100644 index 536694fd2..000000000 --- a/vendor/react/http/src/Io/MultipartParser.php +++ /dev/null @@ -1,328 +0,0 @@ -maxInputVars = (int)$var; - } - $var = \ini_get('max_input_nesting_level'); - if ($var !== false) { - $this->maxInputNestingLevel = (int)$var; - } - - if ($uploadMaxFilesize === null) { - $uploadMaxFilesize = \ini_get('upload_max_filesize'); - } - - $this->uploadMaxFilesize = IniUtil::iniSizeToBytes($uploadMaxFilesize); - $this->maxFileUploads = $maxFileUploads === null ? (\ini_get('file_uploads') === '' ? 0 : (int)\ini_get('max_file_uploads')) : (int)$maxFileUploads; - } - - public function parse(ServerRequestInterface $request) - { - $contentType = $request->getHeaderLine('content-type'); - if(!\preg_match('/boundary="?(.*?)"?$/', $contentType, $matches)) { - return $request; - } - - $this->request = $request; - $this->parseBody('--' . $matches[1], (string)$request->getBody()); - - $request = $this->request; - $this->request = null; - $this->postCount = 0; - $this->filesCount = 0; - $this->emptyCount = 0; - $this->maxFileSize = null; - - return $request; - } - - private function parseBody($boundary, $buffer) - { - $len = \strlen($boundary); - - // ignore everything before initial boundary (SHOULD be empty) - $start = \strpos($buffer, $boundary . "\r\n"); - - while ($start !== false) { - // search following boundary (preceded by newline) - // ignore last if not followed by boundary (SHOULD end with "--") - $start += $len + 2; - $end = \strpos($buffer, "\r\n" . $boundary, $start); - if ($end === false) { - break; - } - - // parse one part and continue searching for next - $this->parsePart(\substr($buffer, $start, $end - $start)); - $start = $end; - } - } - - private function parsePart($chunk) - { - $pos = \strpos($chunk, "\r\n\r\n"); - if ($pos === false) { - return; - } - - $headers = $this->parseHeaders((string)substr($chunk, 0, $pos)); - $body = (string)\substr($chunk, $pos + 4); - - if (!isset($headers['content-disposition'])) { - return; - } - - $name = $this->getParameterFromHeader($headers['content-disposition'], 'name'); - if ($name === null) { - return; - } - - $filename = $this->getParameterFromHeader($headers['content-disposition'], 'filename'); - if ($filename !== null) { - $this->parseFile( - $name, - $filename, - isset($headers['content-type'][0]) ? $headers['content-type'][0] : null, - $body - ); - } else { - $this->parsePost($name, $body); - } - } - - private function parseFile($name, $filename, $contentType, $contents) - { - $file = $this->parseUploadedFile($filename, $contentType, $contents); - if ($file === null) { - return; - } - - $this->request = $this->request->withUploadedFiles($this->extractPost( - $this->request->getUploadedFiles(), - $name, - $file - )); - } - - private function parseUploadedFile($filename, $contentType, $contents) - { - $size = \strlen($contents); - - // no file selected (zero size and empty filename) - if ($size === 0 && $filename === '') { - // ignore excessive number of empty file uploads - if (++$this->emptyCount + $this->filesCount > $this->maxInputVars) { - return; - } - - return new UploadedFile( - new BufferedBody(''), - $size, - \UPLOAD_ERR_NO_FILE, - $filename, - $contentType - ); - } - - // ignore excessive number of file uploads - if (++$this->filesCount > $this->maxFileUploads) { - return; - } - - // file exceeds "upload_max_filesize" ini setting - if ($size > $this->uploadMaxFilesize) { - return new UploadedFile( - new BufferedBody(''), - $size, - \UPLOAD_ERR_INI_SIZE, - $filename, - $contentType - ); - } - - // file exceeds MAX_FILE_SIZE value - if ($this->maxFileSize !== null && $size > $this->maxFileSize) { - return new UploadedFile( - new BufferedBody(''), - $size, - \UPLOAD_ERR_FORM_SIZE, - $filename, - $contentType - ); - } - - return new UploadedFile( - new BufferedBody($contents), - $size, - \UPLOAD_ERR_OK, - $filename, - $contentType - ); - } - - private function parsePost($name, $value) - { - // ignore excessive number of post fields - if (++$this->postCount > $this->maxInputVars) { - return; - } - - $this->request = $this->request->withParsedBody($this->extractPost( - $this->request->getParsedBody(), - $name, - $value - )); - - if (\strtoupper($name) === 'MAX_FILE_SIZE') { - $this->maxFileSize = (int)$value; - - if ($this->maxFileSize === 0) { - $this->maxFileSize = null; - } - } - } - - private function parseHeaders($header) - { - $headers = array(); - - foreach (\explode("\r\n", \trim($header)) as $line) { - $parts = \explode(':', $line, 2); - if (!isset($parts[1])) { - continue; - } - - $key = \strtolower(trim($parts[0])); - $values = \explode(';', $parts[1]); - $values = \array_map('trim', $values); - $headers[$key] = $values; - } - - return $headers; - } - - private function getParameterFromHeader(array $header, $parameter) - { - foreach ($header as $part) { - if (\preg_match('/' . $parameter . '="?(.*?)"?$/', $part, $matches)) { - return $matches[1]; - } - } - - return null; - } - - private function extractPost($postFields, $key, $value) - { - $chunks = \explode('[', $key); - if (\count($chunks) == 1) { - $postFields[$key] = $value; - return $postFields; - } - - // ignore this key if maximum nesting level is exceeded - if (isset($chunks[$this->maxInputNestingLevel])) { - return $postFields; - } - - $chunkKey = \rtrim($chunks[0], ']'); - $parent = &$postFields; - for ($i = 1; isset($chunks[$i]); $i++) { - $previousChunkKey = $chunkKey; - - if ($previousChunkKey === '') { - $parent[] = array(); - \end($parent); - $parent = &$parent[\key($parent)]; - } else { - if (!isset($parent[$previousChunkKey]) || !\is_array($parent[$previousChunkKey])) { - $parent[$previousChunkKey] = array(); - } - $parent = &$parent[$previousChunkKey]; - } - - $chunkKey = \rtrim($chunks[$i], ']'); - } - - if ($chunkKey === '') { - $parent[] = $value; - } else { - $parent[$chunkKey] = $value; - } - - return $postFields; - } -} diff --git a/vendor/react/http/src/Io/PauseBufferStream.php b/vendor/react/http/src/Io/PauseBufferStream.php deleted file mode 100644 index fb5ed4562..000000000 --- a/vendor/react/http/src/Io/PauseBufferStream.php +++ /dev/null @@ -1,188 +0,0 @@ -input = $input; - - $this->input->on('data', array($this, 'handleData')); - $this->input->on('end', array($this, 'handleEnd')); - $this->input->on('error', array($this, 'handleError')); - $this->input->on('close', array($this, 'handleClose')); - } - - /** - * pause and remember this was not explicitly from user control - * - * @internal - */ - public function pauseImplicit() - { - $this->pause(); - $this->implicit = true; - } - - /** - * resume only if this was previously paused implicitly and not explicitly from user control - * - * @internal - */ - public function resumeImplicit() - { - if ($this->implicit) { - $this->resume(); - } - } - - public function isReadable() - { - return !$this->closed; - } - - public function pause() - { - if ($this->closed) { - return; - } - - $this->input->pause(); - $this->paused = true; - $this->implicit = false; - } - - public function resume() - { - if ($this->closed) { - return; - } - - $this->paused = false; - $this->implicit = false; - - if ($this->dataPaused !== '') { - $this->emit('data', array($this->dataPaused)); - $this->dataPaused = ''; - } - - if ($this->errorPaused) { - $this->emit('error', array($this->errorPaused)); - return $this->close(); - } - - if ($this->endPaused) { - $this->endPaused = false; - $this->emit('end'); - return $this->close(); - } - - if ($this->closePaused) { - $this->closePaused = false; - return $this->close(); - } - - $this->input->resume(); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - Util::pipe($this, $dest, $options); - - return $dest; - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->closed = true; - $this->dataPaused = ''; - $this->endPaused = $this->closePaused = false; - $this->errorPaused = null; - - $this->input->close(); - - $this->emit('close'); - $this->removeAllListeners(); - } - - /** @internal */ - public function handleData($data) - { - if ($this->paused) { - $this->dataPaused .= $data; - return; - } - - $this->emit('data', array($data)); - } - - /** @internal */ - public function handleError(\Exception $e) - { - if ($this->paused) { - $this->errorPaused = $e; - return; - } - - $this->emit('error', array($e)); - $this->close(); - } - - /** @internal */ - public function handleEnd() - { - if ($this->paused) { - $this->endPaused = true; - return; - } - - if (!$this->closed) { - $this->emit('end'); - $this->close(); - } - } - - /** @internal */ - public function handleClose() - { - if ($this->paused) { - $this->closePaused = true; - return; - } - - $this->close(); - } -} diff --git a/vendor/react/http/src/Io/ReadableBodyStream.php b/vendor/react/http/src/Io/ReadableBodyStream.php deleted file mode 100644 index daef45f91..000000000 --- a/vendor/react/http/src/Io/ReadableBodyStream.php +++ /dev/null @@ -1,153 +0,0 @@ -input = $input; - $this->size = $size; - - $that = $this; - $pos =& $this->position; - $input->on('data', function ($data) use ($that, &$pos, $size) { - $that->emit('data', array($data)); - - $pos += \strlen($data); - if ($size !== null && $pos >= $size) { - $that->handleEnd(); - } - }); - $input->on('error', function ($error) use ($that) { - $that->emit('error', array($error)); - $that->close(); - }); - $input->on('end', array($that, 'handleEnd')); - $input->on('close', array($that, 'close')); - } - - public function close() - { - if (!$this->closed) { - $this->closed = true; - $this->input->close(); - - $this->emit('close'); - $this->removeAllListeners(); - } - } - - public function isReadable() - { - return $this->input->isReadable(); - } - - public function pause() - { - $this->input->pause(); - } - - public function resume() - { - $this->input->resume(); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - Util::pipe($this, $dest, $options); - - return $dest; - } - - public function eof() - { - return !$this->isReadable(); - } - - public function __toString() - { - return ''; - } - - public function detach() - { - throw new \BadMethodCallException(); - } - - public function getSize() - { - return $this->size; - } - - public function tell() - { - throw new \BadMethodCallException(); - } - - public function isSeekable() - { - return false; - } - - public function seek($offset, $whence = SEEK_SET) - { - throw new \BadMethodCallException(); - } - - public function rewind() - { - throw new \BadMethodCallException(); - } - - public function isWritable() - { - return false; - } - - public function write($string) - { - throw new \BadMethodCallException(); - } - - public function read($length) - { - throw new \BadMethodCallException(); - } - - public function getContents() - { - throw new \BadMethodCallException(); - } - - public function getMetadata($key = null) - { - return ($key === null) ? array() : null; - } - - /** @internal */ - public function handleEnd() - { - if ($this->position !== $this->size && $this->size !== null) { - $this->emit('error', array(new \UnderflowException('Unexpected end of response body after ' . $this->position . '/' . $this->size . ' bytes'))); - } else { - $this->emit('end'); - } - - $this->close(); - } -} diff --git a/vendor/react/http/src/Io/RequestHeaderParser.php b/vendor/react/http/src/Io/RequestHeaderParser.php deleted file mode 100644 index e5554c46b..000000000 --- a/vendor/react/http/src/Io/RequestHeaderParser.php +++ /dev/null @@ -1,281 +0,0 @@ -maxSize; - $that = $this; - $conn->on('data', $fn = function ($data) use (&$buffer, &$fn, $conn, $maxSize, $that) { - // append chunk of data to buffer and look for end of request headers - $buffer .= $data; - $endOfHeader = \strpos($buffer, "\r\n\r\n"); - - // reject request if buffer size is exceeded - if ($endOfHeader > $maxSize || ($endOfHeader === false && isset($buffer[$maxSize]))) { - $conn->removeListener('data', $fn); - $fn = null; - - $that->emit('error', array( - new \OverflowException("Maximum header size of {$maxSize} exceeded.", Response::STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE), - $conn - )); - return; - } - - // ignore incomplete requests - if ($endOfHeader === false) { - return; - } - - // request headers received => try to parse request - $conn->removeListener('data', $fn); - $fn = null; - - try { - $request = $that->parseRequest( - (string)\substr($buffer, 0, $endOfHeader + 2), - $conn->getRemoteAddress(), - $conn->getLocalAddress() - ); - } catch (Exception $exception) { - $buffer = ''; - $that->emit('error', array( - $exception, - $conn - )); - return; - } - - $contentLength = 0; - if ($request->hasHeader('Transfer-Encoding')) { - $contentLength = null; - } elseif ($request->hasHeader('Content-Length')) { - $contentLength = (int)$request->getHeaderLine('Content-Length'); - } - - if ($contentLength === 0) { - // happy path: request body is known to be empty - $stream = new EmptyBodyStream(); - $request = $request->withBody($stream); - } else { - // otherwise body is present => delimit using Content-Length or ChunkedDecoder - $stream = new CloseProtectionStream($conn); - if ($contentLength !== null) { - $stream = new LengthLimitedStream($stream, $contentLength); - } else { - $stream = new ChunkedDecoder($stream); - } - - $request = $request->withBody(new HttpBodyStream($stream, $contentLength)); - } - - $bodyBuffer = isset($buffer[$endOfHeader + 4]) ? \substr($buffer, $endOfHeader + 4) : ''; - $buffer = ''; - $that->emit('headers', array($request, $conn)); - - if ($bodyBuffer !== '') { - $conn->emit('data', array($bodyBuffer)); - } - - // happy path: request body is known to be empty => immediately end stream - if ($contentLength === 0) { - $stream->emit('end'); - $stream->close(); - } - }); - } - - /** - * @param string $headers buffer string containing request headers only - * @param ?string $remoteSocketUri - * @param ?string $localSocketUri - * @return ServerRequestInterface - * @throws \InvalidArgumentException - * @internal - */ - public function parseRequest($headers, $remoteSocketUri, $localSocketUri) - { - // additional, stricter safe-guard for request line - // because request parser doesn't properly cope with invalid ones - $start = array(); - if (!\preg_match('#^(?[^ ]+) (?[^ ]+) HTTP/(?\d\.\d)#m', $headers, $start)) { - throw new \InvalidArgumentException('Unable to parse invalid request-line'); - } - - // only support HTTP/1.1 and HTTP/1.0 requests - if ($start['version'] !== '1.1' && $start['version'] !== '1.0') { - throw new \InvalidArgumentException('Received request with invalid protocol version', Response::STATUS_VERSION_NOT_SUPPORTED); - } - - // match all request header fields into array, thanks to @kelunik for checking the HTTP specs and coming up with this regex - $matches = array(); - $n = \preg_match_all('/^([^()<>@,;:\\\"\/\[\]?={}\x01-\x20\x7F]++):[\x20\x09]*+((?:[\x20\x09]*+[\x21-\x7E\x80-\xFF]++)*+)[\x20\x09]*+[\r]?+\n/m', $headers, $matches, \PREG_SET_ORDER); - - // check number of valid header fields matches number of lines + request line - if (\substr_count($headers, "\n") !== $n + 1) { - throw new \InvalidArgumentException('Unable to parse invalid request header fields'); - } - - // format all header fields into associative array - $host = null; - $fields = array(); - foreach ($matches as $match) { - $fields[$match[1]][] = $match[2]; - - // match `Host` request header - if ($host === null && \strtolower($match[1]) === 'host') { - $host = $match[2]; - } - } - - // create new obj implementing ServerRequestInterface by preserving all - // previous properties and restoring original request-target - $serverParams = array( - 'REQUEST_TIME' => \time(), - 'REQUEST_TIME_FLOAT' => \microtime(true) - ); - - // scheme is `http` unless TLS is used - $localParts = $localSocketUri === null ? array() : \parse_url($localSocketUri); - if (isset($localParts['scheme']) && $localParts['scheme'] === 'tls') { - $scheme = 'https://'; - $serverParams['HTTPS'] = 'on'; - } else { - $scheme = 'http://'; - } - - // default host if unset comes from local socket address or defaults to localhost - $hasHost = $host !== null; - if ($host === null) { - $host = isset($localParts['host'], $localParts['port']) ? $localParts['host'] . ':' . $localParts['port'] : '127.0.0.1'; - } - - if ($start['method'] === 'OPTIONS' && $start['target'] === '*') { - // support asterisk-form for `OPTIONS *` request line only - $uri = $scheme . $host; - } elseif ($start['method'] === 'CONNECT') { - $parts = \parse_url('tcp://' . $start['target']); - - // check this is a valid authority-form request-target (host:port) - if (!isset($parts['scheme'], $parts['host'], $parts['port']) || \count($parts) !== 3) { - throw new \InvalidArgumentException('CONNECT method MUST use authority-form request target'); - } - $uri = $scheme . $start['target']; - } else { - // support absolute-form or origin-form for proxy requests - if ($start['target'][0] === '/') { - $uri = $scheme . $host . $start['target']; - } else { - // ensure absolute-form request-target contains a valid URI - $parts = \parse_url($start['target']); - - // make sure value contains valid host component (IP or hostname), but no fragment - if (!isset($parts['scheme'], $parts['host']) || $parts['scheme'] !== 'http' || isset($parts['fragment'])) { - throw new \InvalidArgumentException('Invalid absolute-form request-target'); - } - - $uri = $start['target']; - } - } - - // apply REMOTE_ADDR and REMOTE_PORT if source address is known - // address should always be known, unless this is over Unix domain sockets (UDS) - if ($remoteSocketUri !== null) { - $remoteAddress = \parse_url($remoteSocketUri); - $serverParams['REMOTE_ADDR'] = $remoteAddress['host']; - $serverParams['REMOTE_PORT'] = $remoteAddress['port']; - } - - // apply SERVER_ADDR and SERVER_PORT if server address is known - // address should always be known, even for Unix domain sockets (UDS) - // but skip UDS as it doesn't have a concept of host/port. - if ($localSocketUri !== null && isset($localParts['host'], $localParts['port'])) { - $serverParams['SERVER_ADDR'] = $localParts['host']; - $serverParams['SERVER_PORT'] = $localParts['port']; - } - - $request = new ServerRequest( - $start['method'], - $uri, - $fields, - '', - $start['version'], - $serverParams - ); - - // only assign request target if it is not in origin-form (happy path for most normal requests) - if ($start['target'][0] !== '/') { - $request = $request->withRequestTarget($start['target']); - } - - if ($hasHost) { - // Optional Host request header value MUST be valid (host and optional port) - $parts = \parse_url('http://' . $request->getHeaderLine('Host')); - - // make sure value contains valid host component (IP or hostname) - if (!$parts || !isset($parts['scheme'], $parts['host'])) { - $parts = false; - } - - // make sure value does not contain any other URI component - if (\is_array($parts)) { - unset($parts['scheme'], $parts['host'], $parts['port']); - } - if ($parts === false || $parts) { - throw new \InvalidArgumentException('Invalid Host header value'); - } - } elseif (!$hasHost && $start['version'] === '1.1' && $start['method'] !== 'CONNECT') { - // require Host request header for HTTP/1.1 (except for CONNECT method) - throw new \InvalidArgumentException('Missing required Host request header'); - } elseif (!$hasHost) { - // remove default Host request header for HTTP/1.0 when not explicitly given - $request = $request->withoutHeader('Host'); - } - - // ensure message boundaries are valid according to Content-Length and Transfer-Encoding request headers - if ($request->hasHeader('Transfer-Encoding')) { - if (\strtolower($request->getHeaderLine('Transfer-Encoding')) !== 'chunked') { - throw new \InvalidArgumentException('Only chunked-encoding is allowed for Transfer-Encoding', Response::STATUS_NOT_IMPLEMENTED); - } - - // Transfer-Encoding: chunked and Content-Length header MUST NOT be used at the same time - // as per https://tools.ietf.org/html/rfc7230#section-3.3.3 - if ($request->hasHeader('Content-Length')) { - throw new \InvalidArgumentException('Using both `Transfer-Encoding: chunked` and `Content-Length` is not allowed', Response::STATUS_BAD_REQUEST); - } - } elseif ($request->hasHeader('Content-Length')) { - $string = $request->getHeaderLine('Content-Length'); - - if ((string)(int)$string !== $string) { - // Content-Length value is not an integer or not a single integer - throw new \InvalidArgumentException('The value of `Content-Length` is not valid', Response::STATUS_BAD_REQUEST); - } - } - - return $request; - } -} diff --git a/vendor/react/http/src/Io/Sender.php b/vendor/react/http/src/Io/Sender.php deleted file mode 100644 index 2f04c7976..000000000 --- a/vendor/react/http/src/Io/Sender.php +++ /dev/null @@ -1,160 +0,0 @@ -http = $http; - } - - /** - * - * @internal - * @param RequestInterface $request - * @return PromiseInterface Promise - */ - public function send(RequestInterface $request) - { - $body = $request->getBody(); - $size = $body->getSize(); - - if ($size !== null && $size !== 0) { - // automatically assign a "Content-Length" request header if the body size is known and non-empty - $request = $request->withHeader('Content-Length', (string)$size); - } elseif ($size === 0 && \in_array($request->getMethod(), array('POST', 'PUT', 'PATCH'))) { - // only assign a "Content-Length: 0" request header if the body is expected for certain methods - $request = $request->withHeader('Content-Length', '0'); - } elseif ($body instanceof ReadableStreamInterface && $body->isReadable() && !$request->hasHeader('Content-Length')) { - // use "Transfer-Encoding: chunked" when this is a streaming body and body size is unknown - $request = $request->withHeader('Transfer-Encoding', 'chunked'); - } else { - // do not use chunked encoding if size is known or if this is an empty request body - $size = 0; - } - - $headers = array(); - foreach ($request->getHeaders() as $name => $values) { - $headers[$name] = implode(', ', $values); - } - - $requestStream = $this->http->request($request->getMethod(), (string)$request->getUri(), $headers, $request->getProtocolVersion()); - - $deferred = new Deferred(function ($_, $reject) use ($requestStream) { - // close request stream if request is cancelled - $reject(new \RuntimeException('Request cancelled')); - $requestStream->close(); - }); - - $requestStream->on('error', function($error) use ($deferred) { - $deferred->reject($error); - }); - - $requestStream->on('response', function (ResponseInterface $response, ReadableStreamInterface $body) use ($deferred, $request) { - $length = null; - $code = $response->getStatusCode(); - if ($request->getMethod() === 'HEAD' || ($code >= 100 && $code < 200) || $code == Response::STATUS_NO_CONTENT || $code == Response::STATUS_NOT_MODIFIED) { - $length = 0; - } elseif (\strtolower($response->getHeaderLine('Transfer-Encoding')) === 'chunked') { - $body = new ChunkedDecoder($body); - } elseif ($response->hasHeader('Content-Length')) { - $length = (int) $response->getHeaderLine('Content-Length'); - } - - $deferred->resolve($response->withBody(new ReadableBodyStream($body, $length))); - }); - - if ($body instanceof ReadableStreamInterface) { - if ($body->isReadable()) { - // length unknown => apply chunked transfer-encoding - if ($size === null) { - $body = new ChunkedEncoder($body); - } - - // pipe body into request stream - // add dummy write to immediately start request even if body does not emit any data yet - $body->pipe($requestStream); - $requestStream->write(''); - - $body->on('close', $close = function () use ($deferred, $requestStream) { - $deferred->reject(new \RuntimeException('Request failed because request body closed unexpectedly')); - $requestStream->close(); - }); - $body->on('error', function ($e) use ($deferred, $requestStream, $close, $body) { - $body->removeListener('close', $close); - $deferred->reject(new \RuntimeException('Request failed because request body reported an error', 0, $e)); - $requestStream->close(); - }); - $body->on('end', function () use ($close, $body) { - $body->removeListener('close', $close); - }); - } else { - // stream is not readable => end request without body - $requestStream->end(); - } - } else { - // body is fully buffered => write as one chunk - $requestStream->end((string)$body); - } - - return $deferred->promise(); - } -} diff --git a/vendor/react/http/src/Io/StreamingServer.php b/vendor/react/http/src/Io/StreamingServer.php deleted file mode 100644 index 7818f0bd9..000000000 --- a/vendor/react/http/src/Io/StreamingServer.php +++ /dev/null @@ -1,383 +0,0 @@ - 'text/plain' - * ), - * "Hello World!\n" - * ); - * }); - * ``` - * - * Each incoming HTTP request message is always represented by the - * [PSR-7 `ServerRequestInterface`](https://www.php-fig.org/psr/psr-7/#321-psrhttpmessageserverrequestinterface), - * see also following [request](#request) chapter for more details. - * Each outgoing HTTP response message is always represented by the - * [PSR-7 `ResponseInterface`](https://www.php-fig.org/psr/psr-7/#33-psrhttpmessageresponseinterface), - * see also following [response](#response) chapter for more details. - * - * In order to process any connections, the server needs to be attached to an - * instance of `React\Socket\ServerInterface` through the [`listen()`](#listen) method - * as described in the following chapter. In its most simple form, you can attach - * this to a [`React\Socket\SocketServer`](https://github.com/reactphp/socket#socketserver) - * in order to start a plaintext HTTP server like this: - * - * ```php - * $server = new StreamingServer($loop, $handler); - * - * $socket = new React\Socket\SocketServer('0.0.0.0:8080', array(), $loop); - * $server->listen($socket); - * ``` - * - * See also the [`listen()`](#listen) method and the [first example](examples) for more details. - * - * The `StreamingServer` class is considered advanced usage and unless you know - * what you're doing, you're recommended to use the [`HttpServer`](#httpserver) class - * instead. The `StreamingServer` class is specifically designed to help with - * more advanced use cases where you want to have full control over consuming - * the incoming HTTP request body and concurrency settings. - * - * In particular, this class does not buffer and parse the incoming HTTP request - * in memory. It will invoke the request handler function once the HTTP request - * headers have been received, i.e. before receiving the potentially much larger - * HTTP request body. This means the [request](#request) passed to your request - * handler function may not be fully compatible with PSR-7. See also - * [streaming request](#streaming-request) below for more details. - * - * @see \React\Http\HttpServer - * @see \React\Http\Message\Response - * @see self::listen() - * @internal - */ -final class StreamingServer extends EventEmitter -{ - private $callback; - private $parser; - private $loop; - - /** - * Creates an HTTP server that invokes the given callback for each incoming HTTP request - * - * In order to process any connections, the server needs to be attached to an - * instance of `React\Socket\ServerInterface` which emits underlying streaming - * connections in order to then parse incoming data as HTTP. - * See also [listen()](#listen) for more details. - * - * @param LoopInterface $loop - * @param callable $requestHandler - * @see self::listen() - */ - public function __construct(LoopInterface $loop, $requestHandler) - { - if (!\is_callable($requestHandler)) { - throw new \InvalidArgumentException('Invalid request handler given'); - } - - $this->loop = $loop; - - $this->callback = $requestHandler; - $this->parser = new RequestHeaderParser(); - - $that = $this; - $this->parser->on('headers', function (ServerRequestInterface $request, ConnectionInterface $conn) use ($that) { - $that->handleRequest($conn, $request); - }); - - $this->parser->on('error', function(\Exception $e, ConnectionInterface $conn) use ($that) { - $that->emit('error', array($e)); - - // parsing failed => assume dummy request and send appropriate error - $that->writeError( - $conn, - $e->getCode() !== 0 ? $e->getCode() : Response::STATUS_BAD_REQUEST, - new ServerRequest('GET', '/') - ); - }); - } - - /** - * Starts listening for HTTP requests on the given socket server instance - * - * @param ServerInterface $socket - * @see \React\Http\HttpServer::listen() - */ - public function listen(ServerInterface $socket) - { - $socket->on('connection', array($this->parser, 'handle')); - } - - /** @internal */ - public function handleRequest(ConnectionInterface $conn, ServerRequestInterface $request) - { - if ($request->getProtocolVersion() !== '1.0' && '100-continue' === \strtolower($request->getHeaderLine('Expect'))) { - $conn->write("HTTP/1.1 100 Continue\r\n\r\n"); - } - - // execute request handler callback - $callback = $this->callback; - try { - $response = $callback($request); - } catch (\Exception $error) { - // request handler callback throws an Exception - $response = Promise\reject($error); - } catch (\Throwable $error) { // @codeCoverageIgnoreStart - // request handler callback throws a PHP7+ Error - $response = Promise\reject($error); // @codeCoverageIgnoreEnd - } - - // cancel pending promise once connection closes - if ($response instanceof CancellablePromiseInterface) { - $conn->on('close', function () use ($response) { - $response->cancel(); - }); - } - - // happy path: response returned, handle and return immediately - if ($response instanceof ResponseInterface) { - return $this->handleResponse($conn, $request, $response); - } - - // did not return a promise? this is an error, convert into one for rejection below. - if (!$response instanceof PromiseInterface) { - $response = Promise\resolve($response); - } - - $that = $this; - $response->then( - function ($response) use ($that, $conn, $request) { - if (!$response instanceof ResponseInterface) { - $message = 'The response callback is expected to resolve with an object implementing Psr\Http\Message\ResponseInterface, but resolved with "%s" instead.'; - $message = \sprintf($message, \is_object($response) ? \get_class($response) : \gettype($response)); - $exception = new \RuntimeException($message); - - $that->emit('error', array($exception)); - return $that->writeError($conn, Response::STATUS_INTERNAL_SERVER_ERROR, $request); - } - $that->handleResponse($conn, $request, $response); - }, - function ($error) use ($that, $conn, $request) { - $message = 'The response callback is expected to resolve with an object implementing Psr\Http\Message\ResponseInterface, but rejected with "%s" instead.'; - $message = \sprintf($message, \is_object($error) ? \get_class($error) : \gettype($error)); - - $previous = null; - - if ($error instanceof \Throwable || $error instanceof \Exception) { - $previous = $error; - } - - $exception = new \RuntimeException($message, 0, $previous); - - $that->emit('error', array($exception)); - return $that->writeError($conn, Response::STATUS_INTERNAL_SERVER_ERROR, $request); - } - ); - } - - /** @internal */ - public function writeError(ConnectionInterface $conn, $code, ServerRequestInterface $request) - { - $response = new Response( - $code, - array( - 'Content-Type' => 'text/plain', - 'Connection' => 'close' // we do not want to keep the connection open after an error - ), - 'Error ' . $code - ); - - // append reason phrase to response body if known - $reason = $response->getReasonPhrase(); - if ($reason !== '') { - $body = $response->getBody(); - $body->seek(0, SEEK_END); - $body->write(': ' . $reason); - } - - $this->handleResponse($conn, $request, $response); - } - - - /** @internal */ - public function handleResponse(ConnectionInterface $connection, ServerRequestInterface $request, ResponseInterface $response) - { - // return early and close response body if connection is already closed - $body = $response->getBody(); - if (!$connection->isWritable()) { - $body->close(); - return; - } - - $code = $response->getStatusCode(); - $method = $request->getMethod(); - - // assign HTTP protocol version from request automatically - $version = $request->getProtocolVersion(); - $response = $response->withProtocolVersion($version); - - // assign default "Server" header automatically - if (!$response->hasHeader('Server')) { - $response = $response->withHeader('Server', 'ReactPHP/1'); - } elseif ($response->getHeaderLine('Server') === ''){ - $response = $response->withoutHeader('Server'); - } - - // assign default "Date" header from current time automatically - if (!$response->hasHeader('Date')) { - // IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT - $response = $response->withHeader('Date', gmdate('D, d M Y H:i:s') . ' GMT'); - } elseif ($response->getHeaderLine('Date') === ''){ - $response = $response->withoutHeader('Date'); - } - - // assign "Content-Length" header automatically - $chunked = false; - if (($method === 'CONNECT' && $code >= 200 && $code < 300) || ($code >= 100 && $code < 200) || $code === Response::STATUS_NO_CONTENT) { - // 2xx response to CONNECT and 1xx and 204 MUST NOT include Content-Length or Transfer-Encoding header - $response = $response->withoutHeader('Content-Length'); - } elseif ($code === Response::STATUS_NOT_MODIFIED && ($response->hasHeader('Content-Length') || $body->getSize() === 0)) { - // 304 Not Modified: preserve explicit Content-Length and preserve missing header if body is empty - } elseif ($body->getSize() !== null) { - // assign Content-Length header when using a "normal" buffered body string - $response = $response->withHeader('Content-Length', (string)$body->getSize()); - } elseif (!$response->hasHeader('Content-Length') && $version === '1.1') { - // assign chunked transfer-encoding if no 'content-length' is given for HTTP/1.1 responses - $chunked = true; - } - - // assign "Transfer-Encoding" header automatically - if ($chunked) { - $response = $response->withHeader('Transfer-Encoding', 'chunked'); - } else { - // remove any Transfer-Encoding headers unless automatically enabled above - $response = $response->withoutHeader('Transfer-Encoding'); - } - - // assign "Connection" header automatically - $persist = false; - if ($code === Response::STATUS_SWITCHING_PROTOCOLS) { - // 101 (Switching Protocols) response uses Connection: upgrade header - // This implies that this stream now uses another protocol and we - // may not persist this connection for additional requests. - $response = $response->withHeader('Connection', 'upgrade'); - } elseif (\strtolower($request->getHeaderLine('Connection')) === 'close' || \strtolower($response->getHeaderLine('Connection')) === 'close') { - // obey explicit "Connection: close" request header or response header if present - $response = $response->withHeader('Connection', 'close'); - } elseif ($version === '1.1') { - // HTTP/1.1 assumes persistent connection support by default, so we don't need to inform client - $persist = true; - } elseif (strtolower($request->getHeaderLine('Connection')) === 'keep-alive') { - // obey explicit "Connection: keep-alive" request header and inform client - $persist = true; - $response = $response->withHeader('Connection', 'keep-alive'); - } else { - // remove any Connection headers unless automatically enabled above - $response = $response->withoutHeader('Connection'); - } - - // 101 (Switching Protocols) response (for Upgrade request) forwards upgraded data through duplex stream - // 2xx (Successful) response to CONNECT forwards tunneled application data through duplex stream - if (($code === Response::STATUS_SWITCHING_PROTOCOLS || ($method === 'CONNECT' && $code >= 200 && $code < 300)) && $body instanceof HttpBodyStream && $body->input instanceof WritableStreamInterface) { - if ($request->getBody()->isReadable()) { - // request is still streaming => wait for request close before forwarding following data from connection - $request->getBody()->on('close', function () use ($connection, $body) { - if ($body->input->isWritable()) { - $connection->pipe($body->input); - $connection->resume(); - } - }); - } elseif ($body->input->isWritable()) { - // request already closed => forward following data from connection - $connection->pipe($body->input); - $connection->resume(); - } - } - - // build HTTP response header by appending status line and header fields - $headers = "HTTP/" . $version . " " . $code . " " . $response->getReasonPhrase() . "\r\n"; - foreach ($response->getHeaders() as $name => $values) { - foreach ($values as $value) { - $headers .= $name . ": " . $value . "\r\n"; - } - } - - // response to HEAD and 1xx, 204 and 304 responses MUST NOT include a body - // exclude status 101 (Switching Protocols) here for Upgrade request handling above - if ($method === 'HEAD' || ($code >= 100 && $code < 200 && $code !== Response::STATUS_SWITCHING_PROTOCOLS) || $code === Response::STATUS_NO_CONTENT || $code === Response::STATUS_NOT_MODIFIED) { - $body->close(); - $body = ''; - } - - // this is a non-streaming response body or the body stream already closed? - if (!$body instanceof ReadableStreamInterface || !$body->isReadable()) { - // add final chunk if a streaming body is already closed and uses `Transfer-Encoding: chunked` - if ($body instanceof ReadableStreamInterface && $chunked) { - $body = "0\r\n\r\n"; - } - - // write response headers and body - $connection->write($headers . "\r\n" . $body); - - // either wait for next request over persistent connection or end connection - if ($persist) { - $this->parser->handle($connection); - } else { - $connection->end(); - } - return; - } - - $connection->write($headers . "\r\n"); - - if ($chunked) { - $body = new ChunkedEncoder($body); - } - - // Close response stream once connection closes. - // Note that this TCP/IP close detection may take some time, - // in particular this may only fire on a later read/write attempt. - $connection->on('close', array($body, 'close')); - - // write streaming body and then wait for next request over persistent connection - if ($persist) { - $body->pipe($connection, array('end' => false)); - $parser = $this->parser; - $body->on('end', function () use ($connection, $parser, $body) { - $connection->removeListener('close', array($body, 'close')); - $parser->handle($connection); - }); - } else { - $body->pipe($connection); - } - } -} diff --git a/vendor/react/http/src/Io/Transaction.php b/vendor/react/http/src/Io/Transaction.php deleted file mode 100644 index 7bf7008fd..000000000 --- a/vendor/react/http/src/Io/Transaction.php +++ /dev/null @@ -1,303 +0,0 @@ -sender = $sender; - $this->loop = $loop; - } - - /** - * @param array $options - * @return self returns new instance, without modifying existing instance - */ - public function withOptions(array $options) - { - $transaction = clone $this; - foreach ($options as $name => $value) { - if (property_exists($transaction, $name)) { - // restore default value if null is given - if ($value === null) { - $default = new self($this->sender, $this->loop); - $value = $default->$name; - } - - $transaction->$name = $value; - } - } - - return $transaction; - } - - public function send(RequestInterface $request) - { - $deferred = new Deferred(function () use (&$deferred) { - if (isset($deferred->pending)) { - $deferred->pending->cancel(); - unset($deferred->pending); - } - }); - - $deferred->numRequests = 0; - - // use timeout from options or default to PHP's default_socket_timeout (60) - $timeout = (float)($this->timeout !== null ? $this->timeout : ini_get("default_socket_timeout")); - - $loop = $this->loop; - $this->next($request, $deferred)->then( - function (ResponseInterface $response) use ($deferred, $loop, &$timeout) { - if (isset($deferred->timeout)) { - $loop->cancelTimer($deferred->timeout); - unset($deferred->timeout); - } - $timeout = -1; - $deferred->resolve($response); - }, - function ($e) use ($deferred, $loop, &$timeout) { - if (isset($deferred->timeout)) { - $loop->cancelTimer($deferred->timeout); - unset($deferred->timeout); - } - $timeout = -1; - $deferred->reject($e); - } - ); - - if ($timeout < 0) { - return $deferred->promise(); - } - - $body = $request->getBody(); - if ($body instanceof ReadableStreamInterface && $body->isReadable()) { - $that = $this; - $body->on('close', function () use ($that, $deferred, &$timeout) { - if ($timeout >= 0) { - $that->applyTimeout($deferred, $timeout); - } - }); - } else { - $this->applyTimeout($deferred, $timeout); - } - - return $deferred->promise(); - } - - /** - * @internal - * @param Deferred $deferred - * @param number $timeout - * @return void - */ - public function applyTimeout(Deferred $deferred, $timeout) - { - $deferred->timeout = $this->loop->addTimer($timeout, function () use ($timeout, $deferred) { - $deferred->reject(new \RuntimeException( - 'Request timed out after ' . $timeout . ' seconds' - )); - if (isset($deferred->pending)) { - $deferred->pending->cancel(); - unset($deferred->pending); - } - }); - } - - private function next(RequestInterface $request, Deferred $deferred) - { - $this->progress('request', array($request)); - - $that = $this; - ++$deferred->numRequests; - - $promise = $this->sender->send($request); - - if (!$this->streaming) { - $promise = $promise->then(function ($response) use ($deferred, $that) { - return $that->bufferResponse($response, $deferred); - }); - } - - $deferred->pending = $promise; - - return $promise->then( - function (ResponseInterface $response) use ($request, $that, $deferred) { - return $that->onResponse($response, $request, $deferred); - } - ); - } - - /** - * @internal - * @param ResponseInterface $response - * @return PromiseInterface Promise - */ - public function bufferResponse(ResponseInterface $response, $deferred) - { - $stream = $response->getBody(); - - $size = $stream->getSize(); - if ($size !== null && $size > $this->maximumSize) { - $stream->close(); - return \React\Promise\reject(new \OverflowException( - 'Response body size of ' . $size . ' bytes exceeds maximum of ' . $this->maximumSize . ' bytes', - \defined('SOCKET_EMSGSIZE') ? \SOCKET_EMSGSIZE : 0 - )); - } - - // body is not streaming => already buffered - if (!$stream instanceof ReadableStreamInterface) { - return \React\Promise\resolve($response); - } - - // buffer stream and resolve with buffered body - $maximumSize = $this->maximumSize; - $promise = \React\Promise\Stream\buffer($stream, $maximumSize)->then( - function ($body) use ($response) { - return $response->withBody(new BufferedBody($body)); - }, - function ($e) use ($stream, $maximumSize) { - // try to close stream if buffering fails (or is cancelled) - $stream->close(); - - if ($e instanceof \OverflowException) { - $e = new \OverflowException( - 'Response body size exceeds maximum of ' . $maximumSize . ' bytes', - \defined('SOCKET_EMSGSIZE') ? \SOCKET_EMSGSIZE : 0 - ); - } - - throw $e; - } - ); - - $deferred->pending = $promise; - - return $promise; - } - - /** - * @internal - * @param ResponseInterface $response - * @param RequestInterface $request - * @throws ResponseException - * @return ResponseInterface|PromiseInterface - */ - public function onResponse(ResponseInterface $response, RequestInterface $request, $deferred) - { - $this->progress('response', array($response, $request)); - - // follow 3xx (Redirection) response status codes if Location header is present and not explicitly disabled - // @link https://tools.ietf.org/html/rfc7231#section-6.4 - if ($this->followRedirects && ($response->getStatusCode() >= 300 && $response->getStatusCode() < 400) && $response->hasHeader('Location')) { - return $this->onResponseRedirect($response, $request, $deferred); - } - - // only status codes 200-399 are considered to be valid, reject otherwise - if ($this->obeySuccessCode && ($response->getStatusCode() < 200 || $response->getStatusCode() >= 400)) { - throw new ResponseException($response); - } - - // resolve our initial promise - return $response; - } - - /** - * @param ResponseInterface $response - * @param RequestInterface $request - * @return PromiseInterface - * @throws \RuntimeException - */ - private function onResponseRedirect(ResponseInterface $response, RequestInterface $request, Deferred $deferred) - { - // resolve location relative to last request URI - $location = Uri::resolve($request->getUri(), $response->getHeaderLine('Location')); - - $request = $this->makeRedirectRequest($request, $location); - $this->progress('redirect', array($request)); - - if ($deferred->numRequests >= $this->maxRedirects) { - throw new \RuntimeException('Maximum number of redirects (' . $this->maxRedirects . ') exceeded'); - } - - return $this->next($request, $deferred); - } - - /** - * @param RequestInterface $request - * @param UriInterface $location - * @return RequestInterface - */ - private function makeRedirectRequest(RequestInterface $request, UriInterface $location) - { - $originalHost = $request->getUri()->getHost(); - $request = $request - ->withoutHeader('Host') - ->withoutHeader('Content-Type') - ->withoutHeader('Content-Length'); - - // Remove authorization if changing hostnames (but not if just changing ports or protocols). - if ($location->getHost() !== $originalHost) { - $request = $request->withoutHeader('Authorization'); - } - - // naïve approach.. - $method = ($request->getMethod() === 'HEAD') ? 'HEAD' : 'GET'; - - return new Request($method, $location, $request->getHeaders()); - } - - private function progress($name, array $args = array()) - { - return; - - echo $name; - - foreach ($args as $arg) { - echo ' '; - if ($arg instanceof ResponseInterface) { - echo 'HTTP/' . $arg->getProtocolVersion() . ' ' . $arg->getStatusCode() . ' ' . $arg->getReasonPhrase(); - } elseif ($arg instanceof RequestInterface) { - echo $arg->getMethod() . ' ' . $arg->getRequestTarget() . ' HTTP/' . $arg->getProtocolVersion(); - } else { - echo $arg; - } - } - - echo PHP_EOL; - } -} diff --git a/vendor/react/http/src/Io/UploadedFile.php b/vendor/react/http/src/Io/UploadedFile.php deleted file mode 100644 index f2a6c9e79..000000000 --- a/vendor/react/http/src/Io/UploadedFile.php +++ /dev/null @@ -1,130 +0,0 @@ -stream = $stream; - $this->size = $size; - - if (!\is_int($error) || !\in_array($error, array( - \UPLOAD_ERR_OK, - \UPLOAD_ERR_INI_SIZE, - \UPLOAD_ERR_FORM_SIZE, - \UPLOAD_ERR_PARTIAL, - \UPLOAD_ERR_NO_FILE, - \UPLOAD_ERR_NO_TMP_DIR, - \UPLOAD_ERR_CANT_WRITE, - \UPLOAD_ERR_EXTENSION, - ))) { - throw new InvalidArgumentException( - 'Invalid error code, must be an UPLOAD_ERR_* constant' - ); - } - $this->error = $error; - $this->filename = $filename; - $this->mediaType = $mediaType; - } - - /** - * {@inheritdoc} - */ - public function getStream() - { - if ($this->error !== \UPLOAD_ERR_OK) { - throw new RuntimeException('Cannot retrieve stream due to upload error'); - } - - return $this->stream; - } - - /** - * {@inheritdoc} - */ - public function moveTo($targetPath) - { - throw new RuntimeException('Not implemented'); - } - - /** - * {@inheritdoc} - */ - public function getSize() - { - return $this->size; - } - - /** - * {@inheritdoc} - */ - public function getError() - { - return $this->error; - } - - /** - * {@inheritdoc} - */ - public function getClientFilename() - { - return $this->filename; - } - - /** - * {@inheritdoc} - */ - public function getClientMediaType() - { - return $this->mediaType; - } -} diff --git a/vendor/react/http/src/Message/Response.php b/vendor/react/http/src/Message/Response.php deleted file mode 100644 index edd6245bd..000000000 --- a/vendor/react/http/src/Message/Response.php +++ /dev/null @@ -1,291 +0,0 @@ - 'text/html' - * ), - * "Hello world!\n" - * ); - * ``` - * - * This class implements the - * [PSR-7 `ResponseInterface`](https://www.php-fig.org/psr/psr-7/#33-psrhttpmessageresponseinterface) - * which in turn extends the - * [PSR-7 `MessageInterface`](https://www.php-fig.org/psr/psr-7/#31-psrhttpmessagemessageinterface). - * - * On top of this, this class implements the - * [PSR-7 Message Util `StatusCodeInterface`](https://github.com/php-fig/http-message-util/blob/master/src/StatusCodeInterface.php) - * which means that most common HTTP status codes are available as class - * constants with the `STATUS_*` prefix. For instance, the `200 OK` and - * `404 Not Found` status codes can used as `Response::STATUS_OK` and - * `Response::STATUS_NOT_FOUND` respectively. - * - * > Internally, this implementation builds on top of an existing incoming - * response message and only adds required streaming support. This base class is - * considered an implementation detail that may change in the future. - * - * @see \Psr\Http\Message\ResponseInterface - */ -final class Response extends Psr7Response implements StatusCodeInterface -{ - /** - * Create an HTML response - * - * ```php - * $html = << - * - * Hello wörld! - * - * - * HTML; - * - * $response = React\Http\Message\Response::html($html); - * ``` - * - * This is a convenient shortcut method that returns the equivalent of this: - * - * ``` - * $response = new React\Http\Message\Response( - * React\Http\Message\Response::STATUS_OK, - * [ - * 'Content-Type' => 'text/html; charset=utf-8' - * ], - * $html - * ); - * ``` - * - * This method always returns a response with a `200 OK` status code and - * the appropriate `Content-Type` response header for the given HTTP source - * string encoded in UTF-8 (Unicode). It's generally recommended to end the - * given plaintext string with a trailing newline. - * - * If you want to use a different status code or custom HTTP response - * headers, you can manipulate the returned response object using the - * provided PSR-7 methods or directly instantiate a custom HTTP response - * object using the `Response` constructor: - * - * ```php - * $response = React\Http\Message\Response::html( - * "

Error

\n

Invalid user name given.

\n" - * )->withStatus(React\Http\Message\Response::STATUS_BAD_REQUEST); - * ``` - * - * @param string $html - * @return self - */ - public static function html($html) - { - return new self(self::STATUS_OK, array('Content-Type' => 'text/html; charset=utf-8'), $html); - } - - /** - * Create a JSON response - * - * ```php - * $response = React\Http\Message\Response::json(['name' => 'Alice']); - * ``` - * - * This is a convenient shortcut method that returns the equivalent of this: - * - * ``` - * $response = new React\Http\Message\Response( - * React\Http\Message\Response::STATUS_OK, - * [ - * 'Content-Type' => 'application/json' - * ], - * json_encode( - * ['name' => 'Alice'], - * JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRESERVE_ZERO_FRACTION - * ) . "\n" - * ); - * ``` - * - * This method always returns a response with a `200 OK` status code and - * the appropriate `Content-Type` response header for the given structured - * data encoded as a JSON text. - * - * The given structured data will be encoded as a JSON text. Any `string` - * values in the data must be encoded in UTF-8 (Unicode). If the encoding - * fails, this method will throw an `InvalidArgumentException`. - * - * By default, the given structured data will be encoded with the flags as - * shown above. This includes pretty printing (PHP 5.4+) and preserving - * zero fractions for `float` values (PHP 5.6.6+) to ease debugging. It is - * assumed any additional data overhead is usually compensated by using HTTP - * response compression. - * - * If you want to use a different status code or custom HTTP response - * headers, you can manipulate the returned response object using the - * provided PSR-7 methods or directly instantiate a custom HTTP response - * object using the `Response` constructor: - * - * ```php - * $response = React\Http\Message\Response::json( - * ['error' => 'Invalid user name given'] - * )->withStatus(React\Http\Message\Response::STATUS_BAD_REQUEST); - * ``` - * - * @param mixed $data - * @return self - * @throws \InvalidArgumentException when encoding fails - */ - public static function json($data) - { - $json = @\json_encode( - $data, - (\defined('JSON_PRETTY_PRINT') ? \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE : 0) | (\defined('JSON_PRESERVE_ZERO_FRACTION') ? \JSON_PRESERVE_ZERO_FRACTION : 0) - ); - - // throw on error, now `false` but used to be `(string) "null"` before PHP 5.5 - if ($json === false || (\PHP_VERSION_ID < 50500 && \json_last_error() !== \JSON_ERROR_NONE)) { - throw new \InvalidArgumentException( - 'Unable to encode given data as JSON' . (\function_exists('json_last_error_msg') ? ': ' . \json_last_error_msg() : ''), - \json_last_error() - ); - } - - return new self(self::STATUS_OK, array('Content-Type' => 'application/json'), $json . "\n"); - } - - /** - * Create a plaintext response - * - * ```php - * $response = React\Http\Message\Response::plaintext("Hello wörld!\n"); - * ``` - * - * This is a convenient shortcut method that returns the equivalent of this: - * - * ``` - * $response = new React\Http\Message\Response( - * React\Http\Message\Response::STATUS_OK, - * [ - * 'Content-Type' => 'text/plain; charset=utf-8' - * ], - * "Hello wörld!\n" - * ); - * ``` - * - * This method always returns a response with a `200 OK` status code and - * the appropriate `Content-Type` response header for the given plaintext - * string encoded in UTF-8 (Unicode). It's generally recommended to end the - * given plaintext string with a trailing newline. - * - * If you want to use a different status code or custom HTTP response - * headers, you can manipulate the returned response object using the - * provided PSR-7 methods or directly instantiate a custom HTTP response - * object using the `Response` constructor: - * - * ```php - * $response = React\Http\Message\Response::plaintext( - * "Error: Invalid user name given.\n" - * )->withStatus(React\Http\Message\Response::STATUS_BAD_REQUEST); - * ``` - * - * @param string $text - * @return self - */ - public static function plaintext($text) - { - return new self(self::STATUS_OK, array('Content-Type' => 'text/plain; charset=utf-8'), $text); - } - - /** - * Create an XML response - * - * ```php - * $xml = << - * - * Hello wörld! - * - * - * XML; - * - * $response = React\Http\Message\Response::xml($xml); - * ``` - * - * This is a convenient shortcut method that returns the equivalent of this: - * - * ``` - * $response = new React\Http\Message\Response( - * React\Http\Message\Response::STATUS_OK, - * [ - * 'Content-Type' => 'application/xml' - * ], - * $xml - * ); - * ``` - * - * This method always returns a response with a `200 OK` status code and - * the appropriate `Content-Type` response header for the given XML source - * string. It's generally recommended to use UTF-8 (Unicode) and specify - * this as part of the leading XML declaration and to end the given XML - * source string with a trailing newline. - * - * If you want to use a different status code or custom HTTP response - * headers, you can manipulate the returned response object using the - * provided PSR-7 methods or directly instantiate a custom HTTP response - * object using the `Response` constructor: - * - * ```php - * $response = React\Http\Message\Response::xml( - * "Invalid user name given.\n" - * )->withStatus(React\Http\Message\Response::STATUS_BAD_REQUEST); - * ``` - * - * @param string $xml - * @return self - */ - public static function xml($xml) - { - return new self(self::STATUS_OK, array('Content-Type' => 'application/xml'), $xml); - } - - /** - * @param int $status HTTP status code (e.g. 200/404), see `self::STATUS_*` constants - * @param array $headers additional response headers - * @param string|ReadableStreamInterface|StreamInterface $body response body - * @param string $version HTTP protocol version (e.g. 1.1/1.0) - * @param ?string $reason custom HTTP response phrase - * @throws \InvalidArgumentException for an invalid body - */ - public function __construct( - $status = self::STATUS_OK, - array $headers = array(), - $body = '', - $version = '1.1', - $reason = null - ) { - if (\is_string($body)) { - $body = new BufferedBody($body); - } elseif ($body instanceof ReadableStreamInterface && !$body instanceof StreamInterface) { - $body = new HttpBodyStream($body, null); - } elseif (!$body instanceof StreamInterface) { - throw new \InvalidArgumentException('Invalid response body given'); - } - - parent::__construct( - $status, - $headers, - $body, - $version, - $reason - ); - } -} diff --git a/vendor/react/http/src/Message/ResponseException.php b/vendor/react/http/src/Message/ResponseException.php deleted file mode 100644 index f4912c90c..000000000 --- a/vendor/react/http/src/Message/ResponseException.php +++ /dev/null @@ -1,43 +0,0 @@ -getStatusCode() . ' (' . $response->getReasonPhrase() . ')'; - } - if ($code === null) { - $code = $response->getStatusCode(); - } - parent::__construct($message, $code, $previous); - - $this->response = $response; - } - - /** - * Access its underlying response object. - * - * @return ResponseInterface - */ - public function getResponse() - { - return $this->response; - } -} diff --git a/vendor/react/http/src/Message/ServerRequest.php b/vendor/react/http/src/Message/ServerRequest.php deleted file mode 100644 index f446f24e8..000000000 --- a/vendor/react/http/src/Message/ServerRequest.php +++ /dev/null @@ -1,197 +0,0 @@ - Internally, this implementation builds on top of an existing outgoing - * request message and only adds required server methods. This base class is - * considered an implementation detail that may change in the future. - * - * @see ServerRequestInterface - */ -final class ServerRequest extends Request implements ServerRequestInterface -{ - private $attributes = array(); - - private $serverParams; - private $fileParams = array(); - private $cookies = array(); - private $queryParams = array(); - private $parsedBody; - - /** - * @param string $method HTTP method for the request. - * @param string|UriInterface $url URL for the request. - * @param array $headers Headers for the message. - * @param string|ReadableStreamInterface|StreamInterface $body Message body. - * @param string $version HTTP protocol version. - * @param array $serverParams server-side parameters - * @throws \InvalidArgumentException for an invalid URL or body - */ - public function __construct( - $method, - $url, - array $headers = array(), - $body = '', - $version = '1.1', - $serverParams = array() - ) { - $stream = null; - if (\is_string($body)) { - $body = new BufferedBody($body); - } elseif ($body instanceof ReadableStreamInterface && !$body instanceof StreamInterface) { - $stream = $body; - $body = null; - } elseif (!$body instanceof StreamInterface) { - throw new \InvalidArgumentException('Invalid server request body given'); - } - - $this->serverParams = $serverParams; - parent::__construct($method, $url, $headers, $body, $version); - - if ($stream !== null) { - $size = (int) $this->getHeaderLine('Content-Length'); - if (\strtolower($this->getHeaderLine('Transfer-Encoding')) === 'chunked') { - $size = null; - } - $this->stream = new HttpBodyStream($stream, $size); - } - - $query = $this->getUri()->getQuery(); - if ($query !== '') { - \parse_str($query, $this->queryParams); - } - - // Multiple cookie headers are not allowed according - // to https://tools.ietf.org/html/rfc6265#section-5.4 - $cookieHeaders = $this->getHeader("Cookie"); - - if (count($cookieHeaders) === 1) { - $this->cookies = $this->parseCookie($cookieHeaders[0]); - } - } - - public function getServerParams() - { - return $this->serverParams; - } - - public function getCookieParams() - { - return $this->cookies; - } - - public function withCookieParams(array $cookies) - { - $new = clone $this; - $new->cookies = $cookies; - return $new; - } - - public function getQueryParams() - { - return $this->queryParams; - } - - public function withQueryParams(array $query) - { - $new = clone $this; - $new->queryParams = $query; - return $new; - } - - public function getUploadedFiles() - { - return $this->fileParams; - } - - public function withUploadedFiles(array $uploadedFiles) - { - $new = clone $this; - $new->fileParams = $uploadedFiles; - return $new; - } - - public function getParsedBody() - { - return $this->parsedBody; - } - - public function withParsedBody($data) - { - $new = clone $this; - $new->parsedBody = $data; - return $new; - } - - public function getAttributes() - { - return $this->attributes; - } - - public function getAttribute($name, $default = null) - { - if (!\array_key_exists($name, $this->attributes)) { - return $default; - } - return $this->attributes[$name]; - } - - public function withAttribute($name, $value) - { - $new = clone $this; - $new->attributes[$name] = $value; - return $new; - } - - public function withoutAttribute($name) - { - $new = clone $this; - unset($new->attributes[$name]); - return $new; - } - - /** - * @param string $cookie - * @return array - */ - private function parseCookie($cookie) - { - $cookieArray = \explode(';', $cookie); - $result = array(); - - foreach ($cookieArray as $pair) { - $pair = \trim($pair); - $nameValuePair = \explode('=', $pair, 2); - - if (\count($nameValuePair) === 2) { - $key = \urldecode($nameValuePair[0]); - $value = \urldecode($nameValuePair[1]); - $result[$key] = $value; - } - } - - return $result; - } -} diff --git a/vendor/react/http/src/Middleware/LimitConcurrentRequestsMiddleware.php b/vendor/react/http/src/Middleware/LimitConcurrentRequestsMiddleware.php deleted file mode 100644 index 533381008..000000000 --- a/vendor/react/http/src/Middleware/LimitConcurrentRequestsMiddleware.php +++ /dev/null @@ -1,211 +0,0 @@ -limit = $limit; - } - - public function __invoke(ServerRequestInterface $request, $next) - { - // happy path: simply invoke next request handler if we're below limit - if ($this->pending < $this->limit) { - ++$this->pending; - - try { - $response = $next($request); - } catch (\Exception $e) { - $this->processQueue(); - throw $e; - } catch (\Throwable $e) { // @codeCoverageIgnoreStart - // handle Errors just like Exceptions (PHP 7+ only) - $this->processQueue(); - throw $e; // @codeCoverageIgnoreEnd - } - - // happy path: if next request handler returned immediately, - // we can simply try to invoke the next queued request - if ($response instanceof ResponseInterface) { - $this->processQueue(); - return $response; - } - - // if the next handler returns a pending promise, we have to - // await its resolution before invoking next queued request - return $this->await(Promise\resolve($response)); - } - - // if we reach this point, then this request will need to be queued - // check if the body is streaming, in which case we need to buffer everything - $body = $request->getBody(); - if ($body instanceof ReadableStreamInterface) { - // pause actual body to stop emitting data until the handler is called - $size = $body->getSize(); - $body = new PauseBufferStream($body); - $body->pauseImplicit(); - - // replace with buffering body to ensure any readable events will be buffered - $request = $request->withBody(new HttpBodyStream( - $body, - $size - )); - } - - // get next queue position - $queue =& $this->queue; - $queue[] = null; - \end($queue); - $id = \key($queue); - - $deferred = new Deferred(function ($_, $reject) use (&$queue, $id) { - // queued promise cancelled before its next handler is invoked - // remove from queue and reject explicitly - unset($queue[$id]); - $reject(new \RuntimeException('Cancelled queued next handler')); - }); - - // queue request and process queue if pending does not exceed limit - $queue[$id] = $deferred; - - $pending = &$this->pending; - $that = $this; - return $deferred->promise()->then(function () use ($request, $next, $body, &$pending, $that) { - // invoke next request handler - ++$pending; - - try { - $response = $next($request); - } catch (\Exception $e) { - $that->processQueue(); - throw $e; - } catch (\Throwable $e) { // @codeCoverageIgnoreStart - // handle Errors just like Exceptions (PHP 7+ only) - $that->processQueue(); - throw $e; // @codeCoverageIgnoreEnd - } - - // resume readable stream and replay buffered events - if ($body instanceof PauseBufferStream) { - $body->resumeImplicit(); - } - - // if the next handler returns a pending promise, we have to - // await its resolution before invoking next queued request - return $that->await(Promise\resolve($response)); - }); - } - - /** - * @internal - * @param PromiseInterface $promise - * @return PromiseInterface - */ - public function await(PromiseInterface $promise) - { - $that = $this; - - return $promise->then(function ($response) use ($that) { - $that->processQueue(); - - return $response; - }, function ($error) use ($that) { - $that->processQueue(); - - return Promise\reject($error); - }); - } - - /** - * @internal - */ - public function processQueue() - { - // skip if we're still above concurrency limit or there's no queued request waiting - if (--$this->pending >= $this->limit || !$this->queue) { - return; - } - - $first = \reset($this->queue); - unset($this->queue[key($this->queue)]); - - $first->resolve(); - } -} diff --git a/vendor/react/http/src/Middleware/RequestBodyBufferMiddleware.php b/vendor/react/http/src/Middleware/RequestBodyBufferMiddleware.php deleted file mode 100644 index c13a5dec5..000000000 --- a/vendor/react/http/src/Middleware/RequestBodyBufferMiddleware.php +++ /dev/null @@ -1,70 +0,0 @@ -sizeLimit = IniUtil::iniSizeToBytes($sizeLimit); - } - - public function __invoke(ServerRequestInterface $request, $stack) - { - $body = $request->getBody(); - $size = $body->getSize(); - - // happy path: skip if body is known to be empty (or is already buffered) - if ($size === 0 || !$body instanceof ReadableStreamInterface) { - // replace with empty body if body is streaming (or buffered size exceeds limit) - if ($body instanceof ReadableStreamInterface || $size > $this->sizeLimit) { - $request = $request->withBody(new BufferedBody('')); - } - - return $stack($request); - } - - // request body of known size exceeding limit - $sizeLimit = $this->sizeLimit; - if ($size > $this->sizeLimit) { - $sizeLimit = 0; - } - - return Stream\buffer($body, $sizeLimit)->then(function ($buffer) use ($request, $stack) { - $request = $request->withBody(new BufferedBody($buffer)); - - return $stack($request); - }, function ($error) use ($stack, $request, $body) { - // On buffer overflow keep the request body stream in, - // but ignore the contents and wait for the close event - // before passing the request on to the next middleware. - if ($error instanceof OverflowException) { - return Stream\first($body, 'close')->then(function () use ($stack, $request) { - return $stack($request); - }); - } - - throw $error; - }); - } -} diff --git a/vendor/react/http/src/Middleware/RequestBodyParserMiddleware.php b/vendor/react/http/src/Middleware/RequestBodyParserMiddleware.php deleted file mode 100644 index be5ba16ff..000000000 --- a/vendor/react/http/src/Middleware/RequestBodyParserMiddleware.php +++ /dev/null @@ -1,46 +0,0 @@ -multipart = new MultipartParser($uploadMaxFilesize, $maxFileUploads); - } - - public function __invoke(ServerRequestInterface $request, $next) - { - $type = \strtolower($request->getHeaderLine('Content-Type')); - list ($type) = \explode(';', $type); - - if ($type === 'application/x-www-form-urlencoded') { - return $next($this->parseFormUrlencoded($request)); - } - - if ($type === 'multipart/form-data') { - return $next($this->multipart->parse($request)); - } - - return $next($request); - } - - private function parseFormUrlencoded(ServerRequestInterface $request) - { - // parse string into array structure - // ignore warnings due to excessive data structures (max_input_vars and max_input_nesting_level) - $ret = array(); - @\parse_str((string)$request->getBody(), $ret); - - return $request->withParsedBody($ret); - } -} diff --git a/vendor/react/http/src/Middleware/StreamingRequestMiddleware.php b/vendor/react/http/src/Middleware/StreamingRequestMiddleware.php deleted file mode 100644 index 6ab74b715..000000000 --- a/vendor/react/http/src/Middleware/StreamingRequestMiddleware.php +++ /dev/null @@ -1,69 +0,0 @@ -getBody(); - * assert($body instanceof Psr\Http\Message\StreamInterface); - * assert($body instanceof React\Stream\ReadableStreamInterface); - * - * return new React\Promise\Promise(function ($resolve) use ($body) { - * $bytes = 0; - * $body->on('data', function ($chunk) use (&$bytes) { - * $bytes += \count($chunk); - * }); - * $body->on('close', function () use (&$bytes, $resolve) { - * $resolve(new React\Http\Response( - * 200, - * [], - * "Received $bytes bytes\n" - * )); - * }); - * }); - * } - * ); - * ``` - * - * See also [streaming incoming request](../../README.md#streaming-incoming-request) - * for more details. - * - * Additionally, this middleware can be used in combination with the - * [`LimitConcurrentRequestsMiddleware`](#limitconcurrentrequestsmiddleware) and - * [`RequestBodyBufferMiddleware`](#requestbodybuffermiddleware) (see below) - * to explicitly configure the total number of requests that can be handled at - * once: - * - * ```php - * $http = new React\Http\HttpServer( - * new React\Http\Middleware\StreamingRequestMiddleware(), - * new React\Http\Middleware\LimitConcurrentRequestsMiddleware(100), // 100 concurrent buffering handlers - * new React\Http\Middleware\RequestBodyBufferMiddleware(2 * 1024 * 1024), // 2 MiB per request - * new React\Http\Middleware\RequestBodyParserMiddleware(), - * $handler - * ); - * ``` - * - * > Internally, this class is used as a "marker" to not trigger the default - * request buffering behavior in the `HttpServer`. It does not implement any logic - * on its own. - */ -final class StreamingRequestMiddleware -{ - public function __invoke(ServerRequestInterface $request, $next) - { - return $next($request); - } -} diff --git a/vendor/react/http/src/Server.php b/vendor/react/http/src/Server.php deleted file mode 100644 index 9bb9cf7f5..000000000 --- a/vendor/react/http/src/Server.php +++ /dev/null @@ -1,18 +0,0 @@ - - */ - public function __construct(PromiseInterface $promise) - { - $out = $this; - $closed =& $this->closed; - - $this->promise = $promise->then( - function ($stream) { - if (!$stream instanceof ReadableStreamInterface) { - throw new InvalidArgumentException('Not a readable stream'); - } - return $stream; - } - )->then( - function (ReadableStreamInterface $stream) use ($out, &$closed) { - // stream is already closed, make sure to close output stream - if (!$stream->isReadable()) { - $out->close(); - return $stream; - } - - // resolves but output is already closed, make sure to close stream silently - if ($closed) { - $stream->close(); - return $stream; - } - - // stream any writes into output stream - $stream->on('data', function ($data) use ($out) { - $out->emit('data', array($data, $out)); - }); - - // forward end events and close - $stream->on('end', function () use ($out, &$closed) { - if (!$closed) { - $out->emit('end', array($out)); - $out->close(); - } - }); - - // error events cancel output stream - $stream->on('error', function ($error) use ($out) { - $out->emit('error', array($error, $out)); - $out->close(); - }); - - // close both streams once either side closes - $stream->on('close', array($out, 'close')); - $out->on('close', array($stream, 'close')); - - return $stream; - }, - function ($e) use ($out, &$closed) { - if (!$closed) { - $out->emit('error', array($e, $out)); - $out->close(); - } - - // resume() and pause() may attach to this promise, so ensure we actually reject here - throw $e; - } - ); - } - - public function isReadable() - { - return !$this->closed; - } - - public function pause() - { - if ($this->promise !== null) { - $this->promise->then(function (ReadableStreamInterface $stream) { - $stream->pause(); - }); - } - } - - public function resume() - { - if ($this->promise !== null) { - $this->promise->then(function (ReadableStreamInterface $stream) { - $stream->resume(); - }); - } - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - Util::pipe($this, $dest, $options); - - return $dest; - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->closed = true; - - // try to cancel promise once the stream closes - if ($this->promise instanceof CancellablePromiseInterface) { - $this->promise->cancel(); - } - $this->promise = null; - - $this->emit('close'); - $this->removeAllListeners(); - } -} diff --git a/vendor/react/promise-stream/src/UnwrapWritableStream.php b/vendor/react/promise-stream/src/UnwrapWritableStream.php deleted file mode 100644 index f19e706ee..000000000 --- a/vendor/react/promise-stream/src/UnwrapWritableStream.php +++ /dev/null @@ -1,164 +0,0 @@ - - */ - public function __construct(PromiseInterface $promise) - { - $out = $this; - $store =& $this->stream; - $buffer =& $this->buffer; - $ending =& $this->ending; - $closed =& $this->closed; - - $this->promise = $promise->then( - function ($stream) { - if (!$stream instanceof WritableStreamInterface) { - throw new InvalidArgumentException('Not a writable stream'); - } - return $stream; - } - )->then( - function (WritableStreamInterface $stream) use ($out, &$store, &$buffer, &$ending, &$closed) { - // stream is already closed, make sure to close output stream - if (!$stream->isWritable()) { - $out->close(); - return $stream; - } - - // resolves but output is already closed, make sure to close stream silently - if ($closed) { - $stream->close(); - return $stream; - } - - // forward drain events for back pressure - $stream->on('drain', function () use ($out) { - $out->emit('drain', array($out)); - }); - - // error events cancel output stream - $stream->on('error', function ($error) use ($out) { - $out->emit('error', array($error, $out)); - $out->close(); - }); - - // close both streams once either side closes - $stream->on('close', array($out, 'close')); - $out->on('close', array($stream, 'close')); - - if ($buffer) { - // flush buffer to stream and check if its buffer is not exceeded - $drained = true; - foreach ($buffer as $chunk) { - if (!$stream->write($chunk)) { - $drained = false; - } - } - $buffer = array(); - - if ($drained) { - // signal drain event, because the output stream previous signalled a full buffer - $out->emit('drain', array($out)); - } - } - - if ($ending) { - $stream->end(); - } else { - $store = $stream; - } - - return $stream; - }, - function ($e) use ($out, &$closed) { - if (!$closed) { - $out->emit('error', array($e, $out)); - $out->close(); - } - } - ); - } - - public function write($data) - { - if ($this->ending) { - return false; - } - - // forward to inner stream if possible - if ($this->stream !== null) { - return $this->stream->write($data); - } - - // append to buffer and signal the buffer is full - $this->buffer[] = $data; - return false; - } - - public function end($data = null) - { - if ($this->ending) { - return; - } - - $this->ending = true; - - // forward to inner stream if possible - if ($this->stream !== null) { - return $this->stream->end($data); - } - - // append to buffer - if ($data !== null) { - $this->buffer[] = $data; - } - } - - public function isWritable() - { - return !$this->ending; - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->buffer = array(); - $this->ending = true; - $this->closed = true; - - // try to cancel promise once the stream closes - if ($this->promise instanceof CancellablePromiseInterface) { - $this->promise->cancel(); - } - $this->promise = $this->stream = null; - - $this->emit('close'); - $this->removeAllListeners(); - } -} diff --git a/vendor/react/promise-stream/src/functions.php b/vendor/react/promise-stream/src/functions.php deleted file mode 100644 index da66de8ba..000000000 --- a/vendor/react/promise-stream/src/functions.php +++ /dev/null @@ -1,370 +0,0 @@ -then(function (string $contents) { - * var_dump(json_decode($contents)); - * }); - * ``` - * - * The promise will be fulfilled with a `string` of all data chunks concatenated once the stream closes. - * - * The promise will be fulfilled with an empty `string` if the stream is already closed. - * - * The promise will be rejected with a `RuntimeException` if the stream emits an error. - * - * The promise will be rejected with a `RuntimeException` if it is cancelled. - * - * The optional `$maxLength` argument defaults to no limit. In case the maximum - * length is given and the stream emits more data before the end, the promise - * will be rejected with an `OverflowException`. - * - * ```php - * $stream = accessSomeToLargeStream(); - * - * React\Promise\Stream\buffer($stream, 1024)->then(function ($contents) { - * var_dump(json_decode($contents)); - * }, function ($error) { - * // Reaching here when the stream buffer goes above the max size, - * // in this example that is 1024 bytes, - * // or when the stream emits an error. - * }); - * ``` - * - * @param ReadableStreamInterface $stream - * @param ?int $maxLength Maximum number of bytes to buffer or null for unlimited. - * @return PromiseInterface - */ -function buffer(ReadableStreamInterface $stream, $maxLength = null) -{ - // stream already ended => resolve with empty buffer - if (!$stream->isReadable()) { - return Promise\resolve(''); - } - - $buffer = ''; - - $promise = new Promise\Promise(function ($resolve, $reject) use ($stream, $maxLength, &$buffer, &$bufferer) { - $bufferer = function ($data) use (&$buffer, $reject, $maxLength) { - $buffer .= $data; - - if ($maxLength !== null && isset($buffer[$maxLength])) { - $reject(new \OverflowException('Buffer exceeded maximum length')); - } - }; - - $stream->on('data', $bufferer); - - $stream->on('error', function (\Exception $e) use ($reject) { - $reject(new \RuntimeException( - 'An error occured on the underlying stream while buffering: ' . $e->getMessage(), - $e->getCode(), - $e - )); - }); - - $stream->on('close', function () use ($resolve, &$buffer) { - $resolve($buffer); - }); - }, function ($_, $reject) { - $reject(new \RuntimeException('Cancelled buffering')); - }); - - return $promise->then(null, function (\Exception $error) use (&$buffer, $bufferer, $stream) { - // promise rejected => clear buffer and buffering - $buffer = ''; - $stream->removeListener('data', $bufferer); - - throw $error; - }); -} - -/** - * Create a `Promise` which will be fulfilled once the given event triggers for the first time. - * - * ```php - * $stream = accessSomeJsonStream(); - * - * React\Promise\Stream\first($stream)->then(function (string $chunk) { - * echo 'The first chunk arrived: ' . $chunk; - * }); - * ``` - * - * The promise will be fulfilled with a `mixed` value of whatever the first event - * emitted or `null` if the event does not pass any data. - * If you do not pass a custom event name, then it will wait for the first "data" - * event. - * For common streams of type `ReadableStreamInterface`, this means it will be - * fulfilled with a `string` containing the first data chunk. - * - * The promise will be rejected with a `RuntimeException` if the stream emits an error - * – unless you're waiting for the "error" event, in which case it will be fulfilled. - * - * The promise will be rejected with a `RuntimeException` once the stream closes - * – unless you're waiting for the "close" event, in which case it will be fulfilled. - * - * The promise will be rejected with a `RuntimeException` if the stream is already closed. - * - * The promise will be rejected with a `RuntimeException` if it is cancelled. - * - * @param ReadableStreamInterface|WritableStreamInterface $stream - * @param string $event - * @return PromiseInterface - */ -function first(EventEmitterInterface $stream, $event = 'data') -{ - if ($stream instanceof ReadableStreamInterface) { - // readable or duplex stream not readable => already closed - // a half-open duplex stream is considered closed if its readable side is closed - if (!$stream->isReadable()) { - return Promise\reject(new \RuntimeException('Stream already closed')); - } - } elseif ($stream instanceof WritableStreamInterface) { - // writable-only stream (not duplex) not writable => already closed - if (!$stream->isWritable()) { - return Promise\reject(new \RuntimeException('Stream already closed')); - } - } - - return new Promise\Promise(function ($resolve, $reject) use ($stream, $event, &$listener) { - $listener = function ($data = null) use ($stream, $event, &$listener, $resolve) { - $stream->removeListener($event, $listener); - $resolve($data); - }; - $stream->on($event, $listener); - - if ($event !== 'error') { - $stream->on('error', function (\Exception $e) use ($stream, $event, $listener, $reject) { - $stream->removeListener($event, $listener); - $reject(new \RuntimeException( - 'An error occured on the underlying stream while waiting for event: ' . $e->getMessage(), - $e->getCode(), - $e - )); - }); - } - - $stream->on('close', function () use ($stream, $event, $listener, $reject) { - $stream->removeListener($event, $listener); - $reject(new \RuntimeException('Stream closed')); - }); - }, function ($_, $reject) use ($stream, $event, &$listener) { - $stream->removeListener($event, $listener); - $reject(new \RuntimeException('Operation cancelled')); - }); -} - -/** - * Create a `Promise` which will be fulfilled with an array of all the event data. - * - * ```php - * $stream = accessSomeJsonStream(); - * - * React\Promise\Stream\all($stream)->then(function (array $chunks) { - * echo 'The stream consists of ' . count($chunks) . ' chunk(s)'; - * }); - * ``` - * - * The promise will be fulfilled with an `array` once the stream closes. The array - * will contain whatever all events emitted or `null` values if the events do not pass any data. - * If you do not pass a custom event name, then it will wait for all the "data" - * events. - * For common streams of type `ReadableStreamInterface`, this means it will be - * fulfilled with a `string[]` array containing all the data chunk. - * - * The promise will be fulfilled with an empty `array` if the stream is already closed. - * - * The promise will be rejected with a `RuntimeException` if the stream emits an error. - * - * The promise will be rejected with a `RuntimeException` if it is cancelled. - * - * @param ReadableStreamInterface|WritableStreamInterface $stream - * @param string $event - * @return PromiseInterface - */ -function all(EventEmitterInterface $stream, $event = 'data') -{ - // stream already ended => resolve with empty buffer - if ($stream instanceof ReadableStreamInterface) { - // readable or duplex stream not readable => already closed - // a half-open duplex stream is considered closed if its readable side is closed - if (!$stream->isReadable()) { - return Promise\resolve(array()); - } - } elseif ($stream instanceof WritableStreamInterface) { - // writable-only stream (not duplex) not writable => already closed - if (!$stream->isWritable()) { - return Promise\resolve(array()); - } - } - - $buffer = array(); - $bufferer = function ($data = null) use (&$buffer) { - $buffer []= $data; - }; - $stream->on($event, $bufferer); - - $promise = new Promise\Promise(function ($resolve, $reject) use ($stream, &$buffer) { - $stream->on('error', function (\Exception $e) use ($reject) { - $reject(new \RuntimeException( - 'An error occured on the underlying stream while buffering: ' . $e->getMessage(), - $e->getCode(), - $e - )); - }); - - $stream->on('close', function () use ($resolve, &$buffer) { - $resolve($buffer); - }); - }, function ($_, $reject) { - $reject(new \RuntimeException('Cancelled buffering')); - }); - - return $promise->then(null, function ($error) use (&$buffer, $bufferer, $stream, $event) { - // promise rejected => clear buffer and buffering - $buffer = array(); - $stream->removeListener($event, $bufferer); - - throw $error; - }); -} - -/** - * Unwrap a `Promise` which will be fulfilled with a `ReadableStreamInterface`. - * - * This function returns a readable stream instance (implementing `ReadableStreamInterface`) - * right away which acts as a proxy for the future promise resolution. - * Once the given Promise will be fulfilled with a `ReadableStreamInterface`, its - * data will be piped to the output stream. - * - * ```php - * //$promise = someFunctionWhichResolvesWithAStream(); - * $promise = startDownloadStream($uri); - * - * $stream = React\Promise\Stream\unwrapReadable($promise); - * - * $stream->on('data', function (string $data) { - * echo $data; - * }); - * - * $stream->on('end', function () { - * echo 'DONE'; - * }); - * ``` - * - * If the given promise is either rejected or fulfilled with anything but an - * instance of `ReadableStreamInterface`, then the output stream will emit - * an `error` event and close: - * - * ```php - * $promise = startDownloadStream($invalidUri); - * - * $stream = React\Promise\Stream\unwrapReadable($promise); - * - * $stream->on('error', function (Exception $error) { - * echo 'Error: ' . $error->getMessage(); - * }); - * ``` - * - * The given `$promise` SHOULD be pending, i.e. it SHOULD NOT be fulfilled or rejected - * at the time of invoking this function. - * If the given promise is already settled and does not fulfill with an instance of - * `ReadableStreamInterface`, then you will not be able to receive the `error` event. - * - * You can `close()` the resulting stream at any time, which will either try to - * `cancel()` the pending promise or try to `close()` the underlying stream. - * - * ```php - * $promise = startDownloadStream($uri); - * - * $stream = React\Promise\Stream\unwrapReadable($promise); - * - * $loop->addTimer(2.0, function () use ($stream) { - * $stream->close(); - * }); - * ``` - * - * @param PromiseInterface,\Exception> $promise - * @return ReadableStreamInterface - */ -function unwrapReadable(PromiseInterface $promise) -{ - return new UnwrapReadableStream($promise); -} - -/** - * unwrap a `Promise` which will be fulfilled with a `WritableStreamInterface`. - * - * This function returns a writable stream instance (implementing `WritableStreamInterface`) - * right away which acts as a proxy for the future promise resolution. - * Any writes to this instance will be buffered in memory for when the promise will - * be fulfilled. - * Once the given Promise will be fulfilled with a `WritableStreamInterface`, any - * data you have written to the proxy will be forwarded transparently to the inner - * stream. - * - * ```php - * //$promise = someFunctionWhichResolvesWithAStream(); - * $promise = startUploadStream($uri); - * - * $stream = React\Promise\Stream\unwrapWritable($promise); - * - * $stream->write('hello'); - * $stream->end('world'); - * - * $stream->on('close', function () { - * echo 'DONE'; - * }); - * ``` - * - * If the given promise is either rejected or fulfilled with anything but an - * instance of `WritableStreamInterface`, then the output stream will emit - * an `error` event and close: - * - * ```php - * $promise = startUploadStream($invalidUri); - * - * $stream = React\Promise\Stream\unwrapWritable($promise); - * - * $stream->on('error', function (Exception $error) { - * echo 'Error: ' . $error->getMessage(); - * }); - * ``` - * - * The given `$promise` SHOULD be pending, i.e. it SHOULD NOT be fulfilled or rejected - * at the time of invoking this function. - * If the given promise is already settled and does not fulfill with an instance of - * `WritableStreamInterface`, then you will not be able to receive the `error` event. - * - * You can `close()` the resulting stream at any time, which will either try to - * `cancel()` the pending promise or try to `close()` the underlying stream. - * - * ```php - * $promise = startUploadStream($uri); - * - * $stream = React\Promise\Stream\unwrapWritable($promise); - * - * $loop->addTimer(2.0, function () use ($stream) { - * $stream->close(); - * }); - * ``` - * - * @param PromiseInterface,\Exception> $promise - * @return WritableStreamInterface - */ -function unwrapWritable(PromiseInterface $promise) -{ - return new UnwrapWritableStream($promise); -} diff --git a/vendor/react/promise-stream/src/functions_include.php b/vendor/react/promise-stream/src/functions_include.php deleted file mode 100644 index 768a4fdbe..000000000 --- a/vendor/react/promise-stream/src/functions_include.php +++ /dev/null @@ -1,7 +0,0 @@ -timeout = (float) $timeout; - } - - /** - * Get the timeout value in seconds. - * - * @return float - */ - public function getTimeout() - { - return $this->timeout; - } -} diff --git a/vendor/react/promise-timer/src/functions.php b/vendor/react/promise-timer/src/functions.php deleted file mode 100644 index 43665b2b9..000000000 --- a/vendor/react/promise-timer/src/functions.php +++ /dev/null @@ -1,335 +0,0 @@ -then(function ($value) { - * // the operation finished within 10.0 seconds - * }); - * ``` - * - * A more complete example could look like this: - * - * ```php - * $promise = accessSomeRemoteResource(); - * React\Promise\Timer\timeout($promise, 10.0)->then( - * function ($value) { - * // the operation finished within 10.0 seconds - * }, - * function ($error) { - * if ($error instanceof React\Promise\Timer\TimeoutException) { - * // the operation has failed due to a timeout - * } else { - * // the input operation has failed due to some other error - * } - * } - * ); - * ``` - * - * Or if you're using [react/promise v2.2.0](https://github.com/reactphp/promise) or up: - * - * ```php - * React\Promise\Timer\timeout($promise, 10.0) - * ->then(function ($value) { - * // the operation finished within 10.0 seconds - * }) - * ->otherwise(function (React\Promise\Timer\TimeoutException $error) { - * // the operation has failed due to a timeout - * }) - * ->otherwise(function ($error) { - * // the input operation has failed due to some other error - * }) - * ; - * ``` - * - * As discussed above, the [`timeout()`](#timeout) function will take care of - * the underlying operation if it takes *too long*. In this case, you can be - * sure the resulting promise will always be rejected with a - * [`TimeoutException`](#timeoutexception). On top of this, the function will - * try to *cancel* the underlying operation. Responsibility for this - * cancellation logic is left up to the underlying operation. - * - * - A common use case involves cleaning up any resources like open network - * sockets or file handles or terminating external processes or timers. - * - * - If the given input `$promise` does not support cancellation, then this is a - * NO-OP. This means that while the resulting promise will still be rejected, - * the underlying input `$promise` may still be pending and can hence continue - * consuming resources - * - * On top of this, the returned promise is implemented in such a way that it can - * be cancelled when it is still pending. Cancelling a pending promise will - * cancel the underlying operation. As discussed above, responsibility for this - * cancellation logic is left up to the underlying operation. - * - * ```php - * $promise = accessSomeRemoteResource(); - * $timeout = React\Promise\Timer\timeout($promise, 10.0); - * - * $timeout->cancel(); - * ``` - * - * For more details on the promise cancellation, please refer to the - * [Promise documentation](https://github.com/reactphp/promise#cancellablepromiseinterface). - * - * If you want to wait for multiple promises to resolve, you can use the normal - * promise primitives like this: - * - * ```php - * $promises = array( - * accessSomeRemoteResource(), - * accessSomeRemoteResource(), - * accessSomeRemoteResource() - * ); - * - * $promise = React\Promise\all($promises); - * - * React\Promise\Timer\timeout($promise, 10)->then(function ($values) { - * // *all* promises resolved - * }); - * ``` - * - * The applies to all promise collection primitives alike, i.e. `all()`, - * `race()`, `any()`, `some()` etc. - * - * For more details on the promise primitives, please refer to the - * [Promise documentation](https://github.com/reactphp/promise#functions). - * - * @param PromiseInterface $promise - * @param float $time - * @param ?LoopInterface $loop - * @return PromiseInterface - */ -function timeout(PromiseInterface $promise, $time, LoopInterface $loop = null) -{ - // cancelling this promise will only try to cancel the input promise, - // thus leaving responsibility to the input promise. - $canceller = null; - if ($promise instanceof CancellablePromiseInterface || (!\interface_exists('React\Promise\CancellablePromiseInterface') && \method_exists($promise, 'cancel'))) { - // pass promise by reference to clean reference after cancellation handler - // has been invoked once in order to avoid garbage references in call stack. - $canceller = function () use (&$promise) { - $promise->cancel(); - $promise = null; - }; - } - - if ($loop === null) { - $loop = Loop::get(); - } - - return new Promise(function ($resolve, $reject) use ($loop, $time, $promise) { - $timer = null; - $promise = $promise->then(function ($v) use (&$timer, $loop, $resolve) { - if ($timer) { - $loop->cancelTimer($timer); - } - $timer = false; - $resolve($v); - }, function ($v) use (&$timer, $loop, $reject) { - if ($timer) { - $loop->cancelTimer($timer); - } - $timer = false; - $reject($v); - }); - - // promise already resolved => no need to start timer - if ($timer === false) { - return; - } - - // start timeout timer which will cancel the input promise - $timer = $loop->addTimer($time, function () use ($time, &$promise, $reject) { - $reject(new TimeoutException($time, 'Timed out after ' . $time . ' seconds')); - - // try to invoke cancellation handler of input promise and then clean - // reference in order to avoid garbage references in call stack. - if ($promise instanceof CancellablePromiseInterface || (!\interface_exists('React\Promise\CancellablePromiseInterface') && \method_exists($promise, 'cancel'))) { - $promise->cancel(); - } - $promise = null; - }); - }, $canceller); -} - -/** - * Create a new promise that resolves in `$time` seconds. - * - * ```php - * React\Promise\Timer\sleep(1.5)->then(function () { - * echo 'Thanks for waiting!' . PHP_EOL; - * }); - * ``` - * - * Internally, the given `$time` value will be used to start a timer that will - * resolve the promise once it triggers. This implies that if you pass a really - * small (or negative) value, it will still start a timer and will thus trigger - * at the earliest possible time in the future. - * - * This function takes an optional `LoopInterface|null $loop` parameter that can be used to - * pass the event loop instance to use. You can use a `null` value here in order to - * use the [default loop](https://github.com/reactphp/event-loop#loop). This value - * SHOULD NOT be given unless you're sure you want to explicitly use a given event - * loop instance. - * - * The returned promise is implemented in such a way that it can be cancelled - * when it is still pending. Cancelling a pending promise will reject its value - * with a `RuntimeException` and clean up any pending timers. - * - * ```php - * $timer = React\Promise\Timer\sleep(2.0); - * - * $timer->cancel(); - * ``` - * - * @param float $time - * @param ?LoopInterface $loop - * @return PromiseInterface - */ -function sleep($time, LoopInterface $loop = null) -{ - if ($loop === null) { - $loop = Loop::get(); - } - - $timer = null; - return new Promise(function ($resolve) use ($loop, $time, &$timer) { - // resolve the promise when the timer fires in $time seconds - $timer = $loop->addTimer($time, function () use ($resolve) { - $resolve(); - }); - }, function () use (&$timer, $loop) { - // cancelling this promise will cancel the timer, clean the reference - // in order to avoid garbage references in call stack and then reject. - $loop->cancelTimer($timer); - $timer = null; - - throw new \RuntimeException('Timer cancelled'); - }); -} - -/** - * [Deprecated] Create a new promise that resolves in `$time` seconds with the `$time` as the fulfillment value. - * - * ```php - * React\Promise\Timer\resolve(1.5)->then(function ($time) { - * echo 'Thanks for waiting ' . $time . ' seconds' . PHP_EOL; - * }); - * ``` - * - * Internally, the given `$time` value will be used to start a timer that will - * resolve the promise once it triggers. This implies that if you pass a really - * small (or negative) value, it will still start a timer and will thus trigger - * at the earliest possible time in the future. - * - * This function takes an optional `LoopInterface|null $loop` parameter that can be used to - * pass the event loop instance to use. You can use a `null` value here in order to - * use the [default loop](https://github.com/reactphp/event-loop#loop). This value - * SHOULD NOT be given unless you're sure you want to explicitly use a given event - * loop instance. - * - * The returned promise is implemented in such a way that it can be cancelled - * when it is still pending. Cancelling a pending promise will reject its value - * with a `RuntimeException` and clean up any pending timers. - * - * ```php - * $timer = React\Promise\Timer\resolve(2.0); - * - * $timer->cancel(); - * ``` - * - * @param float $time - * @param ?LoopInterface $loop - * @return PromiseInterface - * @deprecated 1.8.0 See `sleep()` instead - * @see sleep() - */ -function resolve($time, LoopInterface $loop = null) -{ - return sleep($time, $loop)->then(function() use ($time) { - return $time; - }); -} - -/** - * [Deprecated] Create a new promise which rejects in `$time` seconds with a `TimeoutException`. - * - * ```php - * React\Promise\Timer\reject(2.0)->then(null, function (React\Promise\Timer\TimeoutException $e) { - * echo 'Rejected after ' . $e->getTimeout() . ' seconds ' . PHP_EOL; - * }); - * ``` - * - * Internally, the given `$time` value will be used to start a timer that will - * reject the promise once it triggers. This implies that if you pass a really - * small (or negative) value, it will still start a timer and will thus trigger - * at the earliest possible time in the future. - * - * This function takes an optional `LoopInterface|null $loop` parameter that can be used to - * pass the event loop instance to use. You can use a `null` value here in order to - * use the [default loop](https://github.com/reactphp/event-loop#loop). This value - * SHOULD NOT be given unless you're sure you want to explicitly use a given event - * loop instance. - * - * The returned promise is implemented in such a way that it can be cancelled - * when it is still pending. Cancelling a pending promise will reject its value - * with a `RuntimeException` and clean up any pending timers. - * - * ```php - * $timer = React\Promise\Timer\reject(2.0); - * - * $timer->cancel(); - * ``` - * - * @param float $time - * @param LoopInterface $loop - * @return PromiseInterface - * @deprecated 1.8.0 See `sleep()` instead - * @see sleep() - */ -function reject($time, LoopInterface $loop = null) -{ - return sleep($time, $loop)->then(function () use ($time) { - throw new TimeoutException($time, 'Timer expired after ' . $time . ' seconds'); - }); -} diff --git a/vendor/react/promise-timer/src/functions_include.php b/vendor/react/promise-timer/src/functions_include.php deleted file mode 100644 index 1d5673aed..000000000 --- a/vendor/react/promise-timer/src/functions_include.php +++ /dev/null @@ -1,7 +0,0 @@ -started) { - return; - } - - $this->started = true; - $this->drain(); - } - - public function enqueue($cancellable) - { - if (!\is_object($cancellable) || !\method_exists($cancellable, 'then') || !\method_exists($cancellable, 'cancel')) { - return; - } - - $length = \array_push($this->queue, $cancellable); - - if ($this->started && 1 === $length) { - $this->drain(); - } - } - - private function drain() - { - for ($i = key($this->queue); isset($this->queue[$i]); $i++) { - $cancellable = $this->queue[$i]; - - $exception = null; - - try { - $cancellable->cancel(); - } catch (\Throwable $exception) { - } catch (\Exception $exception) { - } - - unset($this->queue[$i]); - - if ($exception) { - throw $exception; - } - } - - $this->queue = []; - } -} diff --git a/vendor/react/promise/src/Deferred.php b/vendor/react/promise/src/Deferred.php deleted file mode 100644 index 3ca034b85..000000000 --- a/vendor/react/promise/src/Deferred.php +++ /dev/null @@ -1,65 +0,0 @@ -canceller = $canceller; - } - - public function promise() - { - if (null === $this->promise) { - $this->promise = new Promise(function ($resolve, $reject, $notify) { - $this->resolveCallback = $resolve; - $this->rejectCallback = $reject; - $this->notifyCallback = $notify; - }, $this->canceller); - $this->canceller = null; - } - - return $this->promise; - } - - public function resolve($value = null) - { - $this->promise(); - - \call_user_func($this->resolveCallback, $value); - } - - public function reject($reason = null) - { - $this->promise(); - - \call_user_func($this->rejectCallback, $reason); - } - - /** - * @deprecated 2.6.0 Progress support is deprecated and should not be used anymore. - * @param mixed $update - */ - public function notify($update = null) - { - $this->promise(); - - \call_user_func($this->notifyCallback, $update); - } - - /** - * @deprecated 2.2.0 - * @see Deferred::notify() - */ - public function progress($update = null) - { - $this->notify($update); - } -} diff --git a/vendor/react/promise/src/Exception/LengthException.php b/vendor/react/promise/src/Exception/LengthException.php deleted file mode 100644 index 775c48db6..000000000 --- a/vendor/react/promise/src/Exception/LengthException.php +++ /dev/null @@ -1,7 +0,0 @@ -then(null, $onRejected); - * ``` - * - * Additionally, you can type hint the `$reason` argument of `$onRejected` to catch - * only specific errors. - * - * @param callable $onRejected - * @return ExtendedPromiseInterface - */ - public function otherwise(callable $onRejected); - - /** - * Allows you to execute "cleanup" type tasks in a promise chain. - * - * It arranges for `$onFulfilledOrRejected` to be called, with no arguments, - * when the promise is either fulfilled or rejected. - * - * * If `$promise` fulfills, and `$onFulfilledOrRejected` returns successfully, - * `$newPromise` will fulfill with the same value as `$promise`. - * * If `$promise` fulfills, and `$onFulfilledOrRejected` throws or returns a - * rejected promise, `$newPromise` will reject with the thrown exception or - * rejected promise's reason. - * * If `$promise` rejects, and `$onFulfilledOrRejected` returns successfully, - * `$newPromise` will reject with the same reason as `$promise`. - * * If `$promise` rejects, and `$onFulfilledOrRejected` throws or returns a - * rejected promise, `$newPromise` will reject with the thrown exception or - * rejected promise's reason. - * - * `always()` behaves similarly to the synchronous finally statement. When combined - * with `otherwise()`, `always()` allows you to write code that is similar to the familiar - * synchronous catch/finally pair. - * - * Consider the following synchronous code: - * - * ```php - * try { - * return doSomething(); - * } catch(\Exception $e) { - * return handleError($e); - * } finally { - * cleanup(); - * } - * ``` - * - * Similar asynchronous code (with `doSomething()` that returns a promise) can be - * written: - * - * ```php - * return doSomething() - * ->otherwise('handleError') - * ->always('cleanup'); - * ``` - * - * @param callable $onFulfilledOrRejected - * @return ExtendedPromiseInterface - */ - public function always(callable $onFulfilledOrRejected); - - /** - * Registers a handler for progress updates from promise. It is a shortcut for: - * - * ```php - * $promise->then(null, null, $onProgress); - * ``` - * - * @param callable $onProgress - * @return ExtendedPromiseInterface - * @deprecated 2.6.0 Progress support is deprecated and should not be used anymore. - */ - public function progress(callable $onProgress); -} diff --git a/vendor/react/promise/src/FulfilledPromise.php b/vendor/react/promise/src/FulfilledPromise.php deleted file mode 100644 index 147275277..000000000 --- a/vendor/react/promise/src/FulfilledPromise.php +++ /dev/null @@ -1,71 +0,0 @@ -value = $value; - } - - public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) - { - if (null === $onFulfilled) { - return $this; - } - - try { - return resolve($onFulfilled($this->value)); - } catch (\Throwable $exception) { - return new RejectedPromise($exception); - } catch (\Exception $exception) { - return new RejectedPromise($exception); - } - } - - public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) - { - if (null === $onFulfilled) { - return; - } - - $result = $onFulfilled($this->value); - - if ($result instanceof ExtendedPromiseInterface) { - $result->done(); - } - } - - public function otherwise(callable $onRejected) - { - return $this; - } - - public function always(callable $onFulfilledOrRejected) - { - return $this->then(function ($value) use ($onFulfilledOrRejected) { - return resolve($onFulfilledOrRejected())->then(function () use ($value) { - return $value; - }); - }); - } - - public function progress(callable $onProgress) - { - return $this; - } - - public function cancel() - { - } -} diff --git a/vendor/react/promise/src/LazyPromise.php b/vendor/react/promise/src/LazyPromise.php deleted file mode 100644 index bbe9293e1..000000000 --- a/vendor/react/promise/src/LazyPromise.php +++ /dev/null @@ -1,66 +0,0 @@ -factory = $factory; - } - - public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) - { - return $this->promise()->then($onFulfilled, $onRejected, $onProgress); - } - - public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) - { - return $this->promise()->done($onFulfilled, $onRejected, $onProgress); - } - - public function otherwise(callable $onRejected) - { - return $this->promise()->otherwise($onRejected); - } - - public function always(callable $onFulfilledOrRejected) - { - return $this->promise()->always($onFulfilledOrRejected); - } - - public function progress(callable $onProgress) - { - return $this->promise()->progress($onProgress); - } - - public function cancel() - { - return $this->promise()->cancel(); - } - - /** - * @internal - * @see Promise::settle() - */ - public function promise() - { - if (null === $this->promise) { - try { - $this->promise = resolve(\call_user_func($this->factory)); - } catch (\Throwable $exception) { - $this->promise = new RejectedPromise($exception); - } catch (\Exception $exception) { - $this->promise = new RejectedPromise($exception); - } - } - - return $this->promise; - } -} diff --git a/vendor/react/promise/src/Promise.php b/vendor/react/promise/src/Promise.php deleted file mode 100644 index 33759e6fe..000000000 --- a/vendor/react/promise/src/Promise.php +++ /dev/null @@ -1,256 +0,0 @@ -canceller = $canceller; - - // Explicitly overwrite arguments with null values before invoking - // resolver function. This ensure that these arguments do not show up - // in the stack trace in PHP 7+ only. - $cb = $resolver; - $resolver = $canceller = null; - $this->call($cb); - } - - public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) - { - if (null !== $this->result) { - return $this->result->then($onFulfilled, $onRejected, $onProgress); - } - - if (null === $this->canceller) { - return new static($this->resolver($onFulfilled, $onRejected, $onProgress)); - } - - // This promise has a canceller, so we create a new child promise which - // has a canceller that invokes the parent canceller if all other - // followers are also cancelled. We keep a reference to this promise - // instance for the static canceller function and clear this to avoid - // keeping a cyclic reference between parent and follower. - $parent = $this; - ++$parent->requiredCancelRequests; - - return new static( - $this->resolver($onFulfilled, $onRejected, $onProgress), - static function () use (&$parent) { - if (++$parent->cancelRequests >= $parent->requiredCancelRequests) { - $parent->cancel(); - } - - $parent = null; - } - ); - } - - public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) - { - if (null !== $this->result) { - return $this->result->done($onFulfilled, $onRejected, $onProgress); - } - - $this->handlers[] = static function (ExtendedPromiseInterface $promise) use ($onFulfilled, $onRejected) { - $promise - ->done($onFulfilled, $onRejected); - }; - - if ($onProgress) { - $this->progressHandlers[] = $onProgress; - } - } - - public function otherwise(callable $onRejected) - { - return $this->then(null, static function ($reason) use ($onRejected) { - if (!_checkTypehint($onRejected, $reason)) { - return new RejectedPromise($reason); - } - - return $onRejected($reason); - }); - } - - public function always(callable $onFulfilledOrRejected) - { - return $this->then(static function ($value) use ($onFulfilledOrRejected) { - return resolve($onFulfilledOrRejected())->then(function () use ($value) { - return $value; - }); - }, static function ($reason) use ($onFulfilledOrRejected) { - return resolve($onFulfilledOrRejected())->then(function () use ($reason) { - return new RejectedPromise($reason); - }); - }); - } - - public function progress(callable $onProgress) - { - return $this->then(null, null, $onProgress); - } - - public function cancel() - { - if (null === $this->canceller || null !== $this->result) { - return; - } - - $canceller = $this->canceller; - $this->canceller = null; - - $this->call($canceller); - } - - private function resolver(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) - { - return function ($resolve, $reject, $notify) use ($onFulfilled, $onRejected, $onProgress) { - if ($onProgress) { - $progressHandler = static function ($update) use ($notify, $onProgress) { - try { - $notify($onProgress($update)); - } catch (\Throwable $e) { - $notify($e); - } catch (\Exception $e) { - $notify($e); - } - }; - } else { - $progressHandler = $notify; - } - - $this->handlers[] = static function (ExtendedPromiseInterface $promise) use ($onFulfilled, $onRejected, $resolve, $reject, $progressHandler) { - $promise - ->then($onFulfilled, $onRejected) - ->done($resolve, $reject, $progressHandler); - }; - - $this->progressHandlers[] = $progressHandler; - }; - } - - private function reject($reason = null) - { - if (null !== $this->result) { - return; - } - - $this->settle(reject($reason)); - } - - private function settle(ExtendedPromiseInterface $promise) - { - $promise = $this->unwrap($promise); - - if ($promise === $this) { - $promise = new RejectedPromise( - new \LogicException('Cannot resolve a promise with itself.') - ); - } - - $handlers = $this->handlers; - - $this->progressHandlers = $this->handlers = []; - $this->result = $promise; - $this->canceller = null; - - foreach ($handlers as $handler) { - $handler($promise); - } - } - - private function unwrap($promise) - { - $promise = $this->extract($promise); - - while ($promise instanceof self && null !== $promise->result) { - $promise = $this->extract($promise->result); - } - - return $promise; - } - - private function extract($promise) - { - if ($promise instanceof LazyPromise) { - $promise = $promise->promise(); - } - - return $promise; - } - - private function call(callable $cb) - { - // Explicitly overwrite argument with null value. This ensure that this - // argument does not show up in the stack trace in PHP 7+ only. - $callback = $cb; - $cb = null; - - // Use reflection to inspect number of arguments expected by this callback. - // We did some careful benchmarking here: Using reflection to avoid unneeded - // function arguments is actually faster than blindly passing them. - // Also, this helps avoiding unnecessary function arguments in the call stack - // if the callback creates an Exception (creating garbage cycles). - if (\is_array($callback)) { - $ref = new \ReflectionMethod($callback[0], $callback[1]); - } elseif (\is_object($callback) && !$callback instanceof \Closure) { - $ref = new \ReflectionMethod($callback, '__invoke'); - } else { - $ref = new \ReflectionFunction($callback); - } - $args = $ref->getNumberOfParameters(); - - try { - if ($args === 0) { - $callback(); - } else { - // Keep references to this promise instance for the static resolve/reject functions. - // By using static callbacks that are not bound to this instance - // and passing the target promise instance by reference, we can - // still execute its resolving logic and still clear this - // reference when settling the promise. This helps avoiding - // garbage cycles if any callback creates an Exception. - // These assumptions are covered by the test suite, so if you ever feel like - // refactoring this, go ahead, any alternative suggestions are welcome! - $target =& $this; - $progressHandlers =& $this->progressHandlers; - - $callback( - static function ($value = null) use (&$target) { - if ($target !== null) { - $target->settle(resolve($value)); - $target = null; - } - }, - static function ($reason = null) use (&$target) { - if ($target !== null) { - $target->reject($reason); - $target = null; - } - }, - static function ($update = null) use (&$progressHandlers) { - foreach ($progressHandlers as $handler) { - $handler($update); - } - } - ); - } - } catch (\Throwable $e) { - $target = null; - $this->reject($e); - } catch (\Exception $e) { - $target = null; - $this->reject($e); - } - } -} diff --git a/vendor/react/promise/src/PromiseInterface.php b/vendor/react/promise/src/PromiseInterface.php deleted file mode 100644 index edcb00770..000000000 --- a/vendor/react/promise/src/PromiseInterface.php +++ /dev/null @@ -1,41 +0,0 @@ -reason = $reason; - } - - public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) - { - if (null === $onRejected) { - return $this; - } - - try { - return resolve($onRejected($this->reason)); - } catch (\Throwable $exception) { - return new RejectedPromise($exception); - } catch (\Exception $exception) { - return new RejectedPromise($exception); - } - } - - public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) - { - if (null === $onRejected) { - throw UnhandledRejectionException::resolve($this->reason); - } - - $result = $onRejected($this->reason); - - if ($result instanceof self) { - throw UnhandledRejectionException::resolve($result->reason); - } - - if ($result instanceof ExtendedPromiseInterface) { - $result->done(); - } - } - - public function otherwise(callable $onRejected) - { - if (!_checkTypehint($onRejected, $this->reason)) { - return $this; - } - - return $this->then(null, $onRejected); - } - - public function always(callable $onFulfilledOrRejected) - { - return $this->then(null, function ($reason) use ($onFulfilledOrRejected) { - return resolve($onFulfilledOrRejected())->then(function () use ($reason) { - return new RejectedPromise($reason); - }); - }); - } - - public function progress(callable $onProgress) - { - return $this; - } - - public function cancel() - { - } -} diff --git a/vendor/react/promise/src/UnhandledRejectionException.php b/vendor/react/promise/src/UnhandledRejectionException.php deleted file mode 100644 index e7fe2f7a8..000000000 --- a/vendor/react/promise/src/UnhandledRejectionException.php +++ /dev/null @@ -1,31 +0,0 @@ -reason = $reason; - - $message = \sprintf('Unhandled Rejection: %s', \json_encode($reason)); - - parent::__construct($message, 0); - } - - public function getReason() - { - return $this->reason; - } -} diff --git a/vendor/react/promise/src/functions.php b/vendor/react/promise/src/functions.php deleted file mode 100644 index 429f0e733..000000000 --- a/vendor/react/promise/src/functions.php +++ /dev/null @@ -1,407 +0,0 @@ -then($resolve, $reject, $notify); - }, $canceller); - } - - return new FulfilledPromise($promiseOrValue); -} - -/** - * Creates a rejected promise for the supplied `$promiseOrValue`. - * - * If `$promiseOrValue` is a value, it will be the rejection value of the - * returned promise. - * - * If `$promiseOrValue` is a promise, its completion value will be the rejected - * value of the returned promise. - * - * This can be useful in situations where you need to reject a promise without - * throwing an exception. For example, it allows you to propagate a rejection with - * the value of another promise. - * - * @param mixed $promiseOrValue - * @return PromiseInterface - */ -function reject($promiseOrValue = null) -{ - if ($promiseOrValue instanceof PromiseInterface) { - return resolve($promiseOrValue)->then(function ($value) { - return new RejectedPromise($value); - }); - } - - return new RejectedPromise($promiseOrValue); -} - -/** - * Returns a promise that will resolve only once all the items in - * `$promisesOrValues` have resolved. The resolution value of the returned promise - * will be an array containing the resolution values of each of the items in - * `$promisesOrValues`. - * - * @param array $promisesOrValues - * @return PromiseInterface - */ -function all($promisesOrValues) -{ - return map($promisesOrValues, function ($val) { - return $val; - }); -} - -/** - * Initiates a competitive race that allows one winner. Returns a promise which is - * resolved in the same way the first settled promise resolves. - * - * The returned promise will become **infinitely pending** if `$promisesOrValues` - * contains 0 items. - * - * @param array $promisesOrValues - * @return PromiseInterface - */ -function race($promisesOrValues) -{ - $cancellationQueue = new CancellationQueue(); - $cancellationQueue->enqueue($promisesOrValues); - - return new Promise(function ($resolve, $reject, $notify) use ($promisesOrValues, $cancellationQueue) { - resolve($promisesOrValues) - ->done(function ($array) use ($cancellationQueue, $resolve, $reject, $notify) { - if (!is_array($array) || !$array) { - $resolve(); - return; - } - - foreach ($array as $promiseOrValue) { - $cancellationQueue->enqueue($promiseOrValue); - - resolve($promiseOrValue) - ->done($resolve, $reject, $notify); - } - }, $reject, $notify); - }, $cancellationQueue); -} - -/** - * Returns a promise that will resolve when any one of the items in - * `$promisesOrValues` resolves. The resolution value of the returned promise - * will be the resolution value of the triggering item. - * - * The returned promise will only reject if *all* items in `$promisesOrValues` are - * rejected. The rejection value will be an array of all rejection reasons. - * - * The returned promise will also reject with a `React\Promise\Exception\LengthException` - * if `$promisesOrValues` contains 0 items. - * - * @param array $promisesOrValues - * @return PromiseInterface - */ -function any($promisesOrValues) -{ - return some($promisesOrValues, 1) - ->then(function ($val) { - return \array_shift($val); - }); -} - -/** - * Returns a promise that will resolve when `$howMany` of the supplied items in - * `$promisesOrValues` resolve. The resolution value of the returned promise - * will be an array of length `$howMany` containing the resolution values of the - * triggering items. - * - * The returned promise will reject if it becomes impossible for `$howMany` items - * to resolve (that is, when `(count($promisesOrValues) - $howMany) + 1` items - * reject). The rejection value will be an array of - * `(count($promisesOrValues) - $howMany) + 1` rejection reasons. - * - * The returned promise will also reject with a `React\Promise\Exception\LengthException` - * if `$promisesOrValues` contains less items than `$howMany`. - * - * @param array $promisesOrValues - * @param int $howMany - * @return PromiseInterface - */ -function some($promisesOrValues, $howMany) -{ - $cancellationQueue = new CancellationQueue(); - $cancellationQueue->enqueue($promisesOrValues); - - return new Promise(function ($resolve, $reject, $notify) use ($promisesOrValues, $howMany, $cancellationQueue) { - resolve($promisesOrValues) - ->done(function ($array) use ($howMany, $cancellationQueue, $resolve, $reject, $notify) { - if (!\is_array($array) || $howMany < 1) { - $resolve([]); - return; - } - - $len = \count($array); - - if ($len < $howMany) { - throw new Exception\LengthException( - \sprintf( - 'Input array must contain at least %d item%s but contains only %s item%s.', - $howMany, - 1 === $howMany ? '' : 's', - $len, - 1 === $len ? '' : 's' - ) - ); - } - - $toResolve = $howMany; - $toReject = ($len - $toResolve) + 1; - $values = []; - $reasons = []; - - foreach ($array as $i => $promiseOrValue) { - $fulfiller = function ($val) use ($i, &$values, &$toResolve, $toReject, $resolve) { - if ($toResolve < 1 || $toReject < 1) { - return; - } - - $values[$i] = $val; - - if (0 === --$toResolve) { - $resolve($values); - } - }; - - $rejecter = function ($reason) use ($i, &$reasons, &$toReject, $toResolve, $reject) { - if ($toResolve < 1 || $toReject < 1) { - return; - } - - $reasons[$i] = $reason; - - if (0 === --$toReject) { - $reject($reasons); - } - }; - - $cancellationQueue->enqueue($promiseOrValue); - - resolve($promiseOrValue) - ->done($fulfiller, $rejecter, $notify); - } - }, $reject, $notify); - }, $cancellationQueue); -} - -/** - * Traditional map function, similar to `array_map()`, but allows input to contain - * promises and/or values, and `$mapFunc` may return either a value or a promise. - * - * The map function receives each item as argument, where item is a fully resolved - * value of a promise or value in `$promisesOrValues`. - * - * @param array $promisesOrValues - * @param callable $mapFunc - * @return PromiseInterface - */ -function map($promisesOrValues, callable $mapFunc) -{ - $cancellationQueue = new CancellationQueue(); - $cancellationQueue->enqueue($promisesOrValues); - - return new Promise(function ($resolve, $reject, $notify) use ($promisesOrValues, $mapFunc, $cancellationQueue) { - resolve($promisesOrValues) - ->done(function ($array) use ($mapFunc, $cancellationQueue, $resolve, $reject, $notify) { - if (!\is_array($array) || !$array) { - $resolve([]); - return; - } - - $toResolve = \count($array); - $values = []; - - foreach ($array as $i => $promiseOrValue) { - $cancellationQueue->enqueue($promiseOrValue); - $values[$i] = null; - - resolve($promiseOrValue) - ->then($mapFunc) - ->done( - function ($mapped) use ($i, &$values, &$toResolve, $resolve) { - $values[$i] = $mapped; - - if (0 === --$toResolve) { - $resolve($values); - } - }, - $reject, - $notify - ); - } - }, $reject, $notify); - }, $cancellationQueue); -} - -/** - * Traditional reduce function, similar to `array_reduce()`, but input may contain - * promises and/or values, and `$reduceFunc` may return either a value or a - * promise, *and* `$initialValue` may be a promise or a value for the starting - * value. - * - * @param array $promisesOrValues - * @param callable $reduceFunc - * @param mixed $initialValue - * @return PromiseInterface - */ -function reduce($promisesOrValues, callable $reduceFunc, $initialValue = null) -{ - $cancellationQueue = new CancellationQueue(); - $cancellationQueue->enqueue($promisesOrValues); - - return new Promise(function ($resolve, $reject, $notify) use ($promisesOrValues, $reduceFunc, $initialValue, $cancellationQueue) { - resolve($promisesOrValues) - ->done(function ($array) use ($reduceFunc, $initialValue, $cancellationQueue, $resolve, $reject, $notify) { - if (!\is_array($array)) { - $array = []; - } - - $total = \count($array); - $i = 0; - - // Wrap the supplied $reduceFunc with one that handles promises and then - // delegates to the supplied. - $wrappedReduceFunc = function ($current, $val) use ($reduceFunc, $cancellationQueue, $total, &$i) { - $cancellationQueue->enqueue($val); - - return $current - ->then(function ($c) use ($reduceFunc, $total, &$i, $val) { - return resolve($val) - ->then(function ($value) use ($reduceFunc, $total, &$i, $c) { - return $reduceFunc($c, $value, $i++, $total); - }); - }); - }; - - $cancellationQueue->enqueue($initialValue); - - \array_reduce($array, $wrappedReduceFunc, resolve($initialValue)) - ->done($resolve, $reject, $notify); - }, $reject, $notify); - }, $cancellationQueue); -} - -/** - * @internal - */ -function _checkTypehint(callable $callback, $object) -{ - if (!\is_object($object)) { - return true; - } - - if (\is_array($callback)) { - $callbackReflection = new \ReflectionMethod($callback[0], $callback[1]); - } elseif (\is_object($callback) && !$callback instanceof \Closure) { - $callbackReflection = new \ReflectionMethod($callback, '__invoke'); - } else { - $callbackReflection = new \ReflectionFunction($callback); - } - - $parameters = $callbackReflection->getParameters(); - - if (!isset($parameters[0])) { - return true; - } - - $expectedException = $parameters[0]; - - // PHP before v8 used an easy API: - if (\PHP_VERSION_ID < 70100 || \defined('HHVM_VERSION')) { - if (!$expectedException->getClass()) { - return true; - } - - return $expectedException->getClass()->isInstance($object); - } - - // Extract the type of the argument and handle different possibilities - $type = $expectedException->getType(); - - $isTypeUnion = true; - $types = []; - - switch (true) { - case $type === null: - break; - case $type instanceof \ReflectionNamedType: - $types = [$type]; - break; - case $type instanceof \ReflectionIntersectionType: - $isTypeUnion = false; - case $type instanceof \ReflectionUnionType; - $types = $type->getTypes(); - break; - default: - throw new \LogicException('Unexpected return value of ReflectionParameter::getType'); - } - - // If there is no type restriction, it matches - if (empty($types)) { - return true; - } - - foreach ($types as $type) { - if (!$type instanceof \ReflectionNamedType) { - throw new \LogicException('This implementation does not support groups of intersection or union types'); - } - - // A named-type can be either a class-name or a built-in type like string, int, array, etc. - $matches = ($type->isBuiltin() && \gettype($object) === $type->getName()) - || (new \ReflectionClass($type->getName()))->isInstance($object); - - - // If we look for a single match (union), we can return early on match - // If we look for a full match (intersection), we can return early on mismatch - if ($matches) { - if ($isTypeUnion) { - return true; - } - } else { - if (!$isTypeUnion) { - return false; - } - } - } - - // If we look for a single match (union) and did not return early, we matched no type and are false - // If we look for a full match (intersection) and did not return early, we matched all types and are true - return $isTypeUnion ? false : true; -} diff --git a/vendor/react/promise/src/functions_include.php b/vendor/react/promise/src/functions_include.php deleted file mode 100644 index bd0c54fd5..000000000 --- a/vendor/react/promise/src/functions_include.php +++ /dev/null @@ -1,5 +0,0 @@ -= 70300 && \PHP_VERSION_ID < 70303); - - // PHP < 7.1.4 (and PHP < 7.0.18) suffers from a bug when writing big - // chunks of data over TLS streams at once. - // We try to work around this by limiting the write chunk size to 8192 - // bytes for older PHP versions only. - // This is only a work-around and has a noticable performance penalty on - // affected versions. Please update your PHP version. - // This applies to all streams because TLS may be enabled later on. - // See https://github.com/reactphp/socket/issues/105 - $limitWriteChunks = (\PHP_VERSION_ID < 70018 || (\PHP_VERSION_ID >= 70100 && \PHP_VERSION_ID < 70104)); - - $this->input = new DuplexResourceStream( - $resource, - $loop, - $clearCompleteBuffer ? -1 : null, - new WritableResourceStream($resource, $loop, null, $limitWriteChunks ? 8192 : null) - ); - - $this->stream = $resource; - - Util::forwardEvents($this->input, $this, array('data', 'end', 'error', 'close', 'pipe', 'drain')); - - $this->input->on('close', array($this, 'close')); - } - - public function isReadable() - { - return $this->input->isReadable(); - } - - public function isWritable() - { - return $this->input->isWritable(); - } - - public function pause() - { - $this->input->pause(); - } - - public function resume() - { - $this->input->resume(); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - return $this->input->pipe($dest, $options); - } - - public function write($data) - { - return $this->input->write($data); - } - - public function end($data = null) - { - $this->input->end($data); - } - - public function close() - { - $this->input->close(); - $this->handleClose(); - $this->removeAllListeners(); - } - - public function handleClose() - { - if (!\is_resource($this->stream)) { - return; - } - - // Try to cleanly shut down socket and ignore any errors in case other - // side already closed. Shutting down may return to blocking mode on - // some legacy versions, so reset to non-blocking just in case before - // continuing to close the socket resource. - // Underlying Stream implementation will take care of closing file - // handle, so we otherwise keep this open here. - @\stream_socket_shutdown($this->stream, \STREAM_SHUT_RDWR); - \stream_set_blocking($this->stream, false); - } - - public function getRemoteAddress() - { - if (!\is_resource($this->stream)) { - return null; - } - - return $this->parseAddress(\stream_socket_get_name($this->stream, true)); - } - - public function getLocalAddress() - { - if (!\is_resource($this->stream)) { - return null; - } - - return $this->parseAddress(\stream_socket_get_name($this->stream, false)); - } - - private function parseAddress($address) - { - if ($address === false) { - return null; - } - - if ($this->unix) { - // remove trailing colon from address for HHVM < 3.19: https://3v4l.org/5C1lo - // note that technically ":" is a valid address, so keep this in place otherwise - if (\substr($address, -1) === ':' && \defined('HHVM_VERSION_ID') && \HHVM_VERSION_ID < 31900) { - $address = (string)\substr($address, 0, -1); // @codeCoverageIgnore - } - - // work around unknown addresses should return null value: https://3v4l.org/5C1lo and https://bugs.php.net/bug.php?id=74556 - // PHP uses "\0" string and HHVM uses empty string (colon removed above) - if ($address === '' || $address[0] === "\x00" ) { - return null; // @codeCoverageIgnore - } - - return 'unix://' . $address; - } - - // check if this is an IPv6 address which includes multiple colons but no square brackets - $pos = \strrpos($address, ':'); - if ($pos !== false && \strpos($address, ':') < $pos && \substr($address, 0, 1) !== '[') { - $address = '[' . \substr($address, 0, $pos) . ']:' . \substr($address, $pos + 1); // @codeCoverageIgnore - } - - return ($this->encryptionEnabled ? 'tls' : 'tcp') . '://' . $address; - } -} diff --git a/vendor/react/socket/src/ConnectionInterface.php b/vendor/react/socket/src/ConnectionInterface.php deleted file mode 100644 index 64613b58a..000000000 --- a/vendor/react/socket/src/ConnectionInterface.php +++ /dev/null @@ -1,119 +0,0 @@ -on('data', function ($chunk) { - * echo $chunk; - * }); - * - * $connection->on('end', function () { - * echo 'ended'; - * }); - * - * $connection->on('error', function (Exception $e) { - * echo 'error: ' . $e->getMessage(); - * }); - * - * $connection->on('close', function () { - * echo 'closed'; - * }); - * - * $connection->write($data); - * $connection->end($data = null); - * $connection->close(); - * // … - * ``` - * - * For more details, see the - * [`DuplexStreamInterface`](https://github.com/reactphp/stream#duplexstreaminterface). - * - * @see DuplexStreamInterface - * @see ServerInterface - * @see ConnectorInterface - */ -interface ConnectionInterface extends DuplexStreamInterface -{ - /** - * Returns the full remote address (URI) where this connection has been established with - * - * ```php - * $address = $connection->getRemoteAddress(); - * echo 'Connection with ' . $address . PHP_EOL; - * ``` - * - * If the remote address can not be determined or is unknown at this time (such as - * after the connection has been closed), it MAY return a `NULL` value instead. - * - * Otherwise, it will return the full address (URI) as a string value, such - * as `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`, - * `unix://example.sock` or `unix:///path/to/example.sock`. - * Note that individual URI components are application specific and depend - * on the underlying transport protocol. - * - * If this is a TCP/IP based connection and you only want the remote IP, you may - * use something like this: - * - * ```php - * $address = $connection->getRemoteAddress(); - * $ip = trim(parse_url($address, PHP_URL_HOST), '[]'); - * echo 'Connection with ' . $ip . PHP_EOL; - * ``` - * - * @return ?string remote address (URI) or null if unknown - */ - public function getRemoteAddress(); - - /** - * Returns the full local address (full URI with scheme, IP and port) where this connection has been established with - * - * ```php - * $address = $connection->getLocalAddress(); - * echo 'Connection with ' . $address . PHP_EOL; - * ``` - * - * If the local address can not be determined or is unknown at this time (such as - * after the connection has been closed), it MAY return a `NULL` value instead. - * - * Otherwise, it will return the full address (URI) as a string value, such - * as `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`, - * `unix://example.sock` or `unix:///path/to/example.sock`. - * Note that individual URI components are application specific and depend - * on the underlying transport protocol. - * - * This method complements the [`getRemoteAddress()`](#getremoteaddress) method, - * so they should not be confused. - * - * If your `TcpServer` instance is listening on multiple interfaces (e.g. using - * the address `0.0.0.0`), you can use this method to find out which interface - * actually accepted this connection (such as a public or local interface). - * - * If your system has multiple interfaces (e.g. a WAN and a LAN interface), - * you can use this method to find out which interface was actually - * used for this connection. - * - * @return ?string local address (URI) or null if unknown - * @see self::getRemoteAddress() - */ - public function getLocalAddress(); -} diff --git a/vendor/react/socket/src/Connector.php b/vendor/react/socket/src/Connector.php deleted file mode 100644 index 93477bd73..000000000 --- a/vendor/react/socket/src/Connector.php +++ /dev/null @@ -1,236 +0,0 @@ - true, - 'tls' => true, - 'unix' => true, - - 'dns' => true, - 'timeout' => true, - 'happy_eyeballs' => true, - ); - - if ($context['timeout'] === true) { - $context['timeout'] = (float)\ini_get("default_socket_timeout"); - } - - if ($context['tcp'] instanceof ConnectorInterface) { - $tcp = $context['tcp']; - } else { - $tcp = new TcpConnector( - $loop, - \is_array($context['tcp']) ? $context['tcp'] : array() - ); - } - - if ($context['dns'] !== false) { - if ($context['dns'] instanceof ResolverInterface) { - $resolver = $context['dns']; - } else { - if ($context['dns'] !== true) { - $config = $context['dns']; - } else { - // try to load nameservers from system config or default to Google's public DNS - $config = DnsConfig::loadSystemConfigBlocking(); - if (!$config->nameservers) { - $config->nameservers[] = '8.8.8.8'; // @codeCoverageIgnore - } - } - - $factory = new DnsFactory(); - $resolver = $factory->createCached( - $config, - $loop - ); - } - - if ($context['happy_eyeballs'] === true) { - $tcp = new HappyEyeBallsConnector($loop, $tcp, $resolver); - } else { - $tcp = new DnsConnector($tcp, $resolver); - } - } - - if ($context['tcp'] !== false) { - $context['tcp'] = $tcp; - - if ($context['timeout'] !== false) { - $context['tcp'] = new TimeoutConnector( - $context['tcp'], - $context['timeout'], - $loop - ); - } - - $this->connectors['tcp'] = $context['tcp']; - } - - if ($context['tls'] !== false) { - if (!$context['tls'] instanceof ConnectorInterface) { - $context['tls'] = new SecureConnector( - $tcp, - $loop, - \is_array($context['tls']) ? $context['tls'] : array() - ); - } - - if ($context['timeout'] !== false) { - $context['tls'] = new TimeoutConnector( - $context['tls'], - $context['timeout'], - $loop - ); - } - - $this->connectors['tls'] = $context['tls']; - } - - if ($context['unix'] !== false) { - if (!$context['unix'] instanceof ConnectorInterface) { - $context['unix'] = new UnixConnector($loop); - } - $this->connectors['unix'] = $context['unix']; - } - } - - public function connect($uri) - { - $scheme = 'tcp'; - if (\strpos($uri, '://') !== false) { - $scheme = (string)\substr($uri, 0, \strpos($uri, '://')); - } - - if (!isset($this->connectors[$scheme])) { - return \React\Promise\reject(new \RuntimeException( - 'No connector available for URI scheme "' . $scheme . '" (EINVAL)', - \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : 22 - )); - } - - return $this->connectors[$scheme]->connect($uri); - } - - - /** - * [internal] Builds on URI from the given URI parts and ip address with original hostname as query - * - * @param array $parts - * @param string $host - * @param string $ip - * @return string - * @internal - */ - public static function uri(array $parts, $host, $ip) - { - $uri = ''; - - // prepend original scheme if known - if (isset($parts['scheme'])) { - $uri .= $parts['scheme'] . '://'; - } - - if (\strpos($ip, ':') !== false) { - // enclose IPv6 addresses in square brackets before appending port - $uri .= '[' . $ip . ']'; - } else { - $uri .= $ip; - } - - // append original port if known - if (isset($parts['port'])) { - $uri .= ':' . $parts['port']; - } - - // append orignal path if known - if (isset($parts['path'])) { - $uri .= $parts['path']; - } - - // append original query if known - if (isset($parts['query'])) { - $uri .= '?' . $parts['query']; - } - - // append original hostname as query if resolved via DNS and if - // destination URI does not contain "hostname" query param already - $args = array(); - \parse_str(isset($parts['query']) ? $parts['query'] : '', $args); - if ($host !== $ip && !isset($args['hostname'])) { - $uri .= (isset($parts['query']) ? '&' : '?') . 'hostname=' . \rawurlencode($host); - } - - // append original fragment if known - if (isset($parts['fragment'])) { - $uri .= '#' . $parts['fragment']; - } - - return $uri; - } -} diff --git a/vendor/react/socket/src/ConnectorInterface.php b/vendor/react/socket/src/ConnectorInterface.php deleted file mode 100644 index 3dd78f139..000000000 --- a/vendor/react/socket/src/ConnectorInterface.php +++ /dev/null @@ -1,58 +0,0 @@ -connect('google.com:443')->then( - * function (React\Socket\ConnectionInterface $connection) { - * // connection successfully established - * }, - * function (Exception $error) { - * // failed to connect due to $error - * } - * ); - * ``` - * - * The returned Promise MUST be implemented in such a way that it can be - * cancelled when it is still pending. Cancelling a pending promise MUST - * reject its value with an Exception. It SHOULD clean up any underlying - * resources and references as applicable. - * - * ```php - * $promise = $connector->connect($uri); - * - * $promise->cancel(); - * ``` - * - * @param string $uri - * @return \React\Promise\PromiseInterface resolves with a stream implementing ConnectionInterface on success or rejects with an Exception on error - * @see ConnectionInterface - */ - public function connect($uri); -} diff --git a/vendor/react/socket/src/DnsConnector.php b/vendor/react/socket/src/DnsConnector.php deleted file mode 100644 index 27fc8f8b9..000000000 --- a/vendor/react/socket/src/DnsConnector.php +++ /dev/null @@ -1,117 +0,0 @@ -connector = $connector; - $this->resolver = $resolver; - } - - public function connect($uri) - { - $original = $uri; - if (\strpos($uri, '://') === false) { - $uri = 'tcp://' . $uri; - $parts = \parse_url($uri); - if (isset($parts['scheme'])) { - unset($parts['scheme']); - } - } else { - $parts = \parse_url($uri); - } - - if (!$parts || !isset($parts['host'])) { - return Promise\reject(new \InvalidArgumentException( - 'Given URI "' . $original . '" is invalid (EINVAL)', - \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : 22 - )); - } - - $host = \trim($parts['host'], '[]'); - $connector = $this->connector; - - // skip DNS lookup / URI manipulation if this URI already contains an IP - if (@\inet_pton($host) !== false) { - return $connector->connect($original); - } - - $promise = $this->resolver->resolve($host); - $resolved = null; - - return new Promise\Promise( - function ($resolve, $reject) use (&$promise, &$resolved, $uri, $connector, $host, $parts) { - // resolve/reject with result of DNS lookup - $promise->then(function ($ip) use (&$promise, &$resolved, $uri, $connector, $host, $parts) { - $resolved = $ip; - - return $promise = $connector->connect( - Connector::uri($parts, $host, $ip) - )->then(null, function (\Exception $e) use ($uri) { - if ($e instanceof \RuntimeException) { - $message = \preg_replace('/^(Connection to [^ ]+)[&?]hostname=[^ &]+/', '$1', $e->getMessage()); - $e = new \RuntimeException( - 'Connection to ' . $uri . ' failed: ' . $message, - $e->getCode(), - $e - ); - - // avoid garbage references by replacing all closures in call stack. - // what a lovely piece of code! - $r = new \ReflectionProperty('Exception', 'trace'); - $r->setAccessible(true); - $trace = $r->getValue($e); - - // Exception trace arguments are not available on some PHP 7.4 installs - // @codeCoverageIgnoreStart - foreach ($trace as &$one) { - if (isset($one['args'])) { - foreach ($one['args'] as &$arg) { - if ($arg instanceof \Closure) { - $arg = 'Object(' . \get_class($arg) . ')'; - } - } - } - } - // @codeCoverageIgnoreEnd - $r->setValue($e, $trace); - } - - throw $e; - }); - }, function ($e) use ($uri, $reject) { - $reject(new \RuntimeException('Connection to ' . $uri .' failed during DNS lookup: ' . $e->getMessage(), 0, $e)); - })->then($resolve, $reject); - }, - function ($_, $reject) use (&$promise, &$resolved, $uri) { - // cancellation should reject connection attempt - // reject DNS resolution with custom reason, otherwise rely on connection cancellation below - if ($resolved === null) { - $reject(new \RuntimeException( - 'Connection to ' . $uri . ' cancelled during DNS lookup (ECONNABORTED)', - \defined('SOCKET_ECONNABORTED') ? \SOCKET_ECONNABORTED : 103 - )); - } - - // (try to) cancel pending DNS lookup / connection attempt - if ($promise instanceof CancellablePromiseInterface) { - // overwrite callback arguments for PHP7+ only, so they do not show - // up in the Exception trace and do not cause a possible cyclic reference. - $_ = $reject = null; - - $promise->cancel(); - $promise = null; - } - } - ); - } -} diff --git a/vendor/react/socket/src/FdServer.php b/vendor/react/socket/src/FdServer.php deleted file mode 100644 index 2c7a6c4de..000000000 --- a/vendor/react/socket/src/FdServer.php +++ /dev/null @@ -1,212 +0,0 @@ -on('connection', function (ConnectionInterface $connection) { - * echo 'Plaintext connection from ' . $connection->getRemoteAddress() . PHP_EOL; - * $connection->write('hello there!' . PHP_EOL); - * … - * }); - * ``` - * - * See also the `ServerInterface` for more details. - * - * @see ServerInterface - * @see ConnectionInterface - * @internal - */ -final class FdServer extends EventEmitter implements ServerInterface -{ - private $master; - private $loop; - private $unix = false; - private $listening = false; - - /** - * Creates a socket server and starts listening on the given file descriptor - * - * This starts accepting new incoming connections on the given file descriptor. - * See also the `connection event` documented in the `ServerInterface` - * for more details. - * - * ```php - * $socket = new React\Socket\FdServer(3); - * ``` - * - * If the given FD is invalid or out of range, it will throw an `InvalidArgumentException`: - * - * ```php - * // throws InvalidArgumentException - * $socket = new React\Socket\FdServer(-1); - * ``` - * - * If the given FD appears to be valid, but listening on it fails (such as - * if the FD does not exist or does not refer to a socket server), it will - * throw a `RuntimeException`: - * - * ```php - * // throws RuntimeException because FD does not reference a socket server - * $socket = new React\Socket\FdServer(0, $loop); - * ``` - * - * Note that these error conditions may vary depending on your system and/or - * configuration. - * See the exception message and code for more details about the actual error - * condition. - * - * @param int|string $fd FD number such as `3` or as URL in the form of `php://fd/3` - * @param ?LoopInterface $loop - * @throws \InvalidArgumentException if the listening address is invalid - * @throws \RuntimeException if listening on this address fails (already in use etc.) - */ - public function __construct($fd, LoopInterface $loop = null) - { - if (\preg_match('#^php://fd/(\d+)$#', $fd, $m)) { - $fd = (int) $m[1]; - } - if (!\is_int($fd) || $fd < 0 || $fd >= \PHP_INT_MAX) { - throw new \InvalidArgumentException( - 'Invalid FD number given (EINVAL)', - \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : 22 - ); - } - - $this->loop = $loop ?: Loop::get(); - - $this->master = @\fopen('php://fd/' . $fd, 'r+'); - if (false === $this->master) { - // Match errstr from PHP's warning message. - // fopen(php://fd/3): Failed to open stream: Error duping file descriptor 3; possibly it doesn't exist: [9]: Bad file descriptor - $error = \error_get_last(); - \preg_match('/\[(\d+)\]: (.*)/', $error['message'], $m); - $errno = isset($m[1]) ? (int) $m[1] : 0; - $errstr = isset($m[2]) ? $m[2] : $error['message']; - - throw new \RuntimeException( - 'Failed to listen on FD ' . $fd . ': ' . $errstr . SocketServer::errconst($errno), - $errno - ); - } - - $meta = \stream_get_meta_data($this->master); - if (!isset($meta['stream_type']) || $meta['stream_type'] !== 'tcp_socket') { - \fclose($this->master); - - $errno = \defined('SOCKET_ENOTSOCK') ? \SOCKET_ENOTSOCK : 88; - $errstr = \function_exists('socket_strerror') ? \socket_strerror($errno) : 'Not a socket'; - - throw new \RuntimeException( - 'Failed to listen on FD ' . $fd . ': ' . $errstr . ' (ENOTSOCK)', - $errno - ); - } - - // Socket should not have a peer address if this is a listening socket. - // Looks like this work-around is the closest we can get because PHP doesn't expose SO_ACCEPTCONN even with ext-sockets. - if (\stream_socket_get_name($this->master, true) !== false) { - \fclose($this->master); - - $errno = \defined('SOCKET_EISCONN') ? \SOCKET_EISCONN : 106; - $errstr = \function_exists('socket_strerror') ? \socket_strerror($errno) : 'Socket is connected'; - - throw new \RuntimeException( - 'Failed to listen on FD ' . $fd . ': ' . $errstr . ' (EISCONN)', - $errno - ); - } - - // Assume this is a Unix domain socket (UDS) when its listening address doesn't parse as a valid URL with a port. - // Looks like this work-around is the closest we can get because PHP doesn't expose SO_DOMAIN even with ext-sockets. - $this->unix = \parse_url($this->getAddress(), \PHP_URL_PORT) === false; - - \stream_set_blocking($this->master, false); - - $this->resume(); - } - - public function getAddress() - { - if (!\is_resource($this->master)) { - return null; - } - - $address = \stream_socket_get_name($this->master, false); - - if ($this->unix === true) { - return 'unix://' . $address; - } - - // check if this is an IPv6 address which includes multiple colons but no square brackets - $pos = \strrpos($address, ':'); - if ($pos !== false && \strpos($address, ':') < $pos && \substr($address, 0, 1) !== '[') { - $address = '[' . \substr($address, 0, $pos) . ']:' . \substr($address, $pos + 1); // @codeCoverageIgnore - } - - return 'tcp://' . $address; - } - - public function pause() - { - if (!$this->listening) { - return; - } - - $this->loop->removeReadStream($this->master); - $this->listening = false; - } - - public function resume() - { - if ($this->listening || !\is_resource($this->master)) { - return; - } - - $that = $this; - $this->loop->addReadStream($this->master, function ($master) use ($that) { - try { - $newSocket = SocketServer::accept($master); - } catch (\RuntimeException $e) { - $that->emit('error', array($e)); - return; - } - $that->handleConnection($newSocket); - }); - $this->listening = true; - } - - public function close() - { - if (!\is_resource($this->master)) { - return; - } - - $this->pause(); - \fclose($this->master); - $this->removeAllListeners(); - } - - /** @internal */ - public function handleConnection($socket) - { - $connection = new Connection($socket, $this->loop); - $connection->unix = $this->unix; - - $this->emit('connection', array($connection)); - } -} diff --git a/vendor/react/socket/src/FixedUriConnector.php b/vendor/react/socket/src/FixedUriConnector.php deleted file mode 100644 index f83241d6c..000000000 --- a/vendor/react/socket/src/FixedUriConnector.php +++ /dev/null @@ -1,41 +0,0 @@ -connect('localhost:80'); - * ``` - */ -class FixedUriConnector implements ConnectorInterface -{ - private $uri; - private $connector; - - /** - * @param string $uri - * @param ConnectorInterface $connector - */ - public function __construct($uri, ConnectorInterface $connector) - { - $this->uri = $uri; - $this->connector = $connector; - } - - public function connect($_) - { - return $this->connector->connect($this->uri); - } -} diff --git a/vendor/react/socket/src/HappyEyeBallsConnectionBuilder.php b/vendor/react/socket/src/HappyEyeBallsConnectionBuilder.php deleted file mode 100644 index 6bd071682..000000000 --- a/vendor/react/socket/src/HappyEyeBallsConnectionBuilder.php +++ /dev/null @@ -1,333 +0,0 @@ - false, - Message::TYPE_AAAA => false, - ); - public $resolverPromises = array(); - public $connectionPromises = array(); - public $connectQueue = array(); - public $nextAttemptTimer; - public $parts; - public $ipsCount = 0; - public $failureCount = 0; - public $resolve; - public $reject; - - public $lastErrorFamily; - public $lastError6; - public $lastError4; - - public function __construct(LoopInterface $loop, ConnectorInterface $connector, ResolverInterface $resolver, $uri, $host, $parts) - { - $this->loop = $loop; - $this->connector = $connector; - $this->resolver = $resolver; - $this->uri = $uri; - $this->host = $host; - $this->parts = $parts; - } - - public function connect() - { - $timer = null; - $that = $this; - return new Promise\Promise(function ($resolve, $reject) use ($that, &$timer) { - $lookupResolve = function ($type) use ($that, $resolve, $reject) { - return function (array $ips) use ($that, $type, $resolve, $reject) { - unset($that->resolverPromises[$type]); - $that->resolved[$type] = true; - - $that->mixIpsIntoConnectQueue($ips); - - // start next connection attempt if not already awaiting next - if ($that->nextAttemptTimer === null && $that->connectQueue) { - $that->check($resolve, $reject); - } - }; - }; - - $that->resolverPromises[Message::TYPE_AAAA] = $that->resolve(Message::TYPE_AAAA, $reject)->then($lookupResolve(Message::TYPE_AAAA)); - $that->resolverPromises[Message::TYPE_A] = $that->resolve(Message::TYPE_A, $reject)->then(function (array $ips) use ($that, &$timer) { - // happy path: IPv6 has resolved already (or could not resolve), continue with IPv4 addresses - if ($that->resolved[Message::TYPE_AAAA] === true || !$ips) { - return $ips; - } - - // Otherwise delay processing IPv4 lookup until short timer passes or IPv6 resolves in the meantime - $deferred = new Promise\Deferred(); - $timer = $that->loop->addTimer($that::RESOLUTION_DELAY, function () use ($deferred, $ips) { - $deferred->resolve($ips); - }); - - $that->resolverPromises[Message::TYPE_AAAA]->then(function () use ($that, $timer, $deferred, $ips) { - $that->loop->cancelTimer($timer); - $deferred->resolve($ips); - }); - - return $deferred->promise(); - })->then($lookupResolve(Message::TYPE_A)); - }, function ($_, $reject) use ($that, &$timer) { - $reject(new \RuntimeException( - 'Connection to ' . $that->uri . ' cancelled' . (!$that->connectionPromises ? ' during DNS lookup' : '') . ' (ECONNABORTED)', - \defined('SOCKET_ECONNABORTED') ? \SOCKET_ECONNABORTED : 103 - )); - $_ = $reject = null; - - $that->cleanUp(); - if ($timer instanceof TimerInterface) { - $that->loop->cancelTimer($timer); - } - }); - } - - /** - * @internal - * @param int $type DNS query type - * @param callable $reject - * @return \React\Promise\PromiseInterface Returns a promise that - * always resolves with a list of IP addresses on success or an empty - * list on error. - */ - public function resolve($type, $reject) - { - $that = $this; - return $that->resolver->resolveAll($that->host, $type)->then(null, function (\Exception $e) use ($type, $reject, $that) { - unset($that->resolverPromises[$type]); - $that->resolved[$type] = true; - - if ($type === Message::TYPE_A) { - $that->lastError4 = $e->getMessage(); - $that->lastErrorFamily = 4; - } else { - $that->lastError6 = $e->getMessage(); - $that->lastErrorFamily = 6; - } - - // cancel next attempt timer when there are no more IPs to connect to anymore - if ($that->nextAttemptTimer !== null && !$that->connectQueue) { - $that->loop->cancelTimer($that->nextAttemptTimer); - $that->nextAttemptTimer = null; - } - - if ($that->hasBeenResolved() && $that->ipsCount === 0) { - $reject(new \RuntimeException( - $that->error(), - 0, - $e - )); - } - - // Exception already handled above, so don't throw an unhandled rejection here - return array(); - }); - } - - /** - * @internal - */ - public function check($resolve, $reject) - { - $ip = \array_shift($this->connectQueue); - - // start connection attempt and remember array position to later unset again - $this->connectionPromises[] = $this->attemptConnection($ip); - \end($this->connectionPromises); - $index = \key($this->connectionPromises); - - $that = $this; - $that->connectionPromises[$index]->then(function ($connection) use ($that, $index, $resolve) { - unset($that->connectionPromises[$index]); - - $that->cleanUp(); - - $resolve($connection); - }, function (\Exception $e) use ($that, $index, $ip, $resolve, $reject) { - unset($that->connectionPromises[$index]); - - $that->failureCount++; - - $message = \preg_replace('/^(Connection to [^ ]+)[&?]hostname=[^ &]+/', '$1', $e->getMessage()); - if (\strpos($ip, ':') === false) { - $that->lastError4 = $message; - $that->lastErrorFamily = 4; - } else { - $that->lastError6 = $message; - $that->lastErrorFamily = 6; - } - - // start next connection attempt immediately on error - if ($that->connectQueue) { - if ($that->nextAttemptTimer !== null) { - $that->loop->cancelTimer($that->nextAttemptTimer); - $that->nextAttemptTimer = null; - } - - $that->check($resolve, $reject); - } - - if ($that->hasBeenResolved() === false) { - return; - } - - if ($that->ipsCount === $that->failureCount) { - $that->cleanUp(); - - $reject(new \RuntimeException( - $that->error(), - $e->getCode(), - $e - )); - } - }); - - // Allow next connection attempt in 100ms: https://tools.ietf.org/html/rfc8305#section-5 - // Only start timer when more IPs are queued or when DNS query is still pending (might add more IPs) - if ($this->nextAttemptTimer === null && (\count($this->connectQueue) > 0 || $this->resolved[Message::TYPE_A] === false || $this->resolved[Message::TYPE_AAAA] === false)) { - $this->nextAttemptTimer = $this->loop->addTimer(self::CONNECTION_ATTEMPT_DELAY, function () use ($that, $resolve, $reject) { - $that->nextAttemptTimer = null; - - if ($that->connectQueue) { - $that->check($resolve, $reject); - } - }); - } - } - - /** - * @internal - */ - public function attemptConnection($ip) - { - $uri = Connector::uri($this->parts, $this->host, $ip); - - return $this->connector->connect($uri); - } - - /** - * @internal - */ - public function cleanUp() - { - // clear list of outstanding IPs to avoid creating new connections - $this->connectQueue = array(); - - foreach ($this->connectionPromises as $connectionPromise) { - if ($connectionPromise instanceof CancellablePromiseInterface) { - $connectionPromise->cancel(); - } - } - - foreach ($this->resolverPromises as $resolverPromise) { - if ($resolverPromise instanceof CancellablePromiseInterface) { - $resolverPromise->cancel(); - } - } - - if ($this->nextAttemptTimer instanceof TimerInterface) { - $this->loop->cancelTimer($this->nextAttemptTimer); - $this->nextAttemptTimer = null; - } - } - - /** - * @internal - */ - public function hasBeenResolved() - { - foreach ($this->resolved as $typeHasBeenResolved) { - if ($typeHasBeenResolved === false) { - return false; - } - } - - return true; - } - - /** - * Mixes an array of IP addresses into the connect queue in such a way they alternate when attempting to connect. - * The goal behind it is first attempt to connect to IPv6, then to IPv4, then to IPv6 again until one of those - * attempts succeeds. - * - * @link https://tools.ietf.org/html/rfc8305#section-4 - * - * @internal - */ - public function mixIpsIntoConnectQueue(array $ips) - { - \shuffle($ips); - $this->ipsCount += \count($ips); - $connectQueueStash = $this->connectQueue; - $this->connectQueue = array(); - while (\count($connectQueueStash) > 0 || \count($ips) > 0) { - if (\count($ips) > 0) { - $this->connectQueue[] = \array_shift($ips); - } - if (\count($connectQueueStash) > 0) { - $this->connectQueue[] = \array_shift($connectQueueStash); - } - } - } - - /** - * @internal - * @return string - */ - public function error() - { - if ($this->lastError4 === $this->lastError6) { - $message = $this->lastError6; - } elseif ($this->lastErrorFamily === 6) { - $message = 'Last error for IPv6: ' . $this->lastError6 . '. Previous error for IPv4: ' . $this->lastError4; - } else { - $message = 'Last error for IPv4: ' . $this->lastError4 . '. Previous error for IPv6: ' . $this->lastError6; - } - - if ($this->hasBeenResolved() && $this->ipsCount === 0) { - if ($this->lastError6 === $this->lastError4) { - $message = ' during DNS lookup: ' . $this->lastError6; - } else { - $message = ' during DNS lookup. ' . $message; - } - } else { - $message = ': ' . $message; - } - - return 'Connection to ' . $this->uri . ' failed' . $message; - } -} diff --git a/vendor/react/socket/src/HappyEyeBallsConnector.php b/vendor/react/socket/src/HappyEyeBallsConnector.php deleted file mode 100644 index 4b04f7738..000000000 --- a/vendor/react/socket/src/HappyEyeBallsConnector.php +++ /dev/null @@ -1,69 +0,0 @@ -loop = $loop ?: Loop::get(); - $this->connector = $connector; - $this->resolver = $resolver; - } - - public function connect($uri) - { - $original = $uri; - if (\strpos($uri, '://') === false) { - $uri = 'tcp://' . $uri; - $parts = \parse_url($uri); - if (isset($parts['scheme'])) { - unset($parts['scheme']); - } - } else { - $parts = \parse_url($uri); - } - - if (!$parts || !isset($parts['host'])) { - return Promise\reject(new \InvalidArgumentException( - 'Given URI "' . $original . '" is invalid (EINVAL)', - \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : 22 - )); - } - - $host = \trim($parts['host'], '[]'); - - // skip DNS lookup / URI manipulation if this URI already contains an IP - if (@\inet_pton($host) !== false) { - return $this->connector->connect($original); - } - - $builder = new HappyEyeBallsConnectionBuilder( - $this->loop, - $this->connector, - $this->resolver, - $uri, - $host, - $parts - ); - return $builder->connect(); - } -} diff --git a/vendor/react/socket/src/LimitingServer.php b/vendor/react/socket/src/LimitingServer.php deleted file mode 100644 index d19000b36..000000000 --- a/vendor/react/socket/src/LimitingServer.php +++ /dev/null @@ -1,203 +0,0 @@ -on('connection', function (React\Socket\ConnectionInterface $connection) { - * $connection->write('hello there!' . PHP_EOL); - * … - * }); - * ``` - * - * See also the `ServerInterface` for more details. - * - * @see ServerInterface - * @see ConnectionInterface - */ -class LimitingServer extends EventEmitter implements ServerInterface -{ - private $connections = array(); - private $server; - private $limit; - - private $pauseOnLimit = false; - private $autoPaused = false; - private $manuPaused = false; - - /** - * Instantiates a new LimitingServer. - * - * You have to pass a maximum number of open connections to ensure - * the server will automatically reject (close) connections once this limit - * is exceeded. In this case, it will emit an `error` event to inform about - * this and no `connection` event will be emitted. - * - * ```php - * $server = new React\Socket\LimitingServer($server, 100); - * $server->on('connection', function (React\Socket\ConnectionInterface $connection) { - * $connection->write('hello there!' . PHP_EOL); - * … - * }); - * ``` - * - * You MAY pass a `null` limit in order to put no limit on the number of - * open connections and keep accepting new connection until you run out of - * operating system resources (such as open file handles). This may be - * useful if you do not want to take care of applying a limit but still want - * to use the `getConnections()` method. - * - * You can optionally configure the server to pause accepting new - * connections once the connection limit is reached. In this case, it will - * pause the underlying server and no longer process any new connections at - * all, thus also no longer closing any excessive connections. - * The underlying operating system is responsible for keeping a backlog of - * pending connections until its limit is reached, at which point it will - * start rejecting further connections. - * Once the server is below the connection limit, it will continue consuming - * connections from the backlog and will process any outstanding data on - * each connection. - * This mode may be useful for some protocols that are designed to wait for - * a response message (such as HTTP), but may be less useful for other - * protocols that demand immediate responses (such as a "welcome" message in - * an interactive chat). - * - * ```php - * $server = new React\Socket\LimitingServer($server, 100, true); - * $server->on('connection', function (React\Socket\ConnectionInterface $connection) { - * $connection->write('hello there!' . PHP_EOL); - * … - * }); - * ``` - * - * @param ServerInterface $server - * @param int|null $connectionLimit - * @param bool $pauseOnLimit - */ - public function __construct(ServerInterface $server, $connectionLimit, $pauseOnLimit = false) - { - $this->server = $server; - $this->limit = $connectionLimit; - if ($connectionLimit !== null) { - $this->pauseOnLimit = $pauseOnLimit; - } - - $this->server->on('connection', array($this, 'handleConnection')); - $this->server->on('error', array($this, 'handleError')); - } - - /** - * Returns an array with all currently active connections - * - * ```php - * foreach ($server->getConnection() as $connection) { - * $connection->write('Hi!'); - * } - * ``` - * - * @return ConnectionInterface[] - */ - public function getConnections() - { - return $this->connections; - } - - public function getAddress() - { - return $this->server->getAddress(); - } - - public function pause() - { - if (!$this->manuPaused) { - $this->manuPaused = true; - - if (!$this->autoPaused) { - $this->server->pause(); - } - } - } - - public function resume() - { - if ($this->manuPaused) { - $this->manuPaused = false; - - if (!$this->autoPaused) { - $this->server->resume(); - } - } - } - - public function close() - { - $this->server->close(); - } - - /** @internal */ - public function handleConnection(ConnectionInterface $connection) - { - // close connection if limit exceeded - if ($this->limit !== null && \count($this->connections) >= $this->limit) { - $this->handleError(new \OverflowException('Connection closed because server reached connection limit')); - $connection->close(); - return; - } - - $this->connections[] = $connection; - $that = $this; - $connection->on('close', function () use ($that, $connection) { - $that->handleDisconnection($connection); - }); - - // pause accepting new connections if limit exceeded - if ($this->pauseOnLimit && !$this->autoPaused && \count($this->connections) >= $this->limit) { - $this->autoPaused = true; - - if (!$this->manuPaused) { - $this->server->pause(); - } - } - - $this->emit('connection', array($connection)); - } - - /** @internal */ - public function handleDisconnection(ConnectionInterface $connection) - { - unset($this->connections[\array_search($connection, $this->connections)]); - - // continue accepting new connection if below limit - if ($this->autoPaused && \count($this->connections) < $this->limit) { - $this->autoPaused = false; - - if (!$this->manuPaused) { - $this->server->resume(); - } - } - } - - /** @internal */ - public function handleError(\Exception $error) - { - $this->emit('error', array($error)); - } -} diff --git a/vendor/react/socket/src/SecureConnector.php b/vendor/react/socket/src/SecureConnector.php deleted file mode 100644 index 03c6e361f..000000000 --- a/vendor/react/socket/src/SecureConnector.php +++ /dev/null @@ -1,122 +0,0 @@ -connector = $connector; - $this->streamEncryption = new StreamEncryption($loop ?: Loop::get(), false); - $this->context = $context; - } - - public function connect($uri) - { - if (!\function_exists('stream_socket_enable_crypto')) { - return Promise\reject(new \BadMethodCallException('Encryption not supported on your platform (HHVM < 3.8?)')); // @codeCoverageIgnore - } - - if (\strpos($uri, '://') === false) { - $uri = 'tls://' . $uri; - } - - $parts = \parse_url($uri); - if (!$parts || !isset($parts['scheme']) || $parts['scheme'] !== 'tls') { - return Promise\reject(new \InvalidArgumentException( - 'Given URI "' . $uri . '" is invalid (EINVAL)', - \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : 22 - )); - } - - $context = $this->context; - $encryption = $this->streamEncryption; - $connected = false; - $promise = $this->connector->connect( - \str_replace('tls://', '', $uri) - )->then(function (ConnectionInterface $connection) use ($context, $encryption, $uri, &$promise, &$connected) { - // (unencrypted) TCP/IP connection succeeded - $connected = true; - - if (!$connection instanceof Connection) { - $connection->close(); - throw new \UnexpectedValueException('Base connector does not use internal Connection class exposing stream resource'); - } - - // set required SSL/TLS context options - foreach ($context as $name => $value) { - \stream_context_set_option($connection->stream, 'ssl', $name, $value); - } - - // try to enable encryption - return $promise = $encryption->enable($connection)->then(null, function ($error) use ($connection, $uri) { - // establishing encryption failed => close invalid connection and return error - $connection->close(); - - throw new \RuntimeException( - 'Connection to ' . $uri . ' failed during TLS handshake: ' . $error->getMessage(), - $error->getCode() - ); - }); - }, function (\Exception $e) use ($uri) { - if ($e instanceof \RuntimeException) { - $message = \preg_replace('/^Connection to [^ ]+/', '', $e->getMessage()); - $e = new \RuntimeException( - 'Connection to ' . $uri . $message, - $e->getCode(), - $e - ); - - // avoid garbage references by replacing all closures in call stack. - // what a lovely piece of code! - $r = new \ReflectionProperty('Exception', 'trace'); - $r->setAccessible(true); - $trace = $r->getValue($e); - - // Exception trace arguments are not available on some PHP 7.4 installs - // @codeCoverageIgnoreStart - foreach ($trace as &$one) { - if (isset($one['args'])) { - foreach ($one['args'] as &$arg) { - if ($arg instanceof \Closure) { - $arg = 'Object(' . \get_class($arg) . ')'; - } - } - } - } - // @codeCoverageIgnoreEnd - $r->setValue($e, $trace); - } - - throw $e; - }); - - return new \React\Promise\Promise( - function ($resolve, $reject) use ($promise) { - $promise->then($resolve, $reject); - }, - function ($_, $reject) use (&$promise, $uri, &$connected) { - if ($connected) { - $reject(new \RuntimeException( - 'Connection to ' . $uri . ' cancelled during TLS handshake (ECONNABORTED)', - \defined('SOCKET_ECONNABORTED') ? \SOCKET_ECONNABORTED : 103 - )); - } - - $promise->cancel(); - $promise = null; - } - ); - } -} diff --git a/vendor/react/socket/src/SecureServer.php b/vendor/react/socket/src/SecureServer.php deleted file mode 100644 index d0525c942..000000000 --- a/vendor/react/socket/src/SecureServer.php +++ /dev/null @@ -1,206 +0,0 @@ -on('connection', function (React\Socket\ConnectionInterface $connection) { - * echo 'Secure connection from' . $connection->getRemoteAddress() . PHP_EOL; - * - * $connection->write('hello there!' . PHP_EOL); - * … - * }); - * ``` - * - * Whenever a client fails to perform a successful TLS handshake, it will emit an - * `error` event and then close the underlying TCP/IP connection: - * - * ```php - * $server->on('error', function (Exception $e) { - * echo 'Error' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * See also the `ServerInterface` for more details. - * - * Note that the `SecureServer` class is a concrete implementation for TLS sockets. - * If you want to typehint in your higher-level protocol implementation, you SHOULD - * use the generic `ServerInterface` instead. - * - * @see ServerInterface - * @see ConnectionInterface - */ -final class SecureServer extends EventEmitter implements ServerInterface -{ - private $tcp; - private $encryption; - private $context; - - /** - * Creates a secure TLS server and starts waiting for incoming connections - * - * It does so by wrapping a `TcpServer` instance which waits for plaintext - * TCP/IP connections and then performs a TLS handshake for each connection. - * It thus requires valid [TLS context options], - * which in its most basic form may look something like this if you're using a - * PEM encoded certificate file: - * - * ```php - * $server = new React\Socket\TcpServer(8000); - * $server = new React\Socket\SecureServer($server, null, array( - * 'local_cert' => 'server.pem' - * )); - * ``` - * - * Note that the certificate file will not be loaded on instantiation but when an - * incoming connection initializes its TLS context. - * This implies that any invalid certificate file paths or contents will only cause - * an `error` event at a later time. - * - * If your private key is encrypted with a passphrase, you have to specify it - * like this: - * - * ```php - * $server = new React\Socket\TcpServer(8000); - * $server = new React\Socket\SecureServer($server, null, array( - * 'local_cert' => 'server.pem', - * 'passphrase' => 'secret' - * )); - * ``` - * - * Note that available [TLS context options], - * their defaults and effects of changing these may vary depending on your system - * and/or PHP version. - * Passing unknown context options has no effect. - * - * This class takes an optional `LoopInterface|null $loop` parameter that can be used to - * pass the event loop instance to use for this object. You can use a `null` value - * here in order to use the [default loop](https://github.com/reactphp/event-loop#loop). - * This value SHOULD NOT be given unless you're sure you want to explicitly use a - * given event loop instance. - * - * Advanced usage: Despite allowing any `ServerInterface` as first parameter, - * you SHOULD pass a `TcpServer` instance as first parameter, unless you - * know what you're doing. - * Internally, the `SecureServer` has to set the required TLS context options on - * the underlying stream resources. - * These resources are not exposed through any of the interfaces defined in this - * package, but only through the internal `Connection` class. - * The `TcpServer` class is guaranteed to emit connections that implement - * the `ConnectionInterface` and uses the internal `Connection` class in order to - * expose these underlying resources. - * If you use a custom `ServerInterface` and its `connection` event does not - * meet this requirement, the `SecureServer` will emit an `error` event and - * then close the underlying connection. - * - * @param ServerInterface|TcpServer $tcp - * @param ?LoopInterface $loop - * @param array $context - * @throws BadMethodCallException for legacy HHVM < 3.8 due to lack of support - * @see TcpServer - * @link https://www.php.net/manual/en/context.ssl.php for TLS context options - */ - public function __construct(ServerInterface $tcp, LoopInterface $loop = null, array $context = array()) - { - if (!\function_exists('stream_socket_enable_crypto')) { - throw new \BadMethodCallException('Encryption not supported on your platform (HHVM < 3.8?)'); // @codeCoverageIgnore - } - - // default to empty passphrase to suppress blocking passphrase prompt - $context += array( - 'passphrase' => '' - ); - - $this->tcp = $tcp; - $this->encryption = new StreamEncryption($loop ?: Loop::get()); - $this->context = $context; - - $that = $this; - $this->tcp->on('connection', function ($connection) use ($that) { - $that->handleConnection($connection); - }); - $this->tcp->on('error', function ($error) use ($that) { - $that->emit('error', array($error)); - }); - } - - public function getAddress() - { - $address = $this->tcp->getAddress(); - if ($address === null) { - return null; - } - - return \str_replace('tcp://' , 'tls://', $address); - } - - public function pause() - { - $this->tcp->pause(); - } - - public function resume() - { - $this->tcp->resume(); - } - - public function close() - { - return $this->tcp->close(); - } - - /** @internal */ - public function handleConnection(ConnectionInterface $connection) - { - if (!$connection instanceof Connection) { - $this->emit('error', array(new \UnexpectedValueException('Base server does not use internal Connection class exposing stream resource'))); - $connection->close(); - return; - } - - foreach ($this->context as $name => $value) { - \stream_context_set_option($connection->stream, 'ssl', $name, $value); - } - - // get remote address before starting TLS handshake in case connection closes during handshake - $remote = $connection->getRemoteAddress(); - $that = $this; - - $this->encryption->enable($connection)->then( - function ($conn) use ($that) { - $that->emit('connection', array($conn)); - }, - function ($error) use ($that, $connection, $remote) { - $error = new \RuntimeException( - 'Connection from ' . $remote . ' failed during TLS handshake: ' . $error->getMessage(), - $error->getCode() - ); - - $that->emit('error', array($error)); - $connection->close(); - } - ); - } -} diff --git a/vendor/react/socket/src/Server.php b/vendor/react/socket/src/Server.php deleted file mode 100644 index 7d4111e8e..000000000 --- a/vendor/react/socket/src/Server.php +++ /dev/null @@ -1,114 +0,0 @@ - $context); - } - - // apply default options if not explicitly given - $context += array( - 'tcp' => array(), - 'tls' => array(), - 'unix' => array() - ); - - $scheme = 'tcp'; - $pos = \strpos($uri, '://'); - if ($pos !== false) { - $scheme = \substr($uri, 0, $pos); - } - - if ($scheme === 'unix') { - $server = new UnixServer($uri, $loop, $context['unix']); - } else { - $server = new TcpServer(str_replace('tls://', '', $uri), $loop, $context['tcp']); - - if ($scheme === 'tls') { - $server = new SecureServer($server, $loop, $context['tls']); - } - } - - $this->server = $server; - - $that = $this; - $server->on('connection', function (ConnectionInterface $conn) use ($that) { - $that->emit('connection', array($conn)); - }); - $server->on('error', function (Exception $error) use ($that) { - $that->emit('error', array($error)); - }); - } - - public function getAddress() - { - return $this->server->getAddress(); - } - - public function pause() - { - $this->server->pause(); - } - - public function resume() - { - $this->server->resume(); - } - - public function close() - { - $this->server->close(); - } -} diff --git a/vendor/react/socket/src/ServerInterface.php b/vendor/react/socket/src/ServerInterface.php deleted file mode 100644 index aa79fa17e..000000000 --- a/vendor/react/socket/src/ServerInterface.php +++ /dev/null @@ -1,151 +0,0 @@ -on('connection', function (React\Socket\ConnectionInterface $connection) { - * echo 'new connection' . PHP_EOL; - * }); - * ``` - * - * See also the `ConnectionInterface` for more details about handling the - * incoming connection. - * - * error event: - * The `error` event will be emitted whenever there's an error accepting a new - * connection from a client. - * - * ```php - * $socket->on('error', function (Exception $e) { - * echo 'error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * Note that this is not a fatal error event, i.e. the server keeps listening for - * new connections even after this event. - * - * @see ConnectionInterface - */ -interface ServerInterface extends EventEmitterInterface -{ - /** - * Returns the full address (URI) this server is currently listening on - * - * ```php - * $address = $socket->getAddress(); - * echo 'Server listening on ' . $address . PHP_EOL; - * ``` - * - * If the address can not be determined or is unknown at this time (such as - * after the socket has been closed), it MAY return a `NULL` value instead. - * - * Otherwise, it will return the full address (URI) as a string value, such - * as `tcp://127.0.0.1:8080`, `tcp://[::1]:80` or `tls://127.0.0.1:443`. - * Note that individual URI components are application specific and depend - * on the underlying transport protocol. - * - * If this is a TCP/IP based server and you only want the local port, you may - * use something like this: - * - * ```php - * $address = $socket->getAddress(); - * $port = parse_url($address, PHP_URL_PORT); - * echo 'Server listening on port ' . $port . PHP_EOL; - * ``` - * - * @return ?string the full listening address (URI) or NULL if it is unknown (not applicable to this server socket or already closed) - */ - public function getAddress(); - - /** - * Pauses accepting new incoming connections. - * - * Removes the socket resource from the EventLoop and thus stop accepting - * new connections. Note that the listening socket stays active and is not - * closed. - * - * This means that new incoming connections will stay pending in the - * operating system backlog until its configurable backlog is filled. - * Once the backlog is filled, the operating system may reject further - * incoming connections until the backlog is drained again by resuming - * to accept new connections. - * - * Once the server is paused, no futher `connection` events SHOULD - * be emitted. - * - * ```php - * $socket->pause(); - * - * $socket->on('connection', assertShouldNeverCalled()); - * ``` - * - * This method is advisory-only, though generally not recommended, the - * server MAY continue emitting `connection` events. - * - * Unless otherwise noted, a successfully opened server SHOULD NOT start - * in paused state. - * - * You can continue processing events by calling `resume()` again. - * - * Note that both methods can be called any number of times, in particular - * calling `pause()` more than once SHOULD NOT have any effect. - * Similarly, calling this after `close()` is a NO-OP. - * - * @see self::resume() - * @return void - */ - public function pause(); - - /** - * Resumes accepting new incoming connections. - * - * Re-attach the socket resource to the EventLoop after a previous `pause()`. - * - * ```php - * $socket->pause(); - * - * Loop::addTimer(1.0, function () use ($socket) { - * $socket->resume(); - * }); - * ``` - * - * Note that both methods can be called any number of times, in particular - * calling `resume()` without a prior `pause()` SHOULD NOT have any effect. - * Similarly, calling this after `close()` is a NO-OP. - * - * @see self::pause() - * @return void - */ - public function resume(); - - /** - * Shuts down this listening socket - * - * This will stop listening for new incoming connections on this socket. - * - * Calling this method more than once on the same instance is a NO-OP. - * - * @return void - */ - public function close(); -} diff --git a/vendor/react/socket/src/SocketServer.php b/vendor/react/socket/src/SocketServer.php deleted file mode 100644 index 2ea03baea..000000000 --- a/vendor/react/socket/src/SocketServer.php +++ /dev/null @@ -1,187 +0,0 @@ - array(), - 'tls' => array(), - 'unix' => array() - ); - - $scheme = 'tcp'; - $pos = \strpos($uri, '://'); - if ($pos !== false) { - $scheme = \substr($uri, 0, $pos); - } - - if ($scheme === 'unix') { - $server = new UnixServer($uri, $loop, $context['unix']); - } elseif ($scheme === 'php') { - $server = new FdServer($uri, $loop); - } else { - if (preg_match('#^(?:\w+://)?\d+$#', $uri)) { - throw new \InvalidArgumentException( - 'Invalid URI given (EINVAL)', - \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : 22 - ); - } - - $server = new TcpServer(str_replace('tls://', '', $uri), $loop, $context['tcp']); - - if ($scheme === 'tls') { - $server = new SecureServer($server, $loop, $context['tls']); - } - } - - $this->server = $server; - - $that = $this; - $server->on('connection', function (ConnectionInterface $conn) use ($that) { - $that->emit('connection', array($conn)); - }); - $server->on('error', function (\Exception $error) use ($that) { - $that->emit('error', array($error)); - }); - } - - public function getAddress() - { - return $this->server->getAddress(); - } - - public function pause() - { - $this->server->pause(); - } - - public function resume() - { - $this->server->resume(); - } - - public function close() - { - $this->server->close(); - } - - /** - * [internal] Internal helper method to accept new connection from given server socket - * - * @param resource $socket server socket to accept connection from - * @return resource new client socket if any - * @throws \RuntimeException if accepting fails - * @internal - */ - public static function accept($socket) - { - $newSocket = @\stream_socket_accept($socket, 0); - - if (false === $newSocket) { - // Match errstr from PHP's warning message. - // stream_socket_accept(): accept failed: Connection timed out - $error = \error_get_last(); - $errstr = \preg_replace('#.*: #', '', $error['message']); - $errno = self::errno($errstr); - - throw new \RuntimeException( - 'Unable to accept new connection: ' . $errstr . self::errconst($errno), - $errno - ); - } - - return $newSocket; - } - - /** - * [Internal] Returns errno value for given errstr - * - * The errno and errstr values describes the type of error that has been - * encountered. This method tries to look up the given errstr and find a - * matching errno value which can be useful to provide more context to error - * messages. It goes through the list of known errno constants when - * ext-sockets is available to find an errno matching the given errstr. - * - * @param string $errstr - * @return int errno value (e.g. value of `SOCKET_ECONNREFUSED`) or 0 if not found - * @internal - * @copyright Copyright (c) 2018 Christian Lück, taken from https://github.com/clue/errno with permission - * @codeCoverageIgnore - */ - public static function errno($errstr) - { - if (\function_exists('socket_strerror')) { - foreach (\get_defined_constants(false) as $name => $value) { - if (\strpos($name, 'SOCKET_E') === 0 && \socket_strerror($value) === $errstr) { - return $value; - } - } - } - - return 0; - } - - /** - * [Internal] Returns errno constant name for given errno value - * - * The errno value describes the type of error that has been encountered. - * This method tries to look up the given errno value and find a matching - * errno constant name which can be useful to provide more context and more - * descriptive error messages. It goes through the list of known errno - * constants when ext-sockets is available to find the matching errno - * constant name. - * - * Because this method is used to append more context to error messages, the - * constant name will be prefixed with a space and put between parenthesis - * when found. - * - * @param int $errno - * @return string e.g. ` (ECONNREFUSED)` or empty string if no matching const for the given errno could be found - * @internal - * @copyright Copyright (c) 2018 Christian Lück, taken from https://github.com/clue/errno with permission - * @codeCoverageIgnore - */ - public static function errconst($errno) - { - if (\function_exists('socket_strerror')) { - foreach (\get_defined_constants(false) as $name => $value) { - if ($value === $errno && \strpos($name, 'SOCKET_E') === 0) { - return ' (' . \substr($name, 7) . ')'; - } - } - } - - return ''; - } -} diff --git a/vendor/react/socket/src/StreamEncryption.php b/vendor/react/socket/src/StreamEncryption.php deleted file mode 100644 index 4aa7fca0b..000000000 --- a/vendor/react/socket/src/StreamEncryption.php +++ /dev/null @@ -1,141 +0,0 @@ -loop = $loop; - $this->server = $server; - - // support TLSv1.0+ by default and exclude legacy SSLv2/SSLv3. - // As of PHP 7.2+ the main crypto method constant includes all TLS versions. - // As of PHP 5.6+ the crypto method is a bitmask, so we explicitly include all TLS versions. - // For legacy PHP < 5.6 the crypto method is a single value only and this constant includes all TLS versions. - // @link https://3v4l.org/9PSST - if ($server) { - $this->method = \STREAM_CRYPTO_METHOD_TLS_SERVER; - - if (\PHP_VERSION_ID < 70200 && \PHP_VERSION_ID >= 50600) { - $this->method |= \STREAM_CRYPTO_METHOD_TLSv1_0_SERVER | \STREAM_CRYPTO_METHOD_TLSv1_1_SERVER | \STREAM_CRYPTO_METHOD_TLSv1_2_SERVER; // @codeCoverageIgnore - } - } else { - $this->method = \STREAM_CRYPTO_METHOD_TLS_CLIENT; - - if (\PHP_VERSION_ID < 70200 && \PHP_VERSION_ID >= 50600) { - $this->method |= \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT | \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; // @codeCoverageIgnore - } - } - } - - public function enable(Connection $stream) - { - return $this->toggle($stream, true); - } - - public function toggle(Connection $stream, $toggle) - { - // pause actual stream instance to continue operation on raw stream socket - $stream->pause(); - - // TODO: add write() event to make sure we're not sending any excessive data - - // cancelling this leaves this stream in an inconsistent state… - $deferred = new Deferred(function () { - throw new \RuntimeException(); - }); - - // get actual stream socket from stream instance - $socket = $stream->stream; - - // get crypto method from context options or use global setting from constructor - $method = $this->method; - $context = \stream_context_get_options($socket); - if (isset($context['ssl']['crypto_method'])) { - $method = $context['ssl']['crypto_method']; - } - - $that = $this; - $toggleCrypto = function () use ($socket, $deferred, $toggle, $method, $that) { - $that->toggleCrypto($socket, $deferred, $toggle, $method); - }; - - $this->loop->addReadStream($socket, $toggleCrypto); - - if (!$this->server) { - $toggleCrypto(); - } - - $loop = $this->loop; - - return $deferred->promise()->then(function () use ($stream, $socket, $loop, $toggle) { - $loop->removeReadStream($socket); - - $stream->encryptionEnabled = $toggle; - $stream->resume(); - - return $stream; - }, function($error) use ($stream, $socket, $loop) { - $loop->removeReadStream($socket); - $stream->resume(); - throw $error; - }); - } - - public function toggleCrypto($socket, Deferred $deferred, $toggle, $method) - { - $error = null; - \set_error_handler(function ($_, $errstr) use (&$error) { - $error = \str_replace(array("\r", "\n"), ' ', $errstr); - - // remove useless function name from error message - if (($pos = \strpos($error, "): ")) !== false) { - $error = \substr($error, $pos + 3); - } - }); - - $result = \stream_socket_enable_crypto($socket, $toggle, $method); - - \restore_error_handler(); - - if (true === $result) { - $deferred->resolve(); - } else if (false === $result) { - // overwrite callback arguments for PHP7+ only, so they do not show - // up in the Exception trace and do not cause a possible cyclic reference. - $d = $deferred; - $deferred = null; - - if (\feof($socket) || $error === null) { - // EOF or failed without error => connection closed during handshake - $d->reject(new \UnexpectedValueException( - 'Connection lost during TLS handshake (ECONNRESET)', - \defined('SOCKET_ECONNRESET') ? \SOCKET_ECONNRESET : 104 - )); - } else { - // handshake failed with error message - $d->reject(new \UnexpectedValueException( - $error - )); - } - } else { - // need more data, will retry - } - } -} diff --git a/vendor/react/socket/src/TcpConnector.php b/vendor/react/socket/src/TcpConnector.php deleted file mode 100644 index a4d3b5ba6..000000000 --- a/vendor/react/socket/src/TcpConnector.php +++ /dev/null @@ -1,159 +0,0 @@ -loop = $loop ?: Loop::get(); - $this->context = $context; - } - - public function connect($uri) - { - if (\strpos($uri, '://') === false) { - $uri = 'tcp://' . $uri; - } - - $parts = \parse_url($uri); - if (!$parts || !isset($parts['scheme'], $parts['host'], $parts['port']) || $parts['scheme'] !== 'tcp') { - return Promise\reject(new \InvalidArgumentException( - 'Given URI "' . $uri . '" is invalid (EINVAL)', - \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : 22 - )); - } - - $ip = \trim($parts['host'], '[]'); - if (@\inet_pton($ip) === false) { - return Promise\reject(new \InvalidArgumentException( - 'Given URI "' . $uri . '" does not contain a valid host IP (EINVAL)', - \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : 22 - )); - } - - // use context given in constructor - $context = array( - 'socket' => $this->context - ); - - // parse arguments from query component of URI - $args = array(); - if (isset($parts['query'])) { - \parse_str($parts['query'], $args); - } - - // If an original hostname has been given, use this for TLS setup. - // This can happen due to layers of nested connectors, such as a - // DnsConnector reporting its original hostname. - // These context options are here in case TLS is enabled later on this stream. - // If TLS is not enabled later, this doesn't hurt either. - if (isset($args['hostname'])) { - $context['ssl'] = array( - 'SNI_enabled' => true, - 'peer_name' => $args['hostname'] - ); - - // Legacy PHP < 5.6 ignores peer_name and requires legacy context options instead. - // The SNI_server_name context option has to be set here during construction, - // as legacy PHP ignores any values set later. - // @codeCoverageIgnoreStart - if (\PHP_VERSION_ID < 50600) { - $context['ssl'] += array( - 'SNI_server_name' => $args['hostname'], - 'CN_match' => $args['hostname'] - ); - } - // @codeCoverageIgnoreEnd - } - - // latest versions of PHP no longer accept any other URI components and - // HHVM fails to parse URIs with a query but no path, so let's simplify our URI here - $remote = 'tcp://' . $parts['host'] . ':' . $parts['port']; - - $stream = @\stream_socket_client( - $remote, - $errno, - $errstr, - 0, - \STREAM_CLIENT_CONNECT | \STREAM_CLIENT_ASYNC_CONNECT, - \stream_context_create($context) - ); - - if (false === $stream) { - return Promise\reject(new \RuntimeException( - 'Connection to ' . $uri . ' failed: ' . $errstr . SocketServer::errconst($errno), - $errno - )); - } - - // wait for connection - $loop = $this->loop; - return new Promise\Promise(function ($resolve, $reject) use ($loop, $stream, $uri) { - $loop->addWriteStream($stream, function ($stream) use ($loop, $resolve, $reject, $uri) { - $loop->removeWriteStream($stream); - - // The following hack looks like the only way to - // detect connection refused errors with PHP's stream sockets. - if (false === \stream_socket_get_name($stream, true)) { - // If we reach this point, we know the connection is dead, but we don't know the underlying error condition. - // @codeCoverageIgnoreStart - if (\function_exists('socket_import_stream')) { - // actual socket errno and errstr can be retrieved with ext-sockets on PHP 5.4+ - $socket = \socket_import_stream($stream); - $errno = \socket_get_option($socket, \SOL_SOCKET, \SO_ERROR); - $errstr = \socket_strerror($errno); - } elseif (\PHP_OS === 'Linux') { - // Linux reports socket errno and errstr again when trying to write to the dead socket. - // Suppress error reporting to get error message below and close dead socket before rejecting. - // This is only known to work on Linux, Mac and Windows are known to not support this. - @\fwrite($stream, \PHP_EOL); - $error = \error_get_last(); - - // fwrite(): send of 2 bytes failed with errno=111 Connection refused - \preg_match('/errno=(\d+) (.+)/', $error['message'], $m); - $errno = isset($m[1]) ? (int) $m[1] : 0; - $errstr = isset($m[2]) ? $m[2] : $error['message']; - } else { - // Not on Linux and ext-sockets not available? Too bad. - $errno = \defined('SOCKET_ECONNREFUSED') ? \SOCKET_ECONNREFUSED : 111; - $errstr = 'Connection refused?'; - } - // @codeCoverageIgnoreEnd - - \fclose($stream); - $reject(new \RuntimeException( - 'Connection to ' . $uri . ' failed: ' . $errstr . SocketServer::errconst($errno), - $errno - )); - } else { - $resolve(new Connection($stream, $loop)); - } - }); - }, function () use ($loop, $stream, $uri) { - $loop->removeWriteStream($stream); - \fclose($stream); - - // @codeCoverageIgnoreStart - // legacy PHP 5.3 sometimes requires a second close call (see tests) - if (\PHP_VERSION_ID < 50400 && \is_resource($stream)) { - \fclose($stream); - } - // @codeCoverageIgnoreEnd - - throw new \RuntimeException( - 'Connection to ' . $uri . ' cancelled during TCP/IP handshake (ECONNABORTED)', - \defined('SOCKET_ECONNABORTED') ? \SOCKET_ECONNABORTED : 103 - ); - }); - } -} diff --git a/vendor/react/socket/src/TcpServer.php b/vendor/react/socket/src/TcpServer.php deleted file mode 100644 index 442af702b..000000000 --- a/vendor/react/socket/src/TcpServer.php +++ /dev/null @@ -1,258 +0,0 @@ -on('connection', function (React\Socket\ConnectionInterface $connection) { - * echo 'Plaintext connection from ' . $connection->getRemoteAddress() . PHP_EOL; - * $connection->write('hello there!' . PHP_EOL); - * … - * }); - * ``` - * - * See also the `ServerInterface` for more details. - * - * @see ServerInterface - * @see ConnectionInterface - */ -final class TcpServer extends EventEmitter implements ServerInterface -{ - private $master; - private $loop; - private $listening = false; - - /** - * Creates a plaintext TCP/IP socket server and starts listening on the given address - * - * This starts accepting new incoming connections on the given address. - * See also the `connection event` documented in the `ServerInterface` - * for more details. - * - * ```php - * $server = new React\Socket\TcpServer(8080); - * ``` - * - * As above, the `$uri` parameter can consist of only a port, in which case the - * server will default to listening on the localhost address `127.0.0.1`, - * which means it will not be reachable from outside of this system. - * - * In order to use a random port assignment, you can use the port `0`: - * - * ```php - * $server = new React\Socket\TcpServer(0); - * $address = $server->getAddress(); - * ``` - * - * In order to change the host the socket is listening on, you can provide an IP - * address through the first parameter provided to the constructor, optionally - * preceded by the `tcp://` scheme: - * - * ```php - * $server = new React\Socket\TcpServer('192.168.0.1:8080'); - * ``` - * - * If you want to listen on an IPv6 address, you MUST enclose the host in square - * brackets: - * - * ```php - * $server = new React\Socket\TcpServer('[::1]:8080'); - * ``` - * - * If the given URI is invalid, does not contain a port, any other scheme or if it - * contains a hostname, it will throw an `InvalidArgumentException`: - * - * ```php - * // throws InvalidArgumentException due to missing port - * $server = new React\Socket\TcpServer('127.0.0.1'); - * ``` - * - * If the given URI appears to be valid, but listening on it fails (such as if port - * is already in use or port below 1024 may require root access etc.), it will - * throw a `RuntimeException`: - * - * ```php - * $first = new React\Socket\TcpServer(8080); - * - * // throws RuntimeException because port is already in use - * $second = new React\Socket\TcpServer(8080); - * ``` - * - * Note that these error conditions may vary depending on your system and/or - * configuration. - * See the exception message and code for more details about the actual error - * condition. - * - * This class takes an optional `LoopInterface|null $loop` parameter that can be used to - * pass the event loop instance to use for this object. You can use a `null` value - * here in order to use the [default loop](https://github.com/reactphp/event-loop#loop). - * This value SHOULD NOT be given unless you're sure you want to explicitly use a - * given event loop instance. - * - * Optionally, you can specify [socket context options](https://www.php.net/manual/en/context.socket.php) - * for the underlying stream socket resource like this: - * - * ```php - * $server = new React\Socket\TcpServer('[::1]:8080', null, array( - * 'backlog' => 200, - * 'so_reuseport' => true, - * 'ipv6_v6only' => true - * )); - * ``` - * - * Note that available [socket context options](https://www.php.net/manual/en/context.socket.php), - * their defaults and effects of changing these may vary depending on your system - * and/or PHP version. - * Passing unknown context options has no effect. - * The `backlog` context option defaults to `511` unless given explicitly. - * - * @param string|int $uri - * @param ?LoopInterface $loop - * @param array $context - * @throws InvalidArgumentException if the listening address is invalid - * @throws RuntimeException if listening on this address fails (already in use etc.) - */ - public function __construct($uri, LoopInterface $loop = null, array $context = array()) - { - $this->loop = $loop ?: Loop::get(); - - // a single port has been given => assume localhost - if ((string)(int)$uri === (string)$uri) { - $uri = '127.0.0.1:' . $uri; - } - - // assume default scheme if none has been given - if (\strpos($uri, '://') === false) { - $uri = 'tcp://' . $uri; - } - - // parse_url() does not accept null ports (random port assignment) => manually remove - if (\substr($uri, -2) === ':0') { - $parts = \parse_url(\substr($uri, 0, -2)); - if ($parts) { - $parts['port'] = 0; - } - } else { - $parts = \parse_url($uri); - } - - // ensure URI contains TCP scheme, host and port - if (!$parts || !isset($parts['scheme'], $parts['host'], $parts['port']) || $parts['scheme'] !== 'tcp') { - throw new \InvalidArgumentException( - 'Invalid URI "' . $uri . '" given (EINVAL)', - \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : 22 - ); - } - - if (@\inet_pton(\trim($parts['host'], '[]')) === false) { - throw new \InvalidArgumentException( - 'Given URI "' . $uri . '" does not contain a valid host IP (EINVAL)', - \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : 22 - ); - } - - $this->master = @\stream_socket_server( - $uri, - $errno, - $errstr, - \STREAM_SERVER_BIND | \STREAM_SERVER_LISTEN, - \stream_context_create(array('socket' => $context + array('backlog' => 511))) - ); - if (false === $this->master) { - if ($errno === 0) { - // PHP does not seem to report errno, so match errno from errstr - // @link https://3v4l.org/3qOBl - $errno = SocketServer::errno($errstr); - } - - throw new \RuntimeException( - 'Failed to listen on "' . $uri . '": ' . $errstr . SocketServer::errconst($errno), - $errno - ); - } - \stream_set_blocking($this->master, false); - - $this->resume(); - } - - public function getAddress() - { - if (!\is_resource($this->master)) { - return null; - } - - $address = \stream_socket_get_name($this->master, false); - - // check if this is an IPv6 address which includes multiple colons but no square brackets - $pos = \strrpos($address, ':'); - if ($pos !== false && \strpos($address, ':') < $pos && \substr($address, 0, 1) !== '[') { - $address = '[' . \substr($address, 0, $pos) . ']:' . \substr($address, $pos + 1); // @codeCoverageIgnore - } - - return 'tcp://' . $address; - } - - public function pause() - { - if (!$this->listening) { - return; - } - - $this->loop->removeReadStream($this->master); - $this->listening = false; - } - - public function resume() - { - if ($this->listening || !\is_resource($this->master)) { - return; - } - - $that = $this; - $this->loop->addReadStream($this->master, function ($master) use ($that) { - try { - $newSocket = SocketServer::accept($master); - } catch (\RuntimeException $e) { - $that->emit('error', array($e)); - return; - } - $that->handleConnection($newSocket); - }); - $this->listening = true; - } - - public function close() - { - if (!\is_resource($this->master)) { - return; - } - - $this->pause(); - \fclose($this->master); - $this->removeAllListeners(); - } - - /** @internal */ - public function handleConnection($socket) - { - $this->emit('connection', array( - new Connection($socket, $this->loop) - )); - } -} diff --git a/vendor/react/socket/src/TimeoutConnector.php b/vendor/react/socket/src/TimeoutConnector.php deleted file mode 100644 index 332369f84..000000000 --- a/vendor/react/socket/src/TimeoutConnector.php +++ /dev/null @@ -1,51 +0,0 @@ -connector = $connector; - $this->timeout = $timeout; - $this->loop = $loop ?: Loop::get(); - } - - public function connect($uri) - { - return Timer\timeout($this->connector->connect($uri), $this->timeout, $this->loop)->then(null, self::handler($uri)); - } - - /** - * Creates a static rejection handler that reports a proper error message in case of a timeout. - * - * This uses a private static helper method to ensure this closure is not - * bound to this instance and the exception trace does not include a - * reference to this instance and its connector stack as a result. - * - * @param string $uri - * @return callable - */ - private static function handler($uri) - { - return function (\Exception $e) use ($uri) { - if ($e instanceof TimeoutException) { - throw new \RuntimeException( - 'Connection to ' . $uri . ' timed out after ' . $e->getTimeout() . ' seconds (ETIMEDOUT)', - \defined('SOCKET_ETIMEDOUT') ? \SOCKET_ETIMEDOUT : 110 - ); - } - - throw $e; - }; - } -} diff --git a/vendor/react/socket/src/UnixConnector.php b/vendor/react/socket/src/UnixConnector.php deleted file mode 100644 index 513fb51b9..000000000 --- a/vendor/react/socket/src/UnixConnector.php +++ /dev/null @@ -1,51 +0,0 @@ -loop = $loop ?: Loop::get(); - } - - public function connect($path) - { - if (\strpos($path, '://') === false) { - $path = 'unix://' . $path; - } elseif (\substr($path, 0, 7) !== 'unix://') { - return Promise\reject(new \InvalidArgumentException( - 'Given URI "' . $path . '" is invalid (EINVAL)', - \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : 22 - )); - } - - $resource = @\stream_socket_client($path, $errno, $errstr, 1.0); - - if (!$resource) { - return Promise\reject(new \RuntimeException( - 'Unable to connect to unix domain socket "' . $path . '": ' . $errstr . SocketServer::errconst($errno), - $errno - )); - } - - $connection = new Connection($resource, $this->loop); - $connection->unix = true; - - return Promise\resolve($connection); - } -} diff --git a/vendor/react/socket/src/UnixServer.php b/vendor/react/socket/src/UnixServer.php deleted file mode 100644 index 668e8cb3a..000000000 --- a/vendor/react/socket/src/UnixServer.php +++ /dev/null @@ -1,154 +0,0 @@ -loop = $loop ?: Loop::get(); - - if (\strpos($path, '://') === false) { - $path = 'unix://' . $path; - } elseif (\substr($path, 0, 7) !== 'unix://') { - throw new \InvalidArgumentException( - 'Given URI "' . $path . '" is invalid (EINVAL)', - \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : 22 - ); - } - - $this->master = @\stream_socket_server( - $path, - $errno, - $errstr, - \STREAM_SERVER_BIND | \STREAM_SERVER_LISTEN, - \stream_context_create(array('socket' => $context)) - ); - if (false === $this->master) { - // PHP does not seem to report errno/errstr for Unix domain sockets (UDS) right now. - // This only applies to UDS server sockets, see also https://3v4l.org/NAhpr. - // Parse PHP warning message containing unknown error, HHVM reports proper info at least. - if ($errno === 0 && $errstr === '') { - $error = \error_get_last(); - if (\preg_match('/\(([^\)]+)\)|\[(\d+)\]: (.*)/', $error['message'], $match)) { - $errstr = isset($match[3]) ? $match['3'] : $match[1]; - $errno = isset($match[2]) ? (int)$match[2] : 0; - } - } - - throw new \RuntimeException( - 'Failed to listen on Unix domain socket "' . $path . '": ' . $errstr . SocketServer::errconst($errno), - $errno - ); - } - \stream_set_blocking($this->master, 0); - - $this->resume(); - } - - public function getAddress() - { - if (!\is_resource($this->master)) { - return null; - } - - return 'unix://' . \stream_socket_get_name($this->master, false); - } - - public function pause() - { - if (!$this->listening) { - return; - } - - $this->loop->removeReadStream($this->master); - $this->listening = false; - } - - public function resume() - { - if ($this->listening || !is_resource($this->master)) { - return; - } - - $that = $this; - $this->loop->addReadStream($this->master, function ($master) use ($that) { - try { - $newSocket = SocketServer::accept($master); - } catch (\RuntimeException $e) { - $that->emit('error', array($e)); - return; - } - $that->handleConnection($newSocket); - }); - $this->listening = true; - } - - public function close() - { - if (!\is_resource($this->master)) { - return; - } - - $this->pause(); - \fclose($this->master); - $this->removeAllListeners(); - } - - /** @internal */ - public function handleConnection($socket) - { - $connection = new Connection($socket, $this->loop); - $connection->unix = true; - - $this->emit('connection', array( - $connection - )); - } -} diff --git a/vendor/react/stream/src/CompositeStream.php b/vendor/react/stream/src/CompositeStream.php deleted file mode 100644 index dde091de0..000000000 --- a/vendor/react/stream/src/CompositeStream.php +++ /dev/null @@ -1,83 +0,0 @@ -readable = $readable; - $this->writable = $writable; - - if (!$readable->isReadable() || !$writable->isWritable()) { - $this->close(); - return; - } - - Util::forwardEvents($this->readable, $this, array('data', 'end', 'error')); - Util::forwardEvents($this->writable, $this, array('drain', 'error', 'pipe')); - - $this->readable->on('close', array($this, 'close')); - $this->writable->on('close', array($this, 'close')); - } - - public function isReadable() - { - return $this->readable->isReadable(); - } - - public function pause() - { - $this->readable->pause(); - } - - public function resume() - { - if (!$this->writable->isWritable()) { - return; - } - - $this->readable->resume(); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - return Util::pipe($this, $dest, $options); - } - - public function isWritable() - { - return $this->writable->isWritable(); - } - - public function write($data) - { - return $this->writable->write($data); - } - - public function end($data = null) - { - $this->readable->pause(); - $this->writable->end($data); - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->closed = true; - $this->readable->close(); - $this->writable->close(); - - $this->emit('close'); - $this->removeAllListeners(); - } -} diff --git a/vendor/react/stream/src/DuplexResourceStream.php b/vendor/react/stream/src/DuplexResourceStream.php deleted file mode 100644 index c3163c639..000000000 --- a/vendor/react/stream/src/DuplexResourceStream.php +++ /dev/null @@ -1,227 +0,0 @@ -isLegacyPipe($stream)) { - \stream_set_read_buffer($stream, 0); - } - - if ($buffer === null) { - $buffer = new WritableResourceStream($stream, $loop); - } - - $this->stream = $stream; - $this->loop = $loop ?: Loop::get(); - $this->bufferSize = ($readChunkSize === null) ? 65536 : (int)$readChunkSize; - $this->buffer = $buffer; - - $that = $this; - - $this->buffer->on('error', function ($error) use ($that) { - $that->emit('error', array($error)); - }); - - $this->buffer->on('close', array($this, 'close')); - - $this->buffer->on('drain', function () use ($that) { - $that->emit('drain'); - }); - - $this->resume(); - } - - public function isReadable() - { - return $this->readable; - } - - public function isWritable() - { - return $this->writable; - } - - public function pause() - { - if ($this->listening) { - $this->loop->removeReadStream($this->stream); - $this->listening = false; - } - } - - public function resume() - { - if (!$this->listening && $this->readable) { - $this->loop->addReadStream($this->stream, array($this, 'handleData')); - $this->listening = true; - } - } - - public function write($data) - { - if (!$this->writable) { - return false; - } - - return $this->buffer->write($data); - } - - public function close() - { - if (!$this->writable && !$this->closing) { - return; - } - - $this->closing = false; - - $this->readable = false; - $this->writable = false; - - $this->emit('close'); - $this->pause(); - $this->buffer->close(); - $this->removeAllListeners(); - - if (\is_resource($this->stream)) { - \fclose($this->stream); - } - } - - public function end($data = null) - { - if (!$this->writable) { - return; - } - - $this->closing = true; - - $this->readable = false; - $this->writable = false; - $this->pause(); - - $this->buffer->end($data); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - return Util::pipe($this, $dest, $options); - } - - /** @internal */ - public function handleData($stream) - { - $error = null; - \set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error) { - $error = new \ErrorException( - $errstr, - 0, - $errno, - $errfile, - $errline - ); - }); - - $data = \stream_get_contents($stream, $this->bufferSize); - - \restore_error_handler(); - - if ($error !== null) { - $this->emit('error', array(new \RuntimeException('Unable to read from stream: ' . $error->getMessage(), 0, $error))); - $this->close(); - return; - } - - if ($data !== '') { - $this->emit('data', array($data)); - } elseif (\feof($this->stream)) { - // no data read => we reached the end and close the stream - $this->emit('end'); - $this->close(); - } - } - - /** - * Returns whether this is a pipe resource in a legacy environment - * - * This works around a legacy PHP bug (#61019) that was fixed in PHP 5.4.28+ - * and PHP 5.5.12+ and newer. - * - * @param resource $resource - * @return bool - * @link https://github.com/reactphp/child-process/issues/40 - * - * @codeCoverageIgnore - */ - private function isLegacyPipe($resource) - { - if (\PHP_VERSION_ID < 50428 || (\PHP_VERSION_ID >= 50500 && \PHP_VERSION_ID < 50512)) { - $meta = \stream_get_meta_data($resource); - - if (isset($meta['stream_type']) && $meta['stream_type'] === 'STDIO') { - return true; - } - } - return false; - } -} diff --git a/vendor/react/stream/src/DuplexStreamInterface.php b/vendor/react/stream/src/DuplexStreamInterface.php deleted file mode 100644 index 631ce31e8..000000000 --- a/vendor/react/stream/src/DuplexStreamInterface.php +++ /dev/null @@ -1,39 +0,0 @@ - Note that higher-level implementations of this interface may choose to - * define additional events with dedicated semantics not defined as part of - * this low-level stream specification. Conformance with these event semantics - * is out of scope for this interface, so you may also have to refer to the - * documentation of such a higher-level implementation. - * - * @see ReadableStreamInterface - * @see WritableStreamInterface - */ -interface DuplexStreamInterface extends ReadableStreamInterface, WritableStreamInterface -{ -} diff --git a/vendor/react/stream/src/ReadableResourceStream.php b/vendor/react/stream/src/ReadableResourceStream.php deleted file mode 100644 index 1b0b08c99..000000000 --- a/vendor/react/stream/src/ReadableResourceStream.php +++ /dev/null @@ -1,179 +0,0 @@ -isLegacyPipe($stream)) { - \stream_set_read_buffer($stream, 0); - } - - $this->stream = $stream; - $this->loop = $loop ?: Loop::get(); - $this->bufferSize = ($readChunkSize === null) ? 65536 : (int)$readChunkSize; - - $this->resume(); - } - - public function isReadable() - { - return !$this->closed; - } - - public function pause() - { - if ($this->listening) { - $this->loop->removeReadStream($this->stream); - $this->listening = false; - } - } - - public function resume() - { - if (!$this->listening && !$this->closed) { - $this->loop->addReadStream($this->stream, array($this, 'handleData')); - $this->listening = true; - } - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - return Util::pipe($this, $dest, $options); - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->closed = true; - - $this->emit('close'); - $this->pause(); - $this->removeAllListeners(); - - if (\is_resource($this->stream)) { - \fclose($this->stream); - } - } - - /** @internal */ - public function handleData() - { - $error = null; - \set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error) { - $error = new \ErrorException( - $errstr, - 0, - $errno, - $errfile, - $errline - ); - }); - - $data = \stream_get_contents($this->stream, $this->bufferSize); - - \restore_error_handler(); - - if ($error !== null) { - $this->emit('error', array(new \RuntimeException('Unable to read from stream: ' . $error->getMessage(), 0, $error))); - $this->close(); - return; - } - - if ($data !== '') { - $this->emit('data', array($data)); - } elseif (\feof($this->stream)) { - // no data read => we reached the end and close the stream - $this->emit('end'); - $this->close(); - } - } - - /** - * Returns whether this is a pipe resource in a legacy environment - * - * This works around a legacy PHP bug (#61019) that was fixed in PHP 5.4.28+ - * and PHP 5.5.12+ and newer. - * - * @param resource $resource - * @return bool - * @link https://github.com/reactphp/child-process/issues/40 - * - * @codeCoverageIgnore - */ - private function isLegacyPipe($resource) - { - if (\PHP_VERSION_ID < 50428 || (\PHP_VERSION_ID >= 50500 && \PHP_VERSION_ID < 50512)) { - $meta = \stream_get_meta_data($resource); - - if (isset($meta['stream_type']) && $meta['stream_type'] === 'STDIO') { - return true; - } - } - return false; - } -} diff --git a/vendor/react/stream/src/ReadableStreamInterface.php b/vendor/react/stream/src/ReadableStreamInterface.php deleted file mode 100644 index fa3d59cdb..000000000 --- a/vendor/react/stream/src/ReadableStreamInterface.php +++ /dev/null @@ -1,362 +0,0 @@ -on('data', function ($data) { - * echo $data; - * }); - * ``` - * - * This event MAY be emitted any number of times, which may be zero times if - * this stream does not send any data at all. - * It SHOULD not be emitted after an `end` or `close` event. - * - * The given `$data` argument may be of mixed type, but it's usually - * recommended it SHOULD be a `string` value or MAY use a type that allows - * representation as a `string` for maximum compatibility. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * will emit the raw (binary) payload data that is received over the wire as - * chunks of `string` values. - * - * Due to the stream-based nature of this, the sender may send any number - * of chunks with varying sizes. There are no guarantees that these chunks - * will be received with the exact same framing the sender intended to send. - * In other words, many lower-level protocols (such as TCP/IP) transfer the - * data in chunks that may be anywhere between single-byte values to several - * dozens of kilobytes. You may want to apply a higher-level protocol to - * these low-level data chunks in order to achieve proper message framing. - * - * end event: - * The `end` event will be emitted once the source stream has successfully - * reached the end of the stream (EOF). - * - * ```php - * $stream->on('end', function () { - * echo 'END'; - * }); - * ``` - * - * This event SHOULD be emitted once or never at all, depending on whether - * a successful end was detected. - * It SHOULD NOT be emitted after a previous `end` or `close` event. - * It MUST NOT be emitted if the stream closes due to a non-successful - * end, such as after a previous `error` event. - * - * After the stream is ended, it MUST switch to non-readable mode, - * see also `isReadable()`. - * - * This event will only be emitted if the *end* was reached successfully, - * not if the stream was interrupted by an unrecoverable error or explicitly - * closed. Not all streams know this concept of a "successful end". - * Many use-cases involve detecting when the stream closes (terminates) - * instead, in this case you should use the `close` event. - * After the stream emits an `end` event, it SHOULD usually be followed by a - * `close` event. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * will emit this event if either the remote side closes the connection or - * a file handle was successfully read until reaching its end (EOF). - * - * Note that this event should not be confused with the `end()` method. - * This event defines a successful end *reading* from a source stream, while - * the `end()` method defines *writing* a successful end to a destination - * stream. - * - * error event: - * The `error` event will be emitted once a fatal error occurs, usually while - * trying to read from this stream. - * The event receives a single `Exception` argument for the error instance. - * - * ```php - * $stream->on('error', function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * This event SHOULD be emitted once the stream detects a fatal error, such - * as a fatal transmission error or after an unexpected `data` or premature - * `end` event. - * It SHOULD NOT be emitted after a previous `error`, `end` or `close` event. - * It MUST NOT be emitted if this is not a fatal error condition, such as - * a temporary network issue that did not cause any data to be lost. - * - * After the stream errors, it MUST close the stream and SHOULD thus be - * followed by a `close` event and then switch to non-readable mode, see - * also `close()` and `isReadable()`. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * only deal with data transmission and do not make assumption about data - * boundaries (such as unexpected `data` or premature `end` events). - * In other words, many lower-level protocols (such as TCP/IP) may choose - * to only emit this for a fatal transmission error once and will then - * close (terminate) the stream in response. - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the writable side of the stream also implements an `error` event. - * In other words, an error may occur while either reading or writing the - * stream which should result in the same error processing. - * - * close event: - * The `close` event will be emitted once the stream closes (terminates). - * - * ```php - * $stream->on('close', function () { - * echo 'CLOSED'; - * }); - * ``` - * - * This event SHOULD be emitted once or never at all, depending on whether - * the stream ever terminates. - * It SHOULD NOT be emitted after a previous `close` event. - * - * After the stream is closed, it MUST switch to non-readable mode, - * see also `isReadable()`. - * - * Unlike the `end` event, this event SHOULD be emitted whenever the stream - * closes, irrespective of whether this happens implicitly due to an - * unrecoverable error or explicitly when either side closes the stream. - * If you only want to detect a *successful* end, you should use the `end` - * event instead. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * will likely choose to emit this event after reading a *successful* `end` - * event or after a fatal transmission `error` event. - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the writable side of the stream also implements a `close` event. - * In other words, after receiving this event, the stream MUST switch into - * non-writable AND non-readable mode, see also `isWritable()`. - * Note that this event should not be confused with the `end` event. - * - * The event callback functions MUST be a valid `callable` that obeys strict - * parameter definitions and MUST accept event parameters exactly as documented. - * The event callback functions MUST NOT throw an `Exception`. - * The return value of the event callback functions will be ignored and has no - * effect, so for performance reasons you're recommended to not return any - * excessive data structures. - * - * Every implementation of this interface MUST follow these event semantics in - * order to be considered a well-behaving stream. - * - * > Note that higher-level implementations of this interface may choose to - * define additional events with dedicated semantics not defined as part of - * this low-level stream specification. Conformance with these event semantics - * is out of scope for this interface, so you may also have to refer to the - * documentation of such a higher-level implementation. - * - * @see EventEmitterInterface - */ -interface ReadableStreamInterface extends EventEmitterInterface -{ - /** - * Checks whether this stream is in a readable state (not closed already). - * - * This method can be used to check if the stream still accepts incoming - * data events or if it is ended or closed already. - * Once the stream is non-readable, no further `data` or `end` events SHOULD - * be emitted. - * - * ```php - * assert($stream->isReadable() === false); - * - * $stream->on('data', assertNeverCalled()); - * $stream->on('end', assertNeverCalled()); - * ``` - * - * A successfully opened stream always MUST start in readable mode. - * - * Once the stream ends or closes, it MUST switch to non-readable mode. - * This can happen any time, explicitly through `close()` or - * implicitly due to a remote close or an unrecoverable transmission error. - * Once a stream has switched to non-readable mode, it MUST NOT transition - * back to readable mode. - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the writable side of the stream also implements an `isWritable()` - * method. Unless this is a half-open duplex stream, they SHOULD usually - * have the same return value. - * - * @return bool - */ - public function isReadable(); - - /** - * Pauses reading incoming data events. - * - * Removes the data source file descriptor from the event loop. This - * allows you to throttle incoming data. - * - * Unless otherwise noted, a successfully opened stream SHOULD NOT start - * in paused state. - * - * Once the stream is paused, no futher `data` or `end` events SHOULD - * be emitted. - * - * ```php - * $stream->pause(); - * - * $stream->on('data', assertShouldNeverCalled()); - * $stream->on('end', assertShouldNeverCalled()); - * ``` - * - * This method is advisory-only, though generally not recommended, the - * stream MAY continue emitting `data` events. - * - * You can continue processing events by calling `resume()` again. - * - * Note that both methods can be called any number of times, in particular - * calling `pause()` more than once SHOULD NOT have any effect. - * - * @see self::resume() - * @return void - */ - public function pause(); - - /** - * Resumes reading incoming data events. - * - * Re-attach the data source after a previous `pause()`. - * - * ```php - * $stream->pause(); - * - * Loop::addTimer(1.0, function () use ($stream) { - * $stream->resume(); - * }); - * ``` - * - * Note that both methods can be called any number of times, in particular - * calling `resume()` without a prior `pause()` SHOULD NOT have any effect. - * - * @see self::pause() - * @return void - */ - public function resume(); - - /** - * Pipes all the data from this readable source into the given writable destination. - * - * Automatically sends all incoming data to the destination. - * Automatically throttles the source based on what the destination can handle. - * - * ```php - * $source->pipe($dest); - * ``` - * - * Similarly, you can also pipe an instance implementing `DuplexStreamInterface` - * into itself in order to write back all the data that is received. - * This may be a useful feature for a TCP/IP echo service: - * - * ```php - * $connection->pipe($connection); - * ``` - * - * This method returns the destination stream as-is, which can be used to - * set up chains of piped streams: - * - * ```php - * $source->pipe($decodeGzip)->pipe($filterBadWords)->pipe($dest); - * ``` - * - * By default, this will call `end()` on the destination stream once the - * source stream emits an `end` event. This can be disabled like this: - * - * ```php - * $source->pipe($dest, array('end' => false)); - * ``` - * - * Note that this only applies to the `end` event. - * If an `error` or explicit `close` event happens on the source stream, - * you'll have to manually close the destination stream: - * - * ```php - * $source->pipe($dest); - * $source->on('close', function () use ($dest) { - * $dest->end('BYE!'); - * }); - * ``` - * - * If the source stream is not readable (closed state), then this is a NO-OP. - * - * ```php - * $source->close(); - * $source->pipe($dest); // NO-OP - * ``` - * - * If the destinantion stream is not writable (closed state), then this will simply - * throttle (pause) the source stream: - * - * ```php - * $dest->close(); - * $source->pipe($dest); // calls $source->pause() - * ``` - * - * Similarly, if the destination stream is closed while the pipe is still - * active, it will also throttle (pause) the source stream: - * - * ```php - * $source->pipe($dest); - * $dest->close(); // calls $source->pause() - * ``` - * - * Once the pipe is set up successfully, the destination stream MUST emit - * a `pipe` event with this source stream an event argument. - * - * @param WritableStreamInterface $dest - * @param array $options - * @return WritableStreamInterface $dest stream as-is - */ - public function pipe(WritableStreamInterface $dest, array $options = array()); - - /** - * Closes the stream (forcefully). - * - * This method can be used to (forcefully) close the stream. - * - * ```php - * $stream->close(); - * ``` - * - * Once the stream is closed, it SHOULD emit a `close` event. - * Note that this event SHOULD NOT be emitted more than once, in particular - * if this method is called multiple times. - * - * After calling this method, the stream MUST switch into a non-readable - * mode, see also `isReadable()`. - * This means that no further `data` or `end` events SHOULD be emitted. - * - * ```php - * $stream->close(); - * assert($stream->isReadable() === false); - * - * $stream->on('data', assertNeverCalled()); - * $stream->on('end', assertNeverCalled()); - * ``` - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the writable side of the stream also implements a `close()` method. - * In other words, after calling this method, the stream MUST switch into - * non-writable AND non-readable mode, see also `isWritable()`. - * Note that this method should not be confused with the `end()` method. - * - * @return void - * @see WritableStreamInterface::close() - */ - public function close(); -} diff --git a/vendor/react/stream/src/ThroughStream.php b/vendor/react/stream/src/ThroughStream.php deleted file mode 100644 index 6f73fb8f0..000000000 --- a/vendor/react/stream/src/ThroughStream.php +++ /dev/null @@ -1,190 +0,0 @@ -on('data', $this->expectCallableOnceWith('hello')); - * - * $through->write('hello'); - * ``` - * - * Similarly, the [`end()` method](#end) will end the stream and emit an - * [`end` event](#end-event) and then [`close()`](#close-1) the stream. - * The [`close()` method](#close-1) will close the stream and emit a - * [`close` event](#close-event). - * Accordingly, this is can also be used in a [`pipe()`](#pipe) context like this: - * - * ```php - * $through = new ThroughStream(); - * $source->pipe($through)->pipe($dest); - * ``` - * - * Optionally, its constructor accepts any callable function which will then be - * used to *filter* any data written to it. This function receives a single data - * argument as passed to the writable side and must return the data as it will be - * passed to its readable end: - * - * ```php - * $through = new ThroughStream('strtoupper'); - * $source->pipe($through)->pipe($dest); - * ``` - * - * Note that this class makes no assumptions about any data types. This can be - * used to convert data, for example for transforming any structured data into - * a newline-delimited JSON (NDJSON) stream like this: - * - * ```php - * $through = new ThroughStream(function ($data) { - * return json_encode($data) . PHP_EOL; - * }); - * $through->on('data', $this->expectCallableOnceWith("[2, true]\n")); - * - * $through->write(array(2, true)); - * ``` - * - * The callback function is allowed to throw an `Exception`. In this case, - * the stream will emit an `error` event and then [`close()`](#close-1) the stream. - * - * ```php - * $through = new ThroughStream(function ($data) { - * if (!is_string($data)) { - * throw new \UnexpectedValueException('Only strings allowed'); - * } - * return $data; - * }); - * $through->on('error', $this->expectCallableOnce())); - * $through->on('close', $this->expectCallableOnce())); - * $through->on('data', $this->expectCallableNever())); - * - * $through->write(2); - * ``` - * - * @see WritableStreamInterface::write() - * @see WritableStreamInterface::end() - * @see DuplexStreamInterface::close() - * @see WritableStreamInterface::pipe() - */ -final class ThroughStream extends EventEmitter implements DuplexStreamInterface -{ - private $readable = true; - private $writable = true; - private $closed = false; - private $paused = false; - private $drain = false; - private $callback; - - public function __construct($callback = null) - { - if ($callback !== null && !\is_callable($callback)) { - throw new InvalidArgumentException('Invalid transformation callback given'); - } - - $this->callback = $callback; - } - - public function pause() - { - $this->paused = true; - } - - public function resume() - { - if ($this->drain) { - $this->drain = false; - $this->emit('drain'); - } - $this->paused = false; - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - return Util::pipe($this, $dest, $options); - } - - public function isReadable() - { - return $this->readable; - } - - public function isWritable() - { - return $this->writable; - } - - public function write($data) - { - if (!$this->writable) { - return false; - } - - if ($this->callback !== null) { - try { - $data = \call_user_func($this->callback, $data); - } catch (\Exception $e) { - $this->emit('error', array($e)); - $this->close(); - - return false; - } - } - - $this->emit('data', array($data)); - - if ($this->paused) { - $this->drain = true; - return false; - } - - return true; - } - - public function end($data = null) - { - if (!$this->writable) { - return; - } - - if (null !== $data) { - $this->write($data); - - // return if write() already caused the stream to close - if (!$this->writable) { - return; - } - } - - $this->readable = false; - $this->writable = false; - $this->paused = true; - $this->drain = false; - - $this->emit('end'); - $this->close(); - } - - public function close() - { - if ($this->closed) { - return; - } - - $this->readable = false; - $this->writable = false; - $this->closed = true; - $this->paused = true; - $this->drain = false; - $this->callback = null; - - $this->emit('close'); - $this->removeAllListeners(); - } -} diff --git a/vendor/react/stream/src/Util.php b/vendor/react/stream/src/Util.php deleted file mode 100644 index 056b03774..000000000 --- a/vendor/react/stream/src/Util.php +++ /dev/null @@ -1,75 +0,0 @@ - NO-OP - if (!$source->isReadable()) { - return $dest; - } - - // destination not writable => just pause() source - if (!$dest->isWritable()) { - $source->pause(); - - return $dest; - } - - $dest->emit('pipe', array($source)); - - // forward all source data events as $dest->write() - $source->on('data', $dataer = function ($data) use ($source, $dest) { - $feedMore = $dest->write($data); - - if (false === $feedMore) { - $source->pause(); - } - }); - $dest->on('close', function () use ($source, $dataer) { - $source->removeListener('data', $dataer); - $source->pause(); - }); - - // forward destination drain as $source->resume() - $dest->on('drain', $drainer = function () use ($source) { - $source->resume(); - }); - $source->on('close', function () use ($dest, $drainer) { - $dest->removeListener('drain', $drainer); - }); - - // forward end event from source as $dest->end() - $end = isset($options['end']) ? $options['end'] : true; - if ($end) { - $source->on('end', $ender = function () use ($dest) { - $dest->end(); - }); - $dest->on('close', function () use ($source, $ender) { - $source->removeListener('end', $ender); - }); - } - - return $dest; - } - - public static function forwardEvents($source, $target, array $events) - { - foreach ($events as $event) { - $source->on($event, function () use ($event, $target) { - $target->emit($event, \func_get_args()); - }); - } - } -} diff --git a/vendor/react/stream/src/WritableResourceStream.php b/vendor/react/stream/src/WritableResourceStream.php deleted file mode 100644 index 1af16b145..000000000 --- a/vendor/react/stream/src/WritableResourceStream.php +++ /dev/null @@ -1,168 +0,0 @@ -stream = $stream; - $this->loop = $loop ?: Loop::get(); - $this->softLimit = ($writeBufferSoftLimit === null) ? 65536 : (int)$writeBufferSoftLimit; - $this->writeChunkSize = ($writeChunkSize === null) ? -1 : (int)$writeChunkSize; - } - - public function isWritable() - { - return $this->writable; - } - - public function write($data) - { - if (!$this->writable) { - return false; - } - - $this->data .= $data; - - if (!$this->listening && $this->data !== '') { - $this->listening = true; - - $this->loop->addWriteStream($this->stream, array($this, 'handleWrite')); - } - - return !isset($this->data[$this->softLimit - 1]); - } - - public function end($data = null) - { - if (null !== $data) { - $this->write($data); - } - - $this->writable = false; - - // close immediately if buffer is already empty - // otherwise wait for buffer to flush first - if ($this->data === '') { - $this->close(); - } - } - - public function close() - { - if ($this->closed) { - return; - } - - if ($this->listening) { - $this->listening = false; - $this->loop->removeWriteStream($this->stream); - } - - $this->closed = true; - $this->writable = false; - $this->data = ''; - - $this->emit('close'); - $this->removeAllListeners(); - - if (\is_resource($this->stream)) { - \fclose($this->stream); - } - } - - /** @internal */ - public function handleWrite() - { - $error = null; - \set_error_handler(function ($_, $errstr) use (&$error) { - $error = $errstr; - }); - - if ($this->writeChunkSize === -1) { - $sent = \fwrite($this->stream, $this->data); - } else { - $sent = \fwrite($this->stream, $this->data, $this->writeChunkSize); - } - - \restore_error_handler(); - - // Only report errors if *nothing* could be sent and an error has been raised. - // Ignore non-fatal warnings if *some* data could be sent. - // Any hard (permanent) error will fail to send any data at all. - // Sending excessive amounts of data will only flush *some* data and then - // report a temporary error (EAGAIN) which we do not raise here in order - // to keep the stream open for further tries to write. - // Should this turn out to be a permanent error later, it will eventually - // send *nothing* and we can detect this. - if (($sent === 0 || $sent === false) && $error !== null) { - $this->emit('error', array(new \RuntimeException('Unable to write to stream: ' . $error))); - $this->close(); - - return; - } - - $exceeded = isset($this->data[$this->softLimit - 1]); - $this->data = (string) \substr($this->data, $sent); - - // buffer has been above limit and is now below limit - if ($exceeded && !isset($this->data[$this->softLimit - 1])) { - $this->emit('drain'); - } - - // buffer is now completely empty => stop trying to write - if ($this->data === '') { - // stop waiting for resource to be writable - if ($this->listening) { - $this->loop->removeWriteStream($this->stream); - $this->listening = false; - } - - // buffer is end()ing and now completely empty => close buffer - if (!$this->writable) { - $this->close(); - } - } - } -} diff --git a/vendor/react/stream/src/WritableStreamInterface.php b/vendor/react/stream/src/WritableStreamInterface.php deleted file mode 100644 index 9b5468023..000000000 --- a/vendor/react/stream/src/WritableStreamInterface.php +++ /dev/null @@ -1,347 +0,0 @@ -on('drain', function () use ($stream) { - * echo 'Stream is now ready to accept more data'; - * }); - * ``` - * - * This event SHOULD be emitted once every time the buffer became full - * previously and is now ready to accept more data. - * In other words, this event MAY be emitted any number of times, which may - * be zero times if the buffer never became full in the first place. - * This event SHOULD NOT be emitted if the buffer has not become full - * previously. - * - * This event is mostly used internally, see also `write()` for more details. - * - * pipe event: - * The `pipe` event will be emitted whenever a readable stream is `pipe()`d - * into this stream. - * The event receives a single `ReadableStreamInterface` argument for the - * source stream. - * - * ```php - * $stream->on('pipe', function (ReadableStreamInterface $source) use ($stream) { - * echo 'Now receiving piped data'; - * - * // explicitly close target if source emits an error - * $source->on('error', function () use ($stream) { - * $stream->close(); - * }); - * }); - * - * $source->pipe($stream); - * ``` - * - * This event MUST be emitted once for each readable stream that is - * successfully piped into this destination stream. - * In other words, this event MAY be emitted any number of times, which may - * be zero times if no stream is ever piped into this stream. - * This event MUST NOT be emitted if either the source is not readable - * (closed already) or this destination is not writable (closed already). - * - * This event is mostly used internally, see also `pipe()` for more details. - * - * error event: - * The `error` event will be emitted once a fatal error occurs, usually while - * trying to write to this stream. - * The event receives a single `Exception` argument for the error instance. - * - * ```php - * $stream->on('error', function (Exception $e) { - * echo 'Error: ' . $e->getMessage() . PHP_EOL; - * }); - * ``` - * - * This event SHOULD be emitted once the stream detects a fatal error, such - * as a fatal transmission error. - * It SHOULD NOT be emitted after a previous `error` or `close` event. - * It MUST NOT be emitted if this is not a fatal error condition, such as - * a temporary network issue that did not cause any data to be lost. - * - * After the stream errors, it MUST close the stream and SHOULD thus be - * followed by a `close` event and then switch to non-writable mode, see - * also `close()` and `isWritable()`. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * only deal with data transmission and may choose - * to only emit this for a fatal transmission error once and will then - * close (terminate) the stream in response. - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the readable side of the stream also implements an `error` event. - * In other words, an error may occur while either reading or writing the - * stream which should result in the same error processing. - * - * close event: - * The `close` event will be emitted once the stream closes (terminates). - * - * ```php - * $stream->on('close', function () { - * echo 'CLOSED'; - * }); - * ``` - * - * This event SHOULD be emitted once or never at all, depending on whether - * the stream ever terminates. - * It SHOULD NOT be emitted after a previous `close` event. - * - * After the stream is closed, it MUST switch to non-writable mode, - * see also `isWritable()`. - * - * This event SHOULD be emitted whenever the stream closes, irrespective of - * whether this happens implicitly due to an unrecoverable error or - * explicitly when either side closes the stream. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * will likely choose to emit this event after flushing the buffer from - * the `end()` method, after receiving a *successful* `end` event or after - * a fatal transmission `error` event. - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the readable side of the stream also implements a `close` event. - * In other words, after receiving this event, the stream MUST switch into - * non-writable AND non-readable mode, see also `isReadable()`. - * Note that this event should not be confused with the `end` event. - * - * The event callback functions MUST be a valid `callable` that obeys strict - * parameter definitions and MUST accept event parameters exactly as documented. - * The event callback functions MUST NOT throw an `Exception`. - * The return value of the event callback functions will be ignored and has no - * effect, so for performance reasons you're recommended to not return any - * excessive data structures. - * - * Every implementation of this interface MUST follow these event semantics in - * order to be considered a well-behaving stream. - * - * > Note that higher-level implementations of this interface may choose to - * define additional events with dedicated semantics not defined as part of - * this low-level stream specification. Conformance with these event semantics - * is out of scope for this interface, so you may also have to refer to the - * documentation of such a higher-level implementation. - * - * @see EventEmitterInterface - * @see DuplexStreamInterface - */ -interface WritableStreamInterface extends EventEmitterInterface -{ - /** - * Checks whether this stream is in a writable state (not closed already). - * - * This method can be used to check if the stream still accepts writing - * any data or if it is ended or closed already. - * Writing any data to a non-writable stream is a NO-OP: - * - * ```php - * assert($stream->isWritable() === false); - * - * $stream->write('end'); // NO-OP - * $stream->end('end'); // NO-OP - * ``` - * - * A successfully opened stream always MUST start in writable mode. - * - * Once the stream ends or closes, it MUST switch to non-writable mode. - * This can happen any time, explicitly through `end()` or `close()` or - * implicitly due to a remote close or an unrecoverable transmission error. - * Once a stream has switched to non-writable mode, it MUST NOT transition - * back to writable mode. - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the readable side of the stream also implements an `isReadable()` - * method. Unless this is a half-open duplex stream, they SHOULD usually - * have the same return value. - * - * @return bool - */ - public function isWritable(); - - /** - * Write some data into the stream. - * - * A successful write MUST be confirmed with a boolean `true`, which means - * that either the data was written (flushed) immediately or is buffered and - * scheduled for a future write. Note that this interface gives you no - * control over explicitly flushing the buffered data, as finding the - * appropriate time for this is beyond the scope of this interface and left - * up to the implementation of this interface. - * - * Many common streams (such as a TCP/IP connection or file-based stream) - * may choose to buffer all given data and schedule a future flush by using - * an underlying EventLoop to check when the resource is actually writable. - * - * If a stream cannot handle writing (or flushing) the data, it SHOULD emit - * an `error` event and MAY `close()` the stream if it can not recover from - * this error. - * - * If the internal buffer is full after adding `$data`, then `write()` - * SHOULD return `false`, indicating that the caller should stop sending - * data until the buffer drains. - * The stream SHOULD send a `drain` event once the buffer is ready to accept - * more data. - * - * Similarly, if the the stream is not writable (already in a closed state) - * it MUST NOT process the given `$data` and SHOULD return `false`, - * indicating that the caller should stop sending data. - * - * The given `$data` argument MAY be of mixed type, but it's usually - * recommended it SHOULD be a `string` value or MAY use a type that allows - * representation as a `string` for maximum compatibility. - * - * Many common streams (such as a TCP/IP connection or a file-based stream) - * will only accept the raw (binary) payload data that is transferred over - * the wire as chunks of `string` values. - * - * Due to the stream-based nature of this, the sender may send any number - * of chunks with varying sizes. There are no guarantees that these chunks - * will be received with the exact same framing the sender intended to send. - * In other words, many lower-level protocols (such as TCP/IP) transfer the - * data in chunks that may be anywhere between single-byte values to several - * dozens of kilobytes. You may want to apply a higher-level protocol to - * these low-level data chunks in order to achieve proper message framing. - * - * @param mixed|string $data - * @return bool - */ - public function write($data); - - /** - * Successfully ends the stream (after optionally sending some final data). - * - * This method can be used to successfully end the stream, i.e. close - * the stream after sending out all data that is currently buffered. - * - * ```php - * $stream->write('hello'); - * $stream->write('world'); - * $stream->end(); - * ``` - * - * If there's no data currently buffered and nothing to be flushed, then - * this method MAY `close()` the stream immediately. - * - * If there's still data in the buffer that needs to be flushed first, then - * this method SHOULD try to write out this data and only then `close()` - * the stream. - * Once the stream is closed, it SHOULD emit a `close` event. - * - * Note that this interface gives you no control over explicitly flushing - * the buffered data, as finding the appropriate time for this is beyond the - * scope of this interface and left up to the implementation of this - * interface. - * - * Many common streams (such as a TCP/IP connection or file-based stream) - * may choose to buffer all given data and schedule a future flush by using - * an underlying EventLoop to check when the resource is actually writable. - * - * You can optionally pass some final data that is written to the stream - * before ending the stream. If a non-`null` value is given as `$data`, then - * this method will behave just like calling `write($data)` before ending - * with no data. - * - * ```php - * // shorter version - * $stream->end('bye'); - * - * // same as longer version - * $stream->write('bye'); - * $stream->end(); - * ``` - * - * After calling this method, the stream MUST switch into a non-writable - * mode, see also `isWritable()`. - * This means that no further writes are possible, so any additional - * `write()` or `end()` calls have no effect. - * - * ```php - * $stream->end(); - * assert($stream->isWritable() === false); - * - * $stream->write('nope'); // NO-OP - * $stream->end(); // NO-OP - * ``` - * - * If this stream is a `DuplexStreamInterface`, calling this method SHOULD - * also end its readable side, unless the stream supports half-open mode. - * In other words, after calling this method, these streams SHOULD switch - * into non-writable AND non-readable mode, see also `isReadable()`. - * This implies that in this case, the stream SHOULD NOT emit any `data` - * or `end` events anymore. - * Streams MAY choose to use the `pause()` method logic for this, but - * special care may have to be taken to ensure a following call to the - * `resume()` method SHOULD NOT continue emitting readable events. - * - * Note that this method should not be confused with the `close()` method. - * - * @param mixed|string|null $data - * @return void - */ - public function end($data = null); - - /** - * Closes the stream (forcefully). - * - * This method can be used to forcefully close the stream, i.e. close - * the stream without waiting for any buffered data to be flushed. - * If there's still data in the buffer, this data SHOULD be discarded. - * - * ```php - * $stream->close(); - * ``` - * - * Once the stream is closed, it SHOULD emit a `close` event. - * Note that this event SHOULD NOT be emitted more than once, in particular - * if this method is called multiple times. - * - * After calling this method, the stream MUST switch into a non-writable - * mode, see also `isWritable()`. - * This means that no further writes are possible, so any additional - * `write()` or `end()` calls have no effect. - * - * ```php - * $stream->close(); - * assert($stream->isWritable() === false); - * - * $stream->write('nope'); // NO-OP - * $stream->end(); // NO-OP - * ``` - * - * Note that this method should not be confused with the `end()` method. - * Unlike the `end()` method, this method does not take care of any existing - * buffers and simply discards any buffer contents. - * Likewise, this method may also be called after calling `end()` on a - * stream in order to stop waiting for the stream to flush its final data. - * - * ```php - * $stream->end(); - * Loop::addTimer(1.0, function () use ($stream) { - * $stream->close(); - * }); - * ``` - * - * If this stream is a `DuplexStreamInterface`, you should also notice - * how the readable side of the stream also implements a `close()` method. - * In other words, after calling this method, the stream MUST switch into - * non-writable AND non-readable mode, see also `isReadable()`. - * - * @return void - * @see ReadableStreamInterface::close() - */ - public function close(); -} diff --git a/vendor/ringcentral/psr7/src/AppendStream.php b/vendor/ringcentral/psr7/src/AppendStream.php deleted file mode 100644 index 8b8df6f4c..000000000 --- a/vendor/ringcentral/psr7/src/AppendStream.php +++ /dev/null @@ -1,233 +0,0 @@ -addStream($stream); - } - } - - public function __toString() - { - try { - $this->rewind(); - return $this->getContents(); - } catch (\Exception $e) { - return ''; - } - } - - /** - * Add a stream to the AppendStream - * - * @param StreamInterface $stream Stream to append. Must be readable. - * - * @throws \InvalidArgumentException if the stream is not readable - */ - public function addStream(StreamInterface $stream) - { - if (!$stream->isReadable()) { - throw new \InvalidArgumentException('Each stream must be readable'); - } - - // The stream is only seekable if all streams are seekable - if (!$stream->isSeekable()) { - $this->seekable = false; - } - - $this->streams[] = $stream; - } - - public function getContents() - { - return copy_to_string($this); - } - - /** - * Closes each attached stream. - * - * {@inheritdoc} - */ - public function close() - { - $this->pos = $this->current = 0; - - foreach ($this->streams as $stream) { - $stream->close(); - } - - $this->streams = array(); - } - - /** - * Detaches each attached stream - * - * {@inheritdoc} - */ - public function detach() - { - $this->close(); - $this->detached = true; - } - - public function tell() - { - return $this->pos; - } - - /** - * Tries to calculate the size by adding the size of each stream. - * - * If any of the streams do not return a valid number, then the size of the - * append stream cannot be determined and null is returned. - * - * {@inheritdoc} - */ - public function getSize() - { - $size = 0; - - foreach ($this->streams as $stream) { - $s = $stream->getSize(); - if ($s === null) { - return null; - } - $size += $s; - } - - return $size; - } - - public function eof() - { - return !$this->streams || - ($this->current >= count($this->streams) - 1 && - $this->streams[$this->current]->eof()); - } - - public function rewind() - { - $this->seek(0); - } - - /** - * Attempts to seek to the given position. Only supports SEEK_SET. - * - * {@inheritdoc} - */ - public function seek($offset, $whence = SEEK_SET) - { - if (!$this->seekable) { - throw new \RuntimeException('This AppendStream is not seekable'); - } elseif ($whence !== SEEK_SET) { - throw new \RuntimeException('The AppendStream can only seek with SEEK_SET'); - } - - $this->pos = $this->current = 0; - - // Rewind each stream - foreach ($this->streams as $i => $stream) { - try { - $stream->rewind(); - } catch (\Exception $e) { - throw new \RuntimeException('Unable to seek stream ' - . $i . ' of the AppendStream', 0, $e); - } - } - - // Seek to the actual position by reading from each stream - while ($this->pos < $offset && !$this->eof()) { - $result = $this->read(min(8096, $offset - $this->pos)); - if ($result === '') { - break; - } - } - } - - /** - * Reads from all of the appended streams until the length is met or EOF. - * - * {@inheritdoc} - */ - public function read($length) - { - $buffer = ''; - $total = count($this->streams) - 1; - $remaining = $length; - $progressToNext = false; - - while ($remaining > 0) { - - // Progress to the next stream if needed. - if ($progressToNext || $this->streams[$this->current]->eof()) { - $progressToNext = false; - if ($this->current === $total) { - break; - } - $this->current++; - } - - $result = $this->streams[$this->current]->read($remaining); - - // Using a loose comparison here to match on '', false, and null - if ($result == null) { - $progressToNext = true; - continue; - } - - $buffer .= $result; - $remaining = $length - strlen($buffer); - } - - $this->pos += strlen($buffer); - - return $buffer; - } - - public function isReadable() - { - return true; - } - - public function isWritable() - { - return false; - } - - public function isSeekable() - { - return $this->seekable; - } - - public function write($string) - { - throw new \RuntimeException('Cannot write to an AppendStream'); - } - - public function getMetadata($key = null) - { - return $key ? null : array(); - } -} diff --git a/vendor/ringcentral/psr7/src/BufferStream.php b/vendor/ringcentral/psr7/src/BufferStream.php deleted file mode 100644 index a1e236def..000000000 --- a/vendor/ringcentral/psr7/src/BufferStream.php +++ /dev/null @@ -1,137 +0,0 @@ -hwm = $hwm; - } - - public function __toString() - { - return $this->getContents(); - } - - public function getContents() - { - $buffer = $this->buffer; - $this->buffer = ''; - - return $buffer; - } - - public function close() - { - $this->buffer = ''; - } - - public function detach() - { - $this->close(); - } - - public function getSize() - { - return strlen($this->buffer); - } - - public function isReadable() - { - return true; - } - - public function isWritable() - { - return true; - } - - public function isSeekable() - { - return false; - } - - public function rewind() - { - $this->seek(0); - } - - public function seek($offset, $whence = SEEK_SET) - { - throw new \RuntimeException('Cannot seek a BufferStream'); - } - - public function eof() - { - return strlen($this->buffer) === 0; - } - - public function tell() - { - throw new \RuntimeException('Cannot determine the position of a BufferStream'); - } - - /** - * Reads data from the buffer. - */ - public function read($length) - { - $currentLength = strlen($this->buffer); - - if ($length >= $currentLength) { - // No need to slice the buffer because we don't have enough data. - $result = $this->buffer; - $this->buffer = ''; - } else { - // Slice up the result to provide a subset of the buffer. - $result = substr($this->buffer, 0, $length); - $this->buffer = substr($this->buffer, $length); - } - - return $result; - } - - /** - * Writes data to the buffer. - */ - public function write($string) - { - $this->buffer .= $string; - - // TODO: What should happen here? - if (strlen($this->buffer) >= $this->hwm) { - return false; - } - - return strlen($string); - } - - public function getMetadata($key = null) - { - if ($key == 'hwm') { - return $this->hwm; - } - - return $key ? null : array(); - } -} diff --git a/vendor/ringcentral/psr7/src/CachingStream.php b/vendor/ringcentral/psr7/src/CachingStream.php deleted file mode 100644 index ce3aca8bb..000000000 --- a/vendor/ringcentral/psr7/src/CachingStream.php +++ /dev/null @@ -1,135 +0,0 @@ -remoteStream = $stream; - parent::__construct($target ?: new Stream(fopen('php://temp', 'r+'))); - } - - public function getSize() - { - return max($this->stream->getSize(), $this->remoteStream->getSize()); - } - - public function rewind() - { - $this->seek(0); - } - - public function seek($offset, $whence = SEEK_SET) - { - if ($whence == SEEK_SET) { - $byte = $offset; - } elseif ($whence == SEEK_CUR) { - $byte = $offset + $this->tell(); - } elseif ($whence == SEEK_END) { - $size = $this->remoteStream->getSize(); - if ($size === null) { - $size = $this->cacheEntireStream(); - } - // Because 0 is the first byte, we seek to size - 1. - $byte = $size - 1 - $offset; - } else { - throw new \InvalidArgumentException('Invalid whence'); - } - - $diff = $byte - $this->stream->getSize(); - - if ($diff > 0) { - // If the seek byte is greater the number of read bytes, then read - // the difference of bytes to cache the bytes and inherently seek. - $this->read($diff); - } else { - // We can just do a normal seek since we've already seen this byte. - $this->stream->seek($byte); - } - } - - public function read($length) - { - // Perform a regular read on any previously read data from the buffer - $data = $this->stream->read($length); - $remaining = $length - strlen($data); - - // More data was requested so read from the remote stream - if ($remaining) { - // If data was written to the buffer in a position that would have - // been filled from the remote stream, then we must skip bytes on - // the remote stream to emulate overwriting bytes from that - // position. This mimics the behavior of other PHP stream wrappers. - $remoteData = $this->remoteStream->read( - $remaining + $this->skipReadBytes - ); - - if ($this->skipReadBytes) { - $len = strlen($remoteData); - $remoteData = substr($remoteData, $this->skipReadBytes); - $this->skipReadBytes = max(0, $this->skipReadBytes - $len); - } - - $data .= $remoteData; - $this->stream->write($remoteData); - } - - return $data; - } - - public function write($string) - { - // When appending to the end of the currently read stream, you'll want - // to skip bytes from being read from the remote stream to emulate - // other stream wrappers. Basically replacing bytes of data of a fixed - // length. - $overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell(); - if ($overflow > 0) { - $this->skipReadBytes += $overflow; - } - - return $this->stream->write($string); - } - - public function eof() - { - return $this->stream->eof() && $this->remoteStream->eof(); - } - - /** - * Close both the remote stream and buffer stream - */ - public function close() - { - $this->remoteStream->close() && $this->stream->close(); - } - - private function cacheEntireStream() - { - $target = new FnStream(array('write' => 'strlen')); - copy_to_stream($this, $target); - - return $this->tell(); - } -} diff --git a/vendor/ringcentral/psr7/src/DroppingStream.php b/vendor/ringcentral/psr7/src/DroppingStream.php deleted file mode 100644 index 3a34d38fd..000000000 --- a/vendor/ringcentral/psr7/src/DroppingStream.php +++ /dev/null @@ -1,41 +0,0 @@ -maxLength = $maxLength; - } - - public function write($string) - { - $diff = $this->maxLength - $this->stream->getSize(); - - // Begin returning 0 when the underlying stream is too large. - if ($diff <= 0) { - return 0; - } - - // Write the stream or a subset of the stream if needed. - if (strlen($string) < $diff) { - return $this->stream->write($string); - } - - return $this->stream->write(substr($string, 0, $diff)); - } -} diff --git a/vendor/ringcentral/psr7/src/FnStream.php b/vendor/ringcentral/psr7/src/FnStream.php deleted file mode 100644 index f78dc8bab..000000000 --- a/vendor/ringcentral/psr7/src/FnStream.php +++ /dev/null @@ -1,163 +0,0 @@ -methods = $methods; - - // Create the functions on the class - foreach ($methods as $name => $fn) { - $this->{'_fn_' . $name} = $fn; - } - } - - /** - * Lazily determine which methods are not implemented. - * @throws \BadMethodCallException - */ - public function __get($name) - { - throw new \BadMethodCallException(str_replace('_fn_', '', $name) - . '() is not implemented in the FnStream'); - } - - /** - * The close method is called on the underlying stream only if possible. - */ - public function __destruct() - { - if (isset($this->_fn_close)) { - call_user_func($this->_fn_close); - } - } - - /** - * Adds custom functionality to an underlying stream by intercepting - * specific method calls. - * - * @param StreamInterface $stream Stream to decorate - * @param array $methods Hash of method name to a closure - * - * @return FnStream - */ - public static function decorate(StreamInterface $stream, array $methods) - { - // If any of the required methods were not provided, then simply - // proxy to the decorated stream. - foreach (array_diff(self::$slots, array_keys($methods)) as $diff) { - $methods[$diff] = array($stream, $diff); - } - - return new self($methods); - } - - public function __toString() - { - return call_user_func($this->_fn___toString); - } - - public function close() - { - return call_user_func($this->_fn_close); - } - - public function detach() - { - return call_user_func($this->_fn_detach); - } - - public function getSize() - { - return call_user_func($this->_fn_getSize); - } - - public function tell() - { - return call_user_func($this->_fn_tell); - } - - public function eof() - { - return call_user_func($this->_fn_eof); - } - - public function isSeekable() - { - return call_user_func($this->_fn_isSeekable); - } - - public function rewind() - { - call_user_func($this->_fn_rewind); - } - - public function seek($offset, $whence = SEEK_SET) - { - call_user_func($this->_fn_seek, $offset, $whence); - } - - public function isWritable() - { - return call_user_func($this->_fn_isWritable); - } - - public function write($string) - { - return call_user_func($this->_fn_write, $string); - } - - public function isReadable() - { - return call_user_func($this->_fn_isReadable); - } - - public function read($length) - { - return call_user_func($this->_fn_read, $length); - } - - public function getContents() - { - return call_user_func($this->_fn_getContents); - } - - public function getMetadata($key = null) - { - return call_user_func($this->_fn_getMetadata, $key); - } -} diff --git a/vendor/ringcentral/psr7/src/InflateStream.php b/vendor/ringcentral/psr7/src/InflateStream.php deleted file mode 100644 index c718002ba..000000000 --- a/vendor/ringcentral/psr7/src/InflateStream.php +++ /dev/null @@ -1,27 +0,0 @@ -filename = $filename; - $this->mode = $mode; - parent::__construct(); - } - - /** - * Creates the underlying stream lazily when required. - * - * @return StreamInterface - */ - protected function createStream() - { - return stream_for(try_fopen($this->filename, $this->mode)); - } -} diff --git a/vendor/ringcentral/psr7/src/LimitStream.php b/vendor/ringcentral/psr7/src/LimitStream.php deleted file mode 100644 index 57eeca9dc..000000000 --- a/vendor/ringcentral/psr7/src/LimitStream.php +++ /dev/null @@ -1,154 +0,0 @@ -setLimit($limit); - $this->setOffset($offset); - } - - public function eof() - { - // Always return true if the underlying stream is EOF - if ($this->stream->eof()) { - return true; - } - - // No limit and the underlying stream is not at EOF - if ($this->limit == -1) { - return false; - } - - return $this->stream->tell() >= $this->offset + $this->limit; - } - - /** - * Returns the size of the limited subset of data - * {@inheritdoc} - */ - public function getSize() - { - if (null === ($length = $this->stream->getSize())) { - return null; - } elseif ($this->limit == -1) { - return $length - $this->offset; - } else { - return min($this->limit, $length - $this->offset); - } - } - - /** - * Allow for a bounded seek on the read limited stream - * {@inheritdoc} - */ - public function seek($offset, $whence = SEEK_SET) - { - if ($whence !== SEEK_SET || $offset < 0) { - throw new \RuntimeException(sprintf( - 'Cannot seek to offset % with whence %s', - $offset, - $whence - )); - } - - $offset += $this->offset; - - if ($this->limit !== -1) { - if ($offset > $this->offset + $this->limit) { - $offset = $this->offset + $this->limit; - } - } - - $this->stream->seek($offset); - } - - /** - * Give a relative tell() - * {@inheritdoc} - */ - public function tell() - { - return $this->stream->tell() - $this->offset; - } - - /** - * Set the offset to start limiting from - * - * @param int $offset Offset to seek to and begin byte limiting from - * - * @throws \RuntimeException if the stream cannot be seeked. - */ - public function setOffset($offset) - { - $current = $this->stream->tell(); - - if ($current !== $offset) { - // If the stream cannot seek to the offset position, then read to it - if ($this->stream->isSeekable()) { - $this->stream->seek($offset); - } elseif ($current > $offset) { - throw new \RuntimeException("Could not seek to stream offset $offset"); - } else { - $this->stream->read($offset - $current); - } - } - - $this->offset = $offset; - } - - /** - * Set the limit of bytes that the decorator allows to be read from the - * stream. - * - * @param int $limit Number of bytes to allow to be read from the stream. - * Use -1 for no limit. - */ - public function setLimit($limit) - { - $this->limit = $limit; - } - - public function read($length) - { - if ($this->limit == -1) { - return $this->stream->read($length); - } - - // Check if the current position is less than the total allowed - // bytes + original offset - $remaining = ($this->offset + $this->limit) - $this->stream->tell(); - if ($remaining > 0) { - // Only return the amount of requested data, ensuring that the byte - // limit is not exceeded - return $this->stream->read(min($remaining, $length)); - } - - return ''; - } -} diff --git a/vendor/ringcentral/psr7/src/MessageTrait.php b/vendor/ringcentral/psr7/src/MessageTrait.php deleted file mode 100644 index 9330bcba7..000000000 --- a/vendor/ringcentral/psr7/src/MessageTrait.php +++ /dev/null @@ -1,167 +0,0 @@ -protocol; - } - - public function withProtocolVersion($version) - { - if ($this->protocol === $version) { - return $this; - } - - $new = clone $this; - $new->protocol = $version; - return $new; - } - - public function getHeaders() - { - return $this->headerLines; - } - - public function hasHeader($header) - { - return isset($this->headers[strtolower($header)]); - } - - public function getHeader($header) - { - $name = strtolower($header); - return isset($this->headers[$name]) ? $this->headers[$name] : array(); - } - - public function getHeaderLine($header) - { - return implode(', ', $this->getHeader($header)); - } - - public function withHeader($header, $value) - { - $new = clone $this; - $header = trim($header); - $name = strtolower($header); - - if (!is_array($value)) { - $new->headers[$name] = array(trim($value)); - } else { - $new->headers[$name] = $value; - foreach ($new->headers[$name] as &$v) { - $v = trim($v); - } - } - - // Remove the header lines. - foreach (array_keys($new->headerLines) as $key) { - if (strtolower($key) === $name) { - unset($new->headerLines[$key]); - } - } - - // Add the header line. - $new->headerLines[$header] = $new->headers[$name]; - - return $new; - } - - public function withAddedHeader($header, $value) - { - if (!$this->hasHeader($header)) { - return $this->withHeader($header, $value); - } - - $header = trim($header); - $name = strtolower($header); - - $value = (array) $value; - foreach ($value as &$v) { - $v = trim($v); - } - - $new = clone $this; - $new->headers[$name] = array_merge($new->headers[$name], $value); - $new->headerLines[$header] = array_merge($new->headerLines[$header], $value); - - return $new; - } - - public function withoutHeader($header) - { - if (!$this->hasHeader($header)) { - return $this; - } - - $new = clone $this; - $name = strtolower($header); - unset($new->headers[$name]); - - foreach (array_keys($new->headerLines) as $key) { - if (strtolower($key) === $name) { - unset($new->headerLines[$key]); - } - } - - return $new; - } - - public function getBody() - { - if (!$this->stream) { - $this->stream = stream_for(''); - } - - return $this->stream; - } - - public function withBody(StreamInterface $body) - { - if ($body === $this->stream) { - return $this; - } - - $new = clone $this; - $new->stream = $body; - return $new; - } - - protected function setHeaders(array $headers) - { - $this->headerLines = $this->headers = array(); - foreach ($headers as $header => $value) { - $header = trim($header); - $name = strtolower($header); - if (!is_array($value)) { - $value = trim($value); - $this->headers[$name][] = $value; - $this->headerLines[$header][] = $value; - } else { - foreach ($value as $v) { - $v = trim($v); - $this->headers[$name][] = $v; - $this->headerLines[$header][] = $v; - } - } - } - } -} diff --git a/vendor/ringcentral/psr7/src/MultipartStream.php b/vendor/ringcentral/psr7/src/MultipartStream.php deleted file mode 100644 index 8c5e5bc3d..000000000 --- a/vendor/ringcentral/psr7/src/MultipartStream.php +++ /dev/null @@ -1,152 +0,0 @@ -boundary = $boundary ?: uniqid(); - parent::__construct($this->createStream($elements)); - } - - /** - * Get the boundary - * - * @return string - */ - public function getBoundary() - { - return $this->boundary; - } - - public function isWritable() - { - return false; - } - - /** - * Get the headers needed before transferring the content of a POST file - */ - private function getHeaders(array $headers) - { - $str = ''; - foreach ($headers as $key => $value) { - $str .= "{$key}: {$value}\r\n"; - } - - return "--{$this->boundary}\r\n" . trim($str) . "\r\n\r\n"; - } - - /** - * Create the aggregate stream that will be used to upload the POST data - */ - protected function createStream(array $elements) - { - $stream = new AppendStream(); - - foreach ($elements as $element) { - $this->addElement($stream, $element); - } - - // Add the trailing boundary with CRLF - $stream->addStream(stream_for("--{$this->boundary}--\r\n")); - - return $stream; - } - - private function addElement(AppendStream $stream, array $element) - { - foreach (array('contents', 'name') as $key) { - if (!array_key_exists($key, $element)) { - throw new \InvalidArgumentException("A '{$key}' key is required"); - } - } - - $element['contents'] = stream_for($element['contents']); - - if (empty($element['filename'])) { - $uri = $element['contents']->getMetadata('uri'); - if (substr($uri, 0, 6) !== 'php://') { - $element['filename'] = $uri; - } - } - - list($body, $headers) = $this->createElement( - $element['name'], - $element['contents'], - isset($element['filename']) ? $element['filename'] : null, - isset($element['headers']) ? $element['headers'] : array() - ); - - $stream->addStream(stream_for($this->getHeaders($headers))); - $stream->addStream($body); - $stream->addStream(stream_for("\r\n")); - } - - /** - * @return array - */ - private function createElement($name, $stream, $filename, array $headers) - { - // Set a default content-disposition header if one was no provided - $disposition = $this->getHeader($headers, 'content-disposition'); - if (!$disposition) { - $headers['Content-Disposition'] = $filename - ? sprintf('form-data; name="%s"; filename="%s"', - $name, - basename($filename)) - : "form-data; name=\"{$name}\""; - } - - // Set a default content-length header if one was no provided - $length = $this->getHeader($headers, 'content-length'); - if (!$length) { - if ($length = $stream->getSize()) { - $headers['Content-Length'] = (string) $length; - } - } - - // Set a default Content-Type if one was not supplied - $type = $this->getHeader($headers, 'content-type'); - if (!$type && $filename) { - if ($type = mimetype_from_filename($filename)) { - $headers['Content-Type'] = $type; - } - } - - return array($stream, $headers); - } - - private function getHeader(array $headers, $key) - { - $lowercaseHeader = strtolower($key); - foreach ($headers as $k => $v) { - if (strtolower($k) === $lowercaseHeader) { - return $v; - } - } - - return null; - } -} diff --git a/vendor/ringcentral/psr7/src/NoSeekStream.php b/vendor/ringcentral/psr7/src/NoSeekStream.php deleted file mode 100644 index 328fdda40..000000000 --- a/vendor/ringcentral/psr7/src/NoSeekStream.php +++ /dev/null @@ -1,21 +0,0 @@ -source = $source; - $this->size = isset($options['size']) ? $options['size'] : null; - $this->metadata = isset($options['metadata']) ? $options['metadata'] : array(); - $this->buffer = new BufferStream(); - } - - public function __toString() - { - try { - return copy_to_string($this); - } catch (\Exception $e) { - return ''; - } - } - - public function close() - { - $this->detach(); - } - - public function detach() - { - $this->tellPos = false; - $this->source = null; - } - - public function getSize() - { - return $this->size; - } - - public function tell() - { - return $this->tellPos; - } - - public function eof() - { - return !$this->source; - } - - public function isSeekable() - { - return false; - } - - public function rewind() - { - $this->seek(0); - } - - public function seek($offset, $whence = SEEK_SET) - { - throw new \RuntimeException('Cannot seek a PumpStream'); - } - - public function isWritable() - { - return false; - } - - public function write($string) - { - throw new \RuntimeException('Cannot write to a PumpStream'); - } - - public function isReadable() - { - return true; - } - - public function read($length) - { - $data = $this->buffer->read($length); - $readLen = strlen($data); - $this->tellPos += $readLen; - $remaining = $length - $readLen; - - if ($remaining) { - $this->pump($remaining); - $data .= $this->buffer->read($remaining); - $this->tellPos += strlen($data) - $readLen; - } - - return $data; - } - - public function getContents() - { - $result = ''; - while (!$this->eof()) { - $result .= $this->read(1000000); - } - - return $result; - } - - public function getMetadata($key = null) - { - if (!$key) { - return $this->metadata; - } - - return isset($this->metadata[$key]) ? $this->metadata[$key] : null; - } - - private function pump($length) - { - if ($this->source) { - do { - $data = call_user_func($this->source, $length); - if ($data === false || $data === null) { - $this->source = null; - return; - } - $this->buffer->write($data); - $length -= strlen($data); - } while ($length > 0); - } - } -} diff --git a/vendor/ringcentral/psr7/src/Request.php b/vendor/ringcentral/psr7/src/Request.php deleted file mode 100644 index bb0f2fc28..000000000 --- a/vendor/ringcentral/psr7/src/Request.php +++ /dev/null @@ -1,146 +0,0 @@ -method = strtoupper($method); - $this->uri = $uri; - $this->setHeaders($headers); - $this->protocol = $protocolVersion; - - $host = $uri->getHost(); - if ($host && !$this->hasHeader('Host')) { - $this->updateHostFromUri($host); - } - - if ($body) { - $this->stream = stream_for($body); - } - } - - public function getRequestTarget() - { - if ($this->requestTarget !== null) { - return $this->requestTarget; - } - - $target = $this->uri->getPath(); - if ($target == null) { - $target = '/'; - } - if ($this->uri->getQuery()) { - $target .= '?' . $this->uri->getQuery(); - } - - return $target; - } - - public function withRequestTarget($requestTarget) - { - if (preg_match('#\s#', $requestTarget)) { - throw new InvalidArgumentException( - 'Invalid request target provided; cannot contain whitespace' - ); - } - - $new = clone $this; - $new->requestTarget = $requestTarget; - return $new; - } - - public function getMethod() - { - return $this->method; - } - - public function withMethod($method) - { - $new = clone $this; - $new->method = strtoupper($method); - return $new; - } - - public function getUri() - { - return $this->uri; - } - - public function withUri(UriInterface $uri, $preserveHost = false) - { - if ($uri === $this->uri) { - return $this; - } - - $new = clone $this; - $new->uri = $uri; - - if (!$preserveHost) { - if ($host = $uri->getHost()) { - $new->updateHostFromUri($host); - } - } - - return $new; - } - - public function withHeader($header, $value) - { - /** @var Request $newInstance */ - $newInstance = parent::withHeader($header, $value); - return $newInstance; - } - - private function updateHostFromUri($host) - { - // Ensure Host is the first header. - // See: http://tools.ietf.org/html/rfc7230#section-5.4 - if ($port = $this->uri->getPort()) { - $host .= ':' . $port; - } - - $this->headerLines = array('Host' => array($host)) + $this->headerLines; - $this->headers = array('host' => array($host)) + $this->headers; - } -} diff --git a/vendor/ringcentral/psr7/src/Response.php b/vendor/ringcentral/psr7/src/Response.php deleted file mode 100644 index a6d94516b..000000000 --- a/vendor/ringcentral/psr7/src/Response.php +++ /dev/null @@ -1,129 +0,0 @@ - 'Continue', - 101 => 'Switching Protocols', - 102 => 'Processing', - 200 => 'OK', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative Information', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - 207 => 'Multi-status', - 208 => 'Already Reported', - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - 306 => 'Switch Proxy', - 307 => 'Temporary Redirect', - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Time-out', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Large', - 415 => 'Unsupported Media Type', - 416 => 'Requested range not satisfiable', - 417 => 'Expectation Failed', - 418 => 'I\'m a teapot', - 422 => 'Unprocessable Entity', - 423 => 'Locked', - 424 => 'Failed Dependency', - 425 => 'Unordered Collection', - 426 => 'Upgrade Required', - 428 => 'Precondition Required', - 429 => 'Too Many Requests', - 431 => 'Request Header Fields Too Large', - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Time-out', - 505 => 'HTTP Version not supported', - 506 => 'Variant Also Negotiates', - 507 => 'Insufficient Storage', - 508 => 'Loop Detected', - 511 => 'Network Authentication Required', - ); - - /** @var null|string */ - private $reasonPhrase = ''; - - /** @var int */ - private $statusCode = 200; - - /** - * @param int $status Status code for the response, if any. - * @param array $headers Headers for the response, if any. - * @param mixed $body Stream body. - * @param string $version Protocol version. - * @param string $reason Reason phrase (a default will be used if possible). - */ - public function __construct( - $status = 200, - array $headers = array(), - $body = null, - $version = '1.1', - $reason = null - ) { - $this->statusCode = (int) $status; - - if ($body !== null) { - $this->stream = stream_for($body); - } - - $this->setHeaders($headers); - if (!$reason && isset(self::$phrases[$this->statusCode])) { - $this->reasonPhrase = self::$phrases[$status]; - } else { - $this->reasonPhrase = (string) $reason; - } - - $this->protocol = $version; - } - - public function getStatusCode() - { - return $this->statusCode; - } - - public function getReasonPhrase() - { - return $this->reasonPhrase; - } - - public function withStatus($code, $reasonPhrase = '') - { - $new = clone $this; - $new->statusCode = (int) $code; - if (!$reasonPhrase && isset(self::$phrases[$new->statusCode])) { - $reasonPhrase = self::$phrases[$new->statusCode]; - } - $new->reasonPhrase = $reasonPhrase; - return $new; - } -} diff --git a/vendor/ringcentral/psr7/src/ServerRequest.php b/vendor/ringcentral/psr7/src/ServerRequest.php deleted file mode 100644 index 8408a0936..000000000 --- a/vendor/ringcentral/psr7/src/ServerRequest.php +++ /dev/null @@ -1,122 +0,0 @@ -serverParams = $serverParams; - } - - public function getServerParams() - { - return $this->serverParams; - } - - public function getCookieParams() - { - return $this->cookies; - } - - public function withCookieParams(array $cookies) - { - $new = clone $this; - $new->cookies = $cookies; - return $new; - } - - public function getQueryParams() - { - return $this->queryParams; - } - - public function withQueryParams(array $query) - { - $new = clone $this; - $new->queryParams = $query; - return $new; - } - - public function getUploadedFiles() - { - return $this->fileParams; - } - - public function withUploadedFiles(array $uploadedFiles) - { - $new = clone $this; - $new->fileParams = $uploadedFiles; - return $new; - } - - public function getParsedBody() - { - return $this->parsedBody; - } - - public function withParsedBody($data) - { - $new = clone $this; - $new->parsedBody = $data; - return $new; - } - - public function getAttributes() - { - return $this->attributes; - } - - public function getAttribute($name, $default = null) - { - if (!array_key_exists($name, $this->attributes)) { - return $default; - } - return $this->attributes[$name]; - } - - public function withAttribute($name, $value) - { - $new = clone $this; - $new->attributes[$name] = $value; - return $new; - } - - public function withoutAttribute($name) - { - $new = clone $this; - unset($new->attributes[$name]); - return $new; - } -} diff --git a/vendor/ringcentral/psr7/src/Stream.php b/vendor/ringcentral/psr7/src/Stream.php deleted file mode 100644 index 0a0157c53..000000000 --- a/vendor/ringcentral/psr7/src/Stream.php +++ /dev/null @@ -1,245 +0,0 @@ - array( - 'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true, - 'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true, - 'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true, - 'x+t' => true, 'c+t' => true, 'a+' => true - ), - 'write' => array( - 'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true, - 'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true, - 'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true, - 'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true - ) - ); - - /** - * This constructor accepts an associative array of options. - * - * - size: (int) If a read stream would otherwise have an indeterminate - * size, but the size is known due to foreknownledge, then you can - * provide that size, in bytes. - * - metadata: (array) Any additional metadata to return when the metadata - * of the stream is accessed. - * - * @param resource $stream Stream resource to wrap. - * @param array $options Associative array of options. - * - * @throws \InvalidArgumentException if the stream is not a stream resource - */ - public function __construct($stream, $options = array()) - { - if (!is_resource($stream)) { - throw new \InvalidArgumentException('Stream must be a resource'); - } - - if (isset($options['size'])) { - $this->size = $options['size']; - } - - $this->customMetadata = isset($options['metadata']) - ? $options['metadata'] - : array(); - - $this->stream = $stream; - $meta = stream_get_meta_data($this->stream); - $this->seekable = $meta['seekable']; - $this->readable = isset(self::$readWriteHash['read'][$meta['mode']]); - $this->writable = isset(self::$readWriteHash['write'][$meta['mode']]); - $this->uri = $this->getMetadata('uri'); - } - - public function __get($name) - { - if ($name == 'stream') { - throw new \RuntimeException('The stream is detached'); - } - - throw new \BadMethodCallException('No value for ' . $name); - } - - /** - * Closes the stream when the destructed - */ - public function __destruct() - { - $this->close(); - } - - public function __toString() - { - try { - $this->seek(0); - return (string) stream_get_contents($this->stream); - } catch (\Exception $e) { - return ''; - } - } - - public function getContents() - { - $contents = stream_get_contents($this->stream); - - if ($contents === false) { - throw new \RuntimeException('Unable to read stream contents'); - } - - return $contents; - } - - public function close() - { - if (isset($this->stream)) { - if (is_resource($this->stream)) { - fclose($this->stream); - } - $this->detach(); - } - } - - public function detach() - { - if (!isset($this->stream)) { - return null; - } - - $result = $this->stream; - unset($this->stream); - $this->size = $this->uri = null; - $this->readable = $this->writable = $this->seekable = false; - - return $result; - } - - public function getSize() - { - if ($this->size !== null) { - return $this->size; - } - - if (!isset($this->stream)) { - return null; - } - - // Clear the stat cache if the stream has a URI - if ($this->uri) { - clearstatcache(true, $this->uri); - } - - $stats = fstat($this->stream); - if (isset($stats['size'])) { - $this->size = $stats['size']; - return $this->size; - } - - return null; - } - - public function isReadable() - { - return $this->readable; - } - - public function isWritable() - { - return $this->writable; - } - - public function isSeekable() - { - return $this->seekable; - } - - public function eof() - { - return !$this->stream || feof($this->stream); - } - - public function tell() - { - $result = ftell($this->stream); - - if ($result === false) { - throw new \RuntimeException('Unable to determine stream position'); - } - - return $result; - } - - public function rewind() - { - $this->seek(0); - } - - public function seek($offset, $whence = SEEK_SET) - { - if (!$this->seekable) { - throw new \RuntimeException('Stream is not seekable'); - } elseif (fseek($this->stream, $offset, $whence) === -1) { - throw new \RuntimeException('Unable to seek to stream position ' - . $offset . ' with whence ' . var_export($whence, true)); - } - } - - public function read($length) - { - if (!$this->readable) { - throw new \RuntimeException('Cannot read from non-readable stream'); - } - - return fread($this->stream, $length); - } - - public function write($string) - { - if (!$this->writable) { - throw new \RuntimeException('Cannot write to a non-writable stream'); - } - - // We can't know the size after writing anything - $this->size = null; - $result = fwrite($this->stream, $string); - - if ($result === false) { - throw new \RuntimeException('Unable to write to stream'); - } - - return $result; - } - - public function getMetadata($key = null) - { - if (!isset($this->stream)) { - return $key ? null : array(); - } elseif (!$key) { - return $this->customMetadata + stream_get_meta_data($this->stream); - } elseif (isset($this->customMetadata[$key])) { - return $this->customMetadata[$key]; - } - - $meta = stream_get_meta_data($this->stream); - - return isset($meta[$key]) ? $meta[$key] : null; - } -} diff --git a/vendor/ringcentral/psr7/src/StreamDecoratorTrait.php b/vendor/ringcentral/psr7/src/StreamDecoratorTrait.php deleted file mode 100644 index e22c674bc..000000000 --- a/vendor/ringcentral/psr7/src/StreamDecoratorTrait.php +++ /dev/null @@ -1,139 +0,0 @@ -stream = $stream; - } - - /** - * Magic method used to create a new stream if streams are not added in - * the constructor of a decorator (e.g., LazyOpenStream). - * - * @param string $name Name of the property (allows "stream" only). - * - * @return StreamInterface - */ - public function __get($name) - { - if ($name == 'stream') { - $this->stream = $this->createStream(); - return $this->stream; - } - - throw new \UnexpectedValueException("$name not found on class"); - } - - public function __toString() - { - try { - if ($this->isSeekable()) { - $this->seek(0); - } - return $this->getContents(); - } catch (\Exception $e) { - // Really, PHP? https://bugs.php.net/bug.php?id=53648 - trigger_error('StreamDecorator::__toString exception: ' - . (string) $e, E_USER_ERROR); - return ''; - } - } - - public function getContents() - { - return copy_to_string($this); - } - - /** - * Allow decorators to implement custom methods - * - * @param string $method Missing method name - * @param array $args Method arguments - * - * @return mixed - */ - public function __call($method, array $args) - { - $result = call_user_func_array(array($this->stream, $method), $args); - - // Always return the wrapped object if the result is a return $this - return $result === $this->stream ? $this : $result; - } - - public function close() - { - $this->stream->close(); - } - - public function getMetadata($key = null) - { - return $this->stream->getMetadata($key); - } - - public function detach() - { - return $this->stream->detach(); - } - - public function getSize() - { - return $this->stream->getSize(); - } - - public function eof() - { - return $this->stream->eof(); - } - - public function tell() - { - return $this->stream->tell(); - } - - public function isReadable() - { - return $this->stream->isReadable(); - } - - public function isWritable() - { - return $this->stream->isWritable(); - } - - public function isSeekable() - { - return $this->stream->isSeekable(); - } - - public function rewind() - { - $this->seek(0); - } - - public function seek($offset, $whence = SEEK_SET) - { - $this->stream->seek($offset, $whence); - } - - public function read($length) - { - return $this->stream->read($length); - } - - public function write($string) - { - return $this->stream->write($string); - } - -} diff --git a/vendor/ringcentral/psr7/src/StreamWrapper.php b/vendor/ringcentral/psr7/src/StreamWrapper.php deleted file mode 100644 index 8cc07d792..000000000 --- a/vendor/ringcentral/psr7/src/StreamWrapper.php +++ /dev/null @@ -1,121 +0,0 @@ -isReadable()) { - $mode = $stream->isWritable() ? 'r+' : 'r'; - } elseif ($stream->isWritable()) { - $mode = 'w'; - } else { - throw new \InvalidArgumentException('The stream must be readable, ' - . 'writable, or both.'); - } - - return fopen('guzzle://stream', $mode, null, stream_context_create(array( - 'guzzle' => array('stream' => $stream) - ))); - } - - /** - * Registers the stream wrapper if needed - */ - public static function register() - { - if (!in_array('guzzle', stream_get_wrappers())) { - stream_wrapper_register('guzzle', __CLASS__); - } - } - - public function stream_open($path, $mode, $options, &$opened_path) - { - $options = stream_context_get_options($this->context); - - if (!isset($options['guzzle']['stream'])) { - return false; - } - - $this->mode = $mode; - $this->stream = $options['guzzle']['stream']; - - return true; - } - - public function stream_read($count) - { - return $this->stream->read($count); - } - - public function stream_write($data) - { - return (int) $this->stream->write($data); - } - - public function stream_tell() - { - return $this->stream->tell(); - } - - public function stream_eof() - { - return $this->stream->eof(); - } - - public function stream_seek($offset, $whence) - { - $this->stream->seek($offset, $whence); - - return true; - } - - public function stream_stat() - { - static $modeMap = array( - 'r' => 33060, - 'r+' => 33206, - 'w' => 33188 - ); - - return array( - 'dev' => 0, - 'ino' => 0, - 'mode' => $modeMap[$this->mode], - 'nlink' => 0, - 'uid' => 0, - 'gid' => 0, - 'rdev' => 0, - 'size' => $this->stream->getSize() ?: 0, - 'atime' => 0, - 'mtime' => 0, - 'ctime' => 0, - 'blksize' => 0, - 'blocks' => 0 - ); - } -} diff --git a/vendor/ringcentral/psr7/src/Uri.php b/vendor/ringcentral/psr7/src/Uri.php deleted file mode 100644 index 5323cdc4a..000000000 --- a/vendor/ringcentral/psr7/src/Uri.php +++ /dev/null @@ -1,601 +0,0 @@ - 80, - 'https' => 443, - ); - - private static $charUnreserved = 'a-zA-Z0-9_\-\.~'; - private static $charSubDelims = '!\$&\'\(\)\*\+,;='; - private static $replaceQuery = array('=' => '%3D', '&' => '%26'); - - /** @var string Uri scheme. */ - private $scheme = ''; - - /** @var string Uri user info. */ - private $userInfo = ''; - - /** @var string Uri host. */ - private $host = ''; - - /** @var int|null Uri port. */ - private $port; - - /** @var string Uri path. */ - private $path = ''; - - /** @var string Uri query string. */ - private $query = ''; - - /** @var string Uri fragment. */ - private $fragment = ''; - - /** - * @param string $uri URI to parse and wrap. - */ - public function __construct($uri = '') - { - if ($uri != null) { - $parts = parse_url($uri); - if ($parts === false) { - throw new \InvalidArgumentException("Unable to parse URI: $uri"); - } - $this->applyParts($parts); - } - } - - public function __toString() - { - return self::createUriString( - $this->scheme, - $this->getAuthority(), - $this->getPath(), - $this->query, - $this->fragment - ); - } - - /** - * Removes dot segments from a path and returns the new path. - * - * @param string $path - * - * @return string - * @link http://tools.ietf.org/html/rfc3986#section-5.2.4 - */ - public static function removeDotSegments($path) - { - static $noopPaths = array('' => true, '/' => true, '*' => true); - static $ignoreSegments = array('.' => true, '..' => true); - - if (isset($noopPaths[$path])) { - return $path; - } - - $results = array(); - $segments = explode('/', $path); - foreach ($segments as $segment) { - if ($segment == '..') { - array_pop($results); - } elseif (!isset($ignoreSegments[$segment])) { - $results[] = $segment; - } - } - - $newPath = implode('/', $results); - // Add the leading slash if necessary - if (substr($path, 0, 1) === '/' && - substr($newPath, 0, 1) !== '/' - ) { - $newPath = '/' . $newPath; - } - - // Add the trailing slash if necessary - if ($newPath != '/' && isset($ignoreSegments[end($segments)])) { - $newPath .= '/'; - } - - return $newPath; - } - - /** - * Resolve a base URI with a relative URI and return a new URI. - * - * @param UriInterface $base Base URI - * @param string $rel Relative URI - * - * @return UriInterface - */ - public static function resolve(UriInterface $base, $rel) - { - if ($rel === null || $rel === '') { - return $base; - } - - if (!($rel instanceof UriInterface)) { - $rel = new self($rel); - } - - // Return the relative uri as-is if it has a scheme. - if ($rel->getScheme()) { - return $rel->withPath(static::removeDotSegments($rel->getPath())); - } - - $relParts = array( - 'scheme' => $rel->getScheme(), - 'authority' => $rel->getAuthority(), - 'path' => $rel->getPath(), - 'query' => $rel->getQuery(), - 'fragment' => $rel->getFragment() - ); - - $parts = array( - 'scheme' => $base->getScheme(), - 'authority' => $base->getAuthority(), - 'path' => $base->getPath(), - 'query' => $base->getQuery(), - 'fragment' => $base->getFragment() - ); - - if (!empty($relParts['authority'])) { - $parts['authority'] = $relParts['authority']; - $parts['path'] = self::removeDotSegments($relParts['path']); - $parts['query'] = $relParts['query']; - $parts['fragment'] = $relParts['fragment']; - } elseif (!empty($relParts['path'])) { - if (substr($relParts['path'], 0, 1) == '/') { - $parts['path'] = self::removeDotSegments($relParts['path']); - $parts['query'] = $relParts['query']; - $parts['fragment'] = $relParts['fragment']; - } else { - if (!empty($parts['authority']) && empty($parts['path'])) { - $mergedPath = '/'; - } else { - $mergedPath = substr($parts['path'], 0, strrpos($parts['path'], '/') + 1); - } - $parts['path'] = self::removeDotSegments($mergedPath . $relParts['path']); - $parts['query'] = $relParts['query']; - $parts['fragment'] = $relParts['fragment']; - } - } elseif (!empty($relParts['query'])) { - $parts['query'] = $relParts['query']; - } elseif ($relParts['fragment'] != null) { - $parts['fragment'] = $relParts['fragment']; - } - - return new self(static::createUriString( - $parts['scheme'], - $parts['authority'], - $parts['path'], - $parts['query'], - $parts['fragment'] - )); - } - - /** - * Create a new URI with a specific query string value removed. - * - * Any existing query string values that exactly match the provided key are - * removed. - * - * Note: this function will convert "=" to "%3D" and "&" to "%26". - * - * @param UriInterface $uri URI to use as a base. - * @param string $key Query string key value pair to remove. - * - * @return UriInterface - */ - public static function withoutQueryValue(UriInterface $uri, $key) - { - $current = $uri->getQuery(); - if (!$current) { - return $uri; - } - - $result = array(); - foreach (explode('&', $current) as $part) { - $subParts = explode('=', $part); - if ($subParts[0] !== $key) { - $result[] = $part; - }; - } - - return $uri->withQuery(implode('&', $result)); - } - - /** - * Create a new URI with a specific query string value. - * - * Any existing query string values that exactly match the provided key are - * removed and replaced with the given key value pair. - * - * Note: this function will convert "=" to "%3D" and "&" to "%26". - * - * @param UriInterface $uri URI to use as a base. - * @param string $key Key to set. - * @param string $value Value to set. - * - * @return UriInterface - */ - public static function withQueryValue(UriInterface $uri, $key, $value) - { - $current = $uri->getQuery(); - $key = strtr($key, self::$replaceQuery); - - if (!$current) { - $result = array(); - } else { - $result = array(); - foreach (explode('&', $current) as $part) { - $subParts = explode('=', $part); - if ($subParts[0] !== $key) { - $result[] = $part; - }; - } - } - - if ($value !== null) { - $result[] = $key . '=' . strtr($value, self::$replaceQuery); - } else { - $result[] = $key; - } - - return $uri->withQuery(implode('&', $result)); - } - - /** - * Create a URI from a hash of parse_url parts. - * - * @param array $parts - * - * @return self - */ - public static function fromParts(array $parts) - { - $uri = new self(); - $uri->applyParts($parts); - return $uri; - } - - public function getScheme() - { - return $this->scheme; - } - - public function getAuthority() - { - if (empty($this->host)) { - return ''; - } - - $authority = $this->host; - if (!empty($this->userInfo)) { - $authority = $this->userInfo . '@' . $authority; - } - - if ($this->isNonStandardPort($this->scheme, $this->host, $this->port)) { - $authority .= ':' . $this->port; - } - - return $authority; - } - - public function getUserInfo() - { - return $this->userInfo; - } - - public function getHost() - { - return $this->host; - } - - public function getPort() - { - return $this->port; - } - - public function getPath() - { - return $this->path == null ? '' : $this->path; - } - - public function getQuery() - { - return $this->query; - } - - public function getFragment() - { - return $this->fragment; - } - - public function withScheme($scheme) - { - $scheme = $this->filterScheme($scheme); - - if ($this->scheme === $scheme) { - return $this; - } - - $new = clone $this; - $new->scheme = $scheme; - $new->port = $new->filterPort($new->scheme, $new->host, $new->port); - return $new; - } - - public function withUserInfo($user, $password = null) - { - $info = $user; - if ($password) { - $info .= ':' . $password; - } - - if ($this->userInfo === $info) { - return $this; - } - - $new = clone $this; - $new->userInfo = $info; - return $new; - } - - public function withHost($host) - { - if ($this->host === $host) { - return $this; - } - - $new = clone $this; - $new->host = $host; - return $new; - } - - public function withPort($port) - { - $port = $this->filterPort($this->scheme, $this->host, $port); - - if ($this->port === $port) { - return $this; - } - - $new = clone $this; - $new->port = $port; - return $new; - } - - public function withPath($path) - { - if (!is_string($path)) { - throw new \InvalidArgumentException( - 'Invalid path provided; must be a string' - ); - } - - $path = $this->filterPath($path); - - if ($this->path === $path) { - return $this; - } - - $new = clone $this; - $new->path = $path; - return $new; - } - - public function withQuery($query) - { - if (!is_string($query) && !method_exists($query, '__toString')) { - throw new \InvalidArgumentException( - 'Query string must be a string' - ); - } - - $query = (string) $query; - if (substr($query, 0, 1) === '?') { - $query = substr($query, 1); - } - - $query = $this->filterQueryAndFragment($query); - - if ($this->query === $query) { - return $this; - } - - $new = clone $this; - $new->query = $query; - return $new; - } - - public function withFragment($fragment) - { - if (substr($fragment, 0, 1) === '#') { - $fragment = substr($fragment, 1); - } - - $fragment = $this->filterQueryAndFragment($fragment); - - if ($this->fragment === $fragment) { - return $this; - } - - $new = clone $this; - $new->fragment = $fragment; - return $new; - } - - /** - * Apply parse_url parts to a URI. - * - * @param $parts Array of parse_url parts to apply. - */ - private function applyParts(array $parts) - { - $this->scheme = isset($parts['scheme']) - ? $this->filterScheme($parts['scheme']) - : ''; - $this->userInfo = isset($parts['user']) ? $parts['user'] : ''; - $this->host = isset($parts['host']) ? $parts['host'] : ''; - $this->port = !empty($parts['port']) - ? $this->filterPort($this->scheme, $this->host, $parts['port']) - : null; - $this->path = isset($parts['path']) - ? $this->filterPath($parts['path']) - : ''; - $this->query = isset($parts['query']) - ? $this->filterQueryAndFragment($parts['query']) - : ''; - $this->fragment = isset($parts['fragment']) - ? $this->filterQueryAndFragment($parts['fragment']) - : ''; - if (isset($parts['pass'])) { - $this->userInfo .= ':' . $parts['pass']; - } - } - - /** - * Create a URI string from its various parts - * - * @param string $scheme - * @param string $authority - * @param string $path - * @param string $query - * @param string $fragment - * @return string - */ - private static function createUriString($scheme, $authority, $path, $query, $fragment) - { - $uri = ''; - - if (!empty($scheme)) { - $uri .= $scheme . '://'; - } - - if (!empty($authority)) { - $uri .= $authority; - } - - if ($path != null) { - // Add a leading slash if necessary. - if ($uri && substr($path, 0, 1) !== '/') { - $uri .= '/'; - } - $uri .= $path; - } - - if ($query != null) { - $uri .= '?' . $query; - } - - if ($fragment != null) { - $uri .= '#' . $fragment; - } - - return $uri; - } - - /** - * Is a given port non-standard for the current scheme? - * - * @param string $scheme - * @param string $host - * @param int $port - * @return bool - */ - private static function isNonStandardPort($scheme, $host, $port) - { - if (!$scheme && $port) { - return true; - } - - if (!$host || !$port) { - return false; - } - - return !isset(static::$schemes[$scheme]) || $port !== static::$schemes[$scheme]; - } - - /** - * @param string $scheme - * - * @return string - */ - private function filterScheme($scheme) - { - $scheme = strtolower($scheme); - $scheme = rtrim($scheme, ':/'); - - return $scheme; - } - - /** - * @param string $scheme - * @param string $host - * @param int $port - * - * @return int|null - * - * @throws \InvalidArgumentException If the port is invalid. - */ - private function filterPort($scheme, $host, $port) - { - if (null !== $port) { - $port = (int) $port; - if (1 > $port || 0xffff < $port) { - throw new \InvalidArgumentException( - sprintf('Invalid port: %d. Must be between 1 and 65535', $port) - ); - } - } - - return $this->isNonStandardPort($scheme, $host, $port) ? $port : null; - } - - /** - * Filters the path of a URI - * - * @param $path - * - * @return string - */ - private function filterPath($path) - { - return preg_replace_callback( - '/(?:[^' . self::$charUnreserved . self::$charSubDelims . ':@\/%]+|%(?![A-Fa-f0-9]{2}))/', - array($this, 'rawurlencodeMatchZero'), - $path - ); - } - - /** - * Filters the query string or fragment of a URI. - * - * @param $str - * - * @return string - */ - private function filterQueryAndFragment($str) - { - return preg_replace_callback( - '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/', - array($this, 'rawurlencodeMatchZero'), - $str - ); - } - - private function rawurlencodeMatchZero(array $match) - { - return rawurlencode($match[0]); - } -} diff --git a/vendor/ringcentral/psr7/src/functions.php b/vendor/ringcentral/psr7/src/functions.php deleted file mode 100644 index 3c4c549fc..000000000 --- a/vendor/ringcentral/psr7/src/functions.php +++ /dev/null @@ -1,835 +0,0 @@ -getMethod() . ' ' - . $message->getRequestTarget()) - . ' HTTP/' . $message->getProtocolVersion(); - if (!$message->hasHeader('host')) { - $msg .= "\r\nHost: " . $message->getUri()->getHost(); - } - } elseif ($message instanceof ResponseInterface) { - $msg = 'HTTP/' . $message->getProtocolVersion() . ' ' - . $message->getStatusCode() . ' ' - . $message->getReasonPhrase(); - } else { - throw new \InvalidArgumentException('Unknown message type'); - } - - foreach ($message->getHeaders() as $name => $values) { - $msg .= "\r\n{$name}: " . implode(', ', $values); - } - - return "{$msg}\r\n\r\n" . $message->getBody(); -} - -/** - * Returns a UriInterface for the given value. - * - * This function accepts a string or {@see Psr\Http\Message\UriInterface} and - * returns a UriInterface for the given value. If the value is already a - * `UriInterface`, it is returned as-is. - * - * @param string|UriInterface $uri - * - * @return UriInterface - * @throws \InvalidArgumentException - */ -function uri_for($uri) -{ - if ($uri instanceof UriInterface) { - return $uri; - } elseif (is_string($uri)) { - return new Uri($uri); - } - - throw new \InvalidArgumentException('URI must be a string or UriInterface'); -} - -/** - * Create a new stream based on the input type. - * - * Options is an associative array that can contain the following keys: - * - metadata: Array of custom metadata. - * - size: Size of the stream. - * - * @param resource|string|StreamInterface $resource Entity body data - * @param array $options Additional options - * - * @return Stream - * @throws \InvalidArgumentException if the $resource arg is not valid. - */ -function stream_for($resource = '', array $options = array()) -{ - switch (gettype($resource)) { - case 'string': - $stream = fopen('php://temp', 'r+'); - if ($resource !== '') { - fwrite($stream, $resource); - fseek($stream, 0); - } - return new Stream($stream, $options); - case 'resource': - return new Stream($resource, $options); - case 'object': - if ($resource instanceof StreamInterface) { - return $resource; - } elseif ($resource instanceof \Iterator) { - return new PumpStream(function () use ($resource) { - if (!$resource->valid()) { - return false; - } - $result = $resource->current(); - $resource->next(); - return $result; - }, $options); - } elseif (method_exists($resource, '__toString')) { - return stream_for((string) $resource, $options); - } - break; - case 'NULL': - return new Stream(fopen('php://temp', 'r+'), $options); - } - - if (is_callable($resource)) { - return new PumpStream($resource, $options); - } - - throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource)); -} - -/** - * Parse an array of header values containing ";" separated data into an - * array of associative arrays representing the header key value pair - * data of the header. When a parameter does not contain a value, but just - * contains a key, this function will inject a key with a '' string value. - * - * @param string|array $header Header to parse into components. - * - * @return array Returns the parsed header values. - */ -function parse_header($header) -{ - static $trimmed = "\"' \n\t\r"; - $params = $matches = array(); - - foreach (normalize_header($header) as $val) { - $part = array(); - foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) { - if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) { - $m = $matches[0]; - if (isset($m[1])) { - $part[trim($m[0], $trimmed)] = trim($m[1], $trimmed); - } else { - $part[] = trim($m[0], $trimmed); - } - } - } - if ($part) { - $params[] = $part; - } - } - - return $params; -} - -/** - * Converts an array of header values that may contain comma separated - * headers into an array of headers with no comma separated values. - * - * @param string|array $header Header to normalize. - * - * @return array Returns the normalized header field values. - */ -function normalize_header($header) -{ - if (!is_array($header)) { - return array_map('trim', explode(',', $header)); - } - - $result = array(); - foreach ($header as $value) { - foreach ((array) $value as $v) { - if (strpos($v, ',') === false) { - $result[] = $v; - continue; - } - foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $v) as $vv) { - $result[] = trim($vv); - } - } - } - - return $result; -} - -/** - * Clone and modify a request with the given changes. - * - * The changes can be one of: - * - method: (string) Changes the HTTP method. - * - set_headers: (array) Sets the given headers. - * - remove_headers: (array) Remove the given headers. - * - body: (mixed) Sets the given body. - * - uri: (UriInterface) Set the URI. - * - query: (string) Set the query string value of the URI. - * - version: (string) Set the protocol version. - * - * @param RequestInterface $request Request to clone and modify. - * @param array $changes Changes to apply. - * - * @return RequestInterface - */ -function modify_request(RequestInterface $request, array $changes) -{ - if (!$changes) { - return $request; - } - - $headers = $request->getHeaders(); - - if (!isset($changes['uri'])) { - $uri = $request->getUri(); - } else { - // Remove the host header if one is on the URI - if ($host = $changes['uri']->getHost()) { - $changes['set_headers']['Host'] = $host; - } - $uri = $changes['uri']; - } - - if (!empty($changes['remove_headers'])) { - $headers = _caseless_remove($changes['remove_headers'], $headers); - } - - if (!empty($changes['set_headers'])) { - $headers = _caseless_remove(array_keys($changes['set_headers']), $headers); - $headers = $changes['set_headers'] + $headers; - } - - if (isset($changes['query'])) { - $uri = $uri->withQuery($changes['query']); - } - - return new Request( - isset($changes['method']) ? $changes['method'] : $request->getMethod(), - $uri, - $headers, - isset($changes['body']) ? $changes['body'] : $request->getBody(), - isset($changes['version']) - ? $changes['version'] - : $request->getProtocolVersion() - ); -} - -/** - * Attempts to rewind a message body and throws an exception on failure. - * - * The body of the message will only be rewound if a call to `tell()` returns a - * value other than `0`. - * - * @param MessageInterface $message Message to rewind - * - * @throws \RuntimeException - */ -function rewind_body(MessageInterface $message) -{ - $body = $message->getBody(); - - if ($body->tell()) { - $body->rewind(); - } -} - -/** - * Safely opens a PHP stream resource using a filename. - * - * When fopen fails, PHP normally raises a warning. This function adds an - * error handler that checks for errors and throws an exception instead. - * - * @param string $filename File to open - * @param string $mode Mode used to open the file - * - * @return resource - * @throws \RuntimeException if the file cannot be opened - */ -function try_fopen($filename, $mode) -{ - $ex = null; - $fargs = func_get_args(); - set_error_handler(function () use ($filename, $mode, &$ex, $fargs) { - $ex = new \RuntimeException(sprintf( - 'Unable to open %s using mode %s: %s', - $filename, - $mode, - $fargs[1] - )); - }); - - $handle = fopen($filename, $mode); - restore_error_handler(); - - if ($ex) { - /** @var $ex \RuntimeException */ - throw $ex; - } - - return $handle; -} - -/** - * Copy the contents of a stream into a string until the given number of - * bytes have been read. - * - * @param StreamInterface $stream Stream to read - * @param int $maxLen Maximum number of bytes to read. Pass -1 - * to read the entire stream. - * @return string - * @throws \RuntimeException on error. - */ -function copy_to_string(StreamInterface $stream, $maxLen = -1) -{ - $buffer = ''; - - if ($maxLen === -1) { - while (!$stream->eof()) { - $buf = $stream->read(1048576); - // Using a loose equality here to match on '' and false. - if ($buf == null) { - break; - } - $buffer .= $buf; - } - return $buffer; - } - - $len = 0; - while (!$stream->eof() && $len < $maxLen) { - $buf = $stream->read($maxLen - $len); - // Using a loose equality here to match on '' and false. - if ($buf == null) { - break; - } - $buffer .= $buf; - $len = strlen($buffer); - } - - return $buffer; -} - -/** - * Copy the contents of a stream into another stream until the given number - * of bytes have been read. - * - * @param StreamInterface $source Stream to read from - * @param StreamInterface $dest Stream to write to - * @param int $maxLen Maximum number of bytes to read. Pass -1 - * to read the entire stream. - * - * @throws \RuntimeException on error. - */ -function copy_to_stream( - StreamInterface $source, - StreamInterface $dest, - $maxLen = -1 -) { - if ($maxLen === -1) { - while (!$source->eof()) { - if (!$dest->write($source->read(1048576))) { - break; - } - } - return; - } - - $bytes = 0; - while (!$source->eof()) { - $buf = $source->read($maxLen - $bytes); - if (!($len = strlen($buf))) { - break; - } - $bytes += $len; - $dest->write($buf); - if ($bytes == $maxLen) { - break; - } - } -} - -/** - * Calculate a hash of a Stream - * - * @param StreamInterface $stream Stream to calculate the hash for - * @param string $algo Hash algorithm (e.g. md5, crc32, etc) - * @param bool $rawOutput Whether or not to use raw output - * - * @return string Returns the hash of the stream - * @throws \RuntimeException on error. - */ -function hash( - StreamInterface $stream, - $algo, - $rawOutput = false -) { - $pos = $stream->tell(); - - if ($pos > 0) { - $stream->rewind(); - } - - $ctx = hash_init($algo); - while (!$stream->eof()) { - hash_update($ctx, $stream->read(1048576)); - } - - $out = hash_final($ctx, (bool) $rawOutput); - $stream->seek($pos); - - return $out; -} - -/** - * Read a line from the stream up to the maximum allowed buffer length - * - * @param StreamInterface $stream Stream to read from - * @param int $maxLength Maximum buffer length - * - * @return string|bool - */ -function readline(StreamInterface $stream, $maxLength = null) -{ - $buffer = ''; - $size = 0; - - while (!$stream->eof()) { - // Using a loose equality here to match on '' and false. - if (null == ($byte = $stream->read(1))) { - return $buffer; - } - $buffer .= $byte; - // Break when a new line is found or the max length - 1 is reached - if ($byte == PHP_EOL || ++$size == $maxLength - 1) { - break; - } - } - - return $buffer; -} - -/** - * Parses a request message string into a request object. - * - * @param string $message Request message string. - * - * @return Request - */ -function parse_request($message) -{ - $data = _parse_message($message); - $matches = array(); - if (!preg_match('/^[a-zA-Z]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) { - throw new \InvalidArgumentException('Invalid request string'); - } - $parts = explode(' ', $data['start-line'], 3); - $subParts = isset($parts[2]) ? explode('/', $parts[2]) : array(); - $version = isset($parts[2]) ? $subParts[1] : '1.1'; - - $request = new Request( - $parts[0], - $matches[1] === '/' ? _parse_request_uri($parts[1], $data['headers']) : $parts[1], - $data['headers'], - $data['body'], - $version - ); - - return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]); -} - -/** - * Parses a request message string into a server request object. - * - * @param string $message Request message string. - * @param array $serverParams Server params that will be added to the - * ServerRequest object - * - * @return ServerRequest - */ -function parse_server_request($message, array $serverParams = array()) -{ - $request = parse_request($message); - - return new ServerRequest( - $request->getMethod(), - $request->getUri(), - $request->getHeaders(), - $request->getBody(), - $request->getProtocolVersion(), - $serverParams - ); -} - -/** - * Parses a response message string into a response object. - * - * @param string $message Response message string. - * - * @return Response - */ -function parse_response($message) -{ - $data = _parse_message($message); - // According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space - // between status-code and reason-phrase is required. But browsers accept - // responses without space and reason as well. - if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) { - throw new \InvalidArgumentException('Invalid response string'); - } - $parts = explode(' ', $data['start-line'], 3); - $subParts = explode('/', $parts[0]); - - return new Response( - $parts[1], - $data['headers'], - $data['body'], - $subParts[1], - isset($parts[2]) ? $parts[2] : null - ); -} - -/** - * Parse a query string into an associative array. - * - * If multiple values are found for the same key, the value of that key - * value pair will become an array. This function does not parse nested - * PHP style arrays into an associative array (e.g., foo[a]=1&foo[b]=2 will - * be parsed into ['foo[a]' => '1', 'foo[b]' => '2']). - * - * @param string $str Query string to parse - * @param bool|string $urlEncoding How the query string is encoded - * - * @return array - */ -function parse_query($str, $urlEncoding = true) -{ - $result = array(); - - if ($str === '') { - return $result; - } - - if ($urlEncoding === true) { - $decoder = function ($value) { - return rawurldecode(str_replace('+', ' ', $value)); - }; - } elseif ($urlEncoding == PHP_QUERY_RFC3986) { - $decoder = 'rawurldecode'; - } elseif ($urlEncoding == PHP_QUERY_RFC1738) { - $decoder = 'urldecode'; - } else { - $decoder = function ($str) { return $str; }; - } - - foreach (explode('&', $str) as $kvp) { - $parts = explode('=', $kvp, 2); - $key = $decoder($parts[0]); - $value = isset($parts[1]) ? $decoder($parts[1]) : null; - if (!isset($result[$key])) { - $result[$key] = $value; - } else { - if (!is_array($result[$key])) { - $result[$key] = array($result[$key]); - } - $result[$key][] = $value; - } - } - - return $result; -} - -/** - * Build a query string from an array of key value pairs. - * - * This function can use the return value of parseQuery() to build a query - * string. This function does not modify the provided keys when an array is - * encountered (like http_build_query would). - * - * @param array $params Query string parameters. - * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986 - * to encode using RFC3986, or PHP_QUERY_RFC1738 - * to encode using RFC1738. - * @return string - */ -function build_query(array $params, $encoding = PHP_QUERY_RFC3986) -{ - if (!$params) { - return ''; - } - - if ($encoding === false) { - $encoder = function ($str) { return $str; }; - } elseif ($encoding == PHP_QUERY_RFC3986) { - $encoder = 'rawurlencode'; - } elseif ($encoding == PHP_QUERY_RFC1738) { - $encoder = 'urlencode'; - } else { - throw new \InvalidArgumentException('Invalid type'); - } - - $qs = ''; - foreach ($params as $k => $v) { - $k = $encoder($k); - if (!is_array($v)) { - $qs .= $k; - if ($v !== null) { - $qs .= '=' . $encoder($v); - } - $qs .= '&'; - } else { - foreach ($v as $vv) { - $qs .= $k; - if ($vv !== null) { - $qs .= '=' . $encoder($vv); - } - $qs .= '&'; - } - } - } - - return $qs ? (string) substr($qs, 0, -1) : ''; -} - -/** - * Determines the mimetype of a file by looking at its extension. - * - * @param $filename - * - * @return null|string - */ -function mimetype_from_filename($filename) -{ - return mimetype_from_extension(pathinfo($filename, PATHINFO_EXTENSION)); -} - -/** - * Maps a file extensions to a mimetype. - * - * @param $extension string The file extension. - * - * @return string|null - * @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types - */ -function mimetype_from_extension($extension) -{ - static $mimetypes = array( - '7z' => 'application/x-7z-compressed', - 'aac' => 'audio/x-aac', - 'ai' => 'application/postscript', - 'aif' => 'audio/x-aiff', - 'asc' => 'text/plain', - 'asf' => 'video/x-ms-asf', - 'atom' => 'application/atom+xml', - 'avi' => 'video/x-msvideo', - 'bmp' => 'image/bmp', - 'bz2' => 'application/x-bzip2', - 'cer' => 'application/pkix-cert', - 'crl' => 'application/pkix-crl', - 'crt' => 'application/x-x509-ca-cert', - 'css' => 'text/css', - 'csv' => 'text/csv', - 'cu' => 'application/cu-seeme', - 'deb' => 'application/x-debian-package', - 'doc' => 'application/msword', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'dvi' => 'application/x-dvi', - 'eot' => 'application/vnd.ms-fontobject', - 'eps' => 'application/postscript', - 'epub' => 'application/epub+zip', - 'etx' => 'text/x-setext', - 'flac' => 'audio/flac', - 'flv' => 'video/x-flv', - 'gif' => 'image/gif', - 'gz' => 'application/gzip', - 'htm' => 'text/html', - 'html' => 'text/html', - 'ico' => 'image/x-icon', - 'ics' => 'text/calendar', - 'ini' => 'text/plain', - 'iso' => 'application/x-iso9660-image', - 'jar' => 'application/java-archive', - 'jpe' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'js' => 'text/javascript', - 'json' => 'application/json', - 'latex' => 'application/x-latex', - 'log' => 'text/plain', - 'm4a' => 'audio/mp4', - 'm4v' => 'video/mp4', - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mov' => 'video/quicktime', - 'mp3' => 'audio/mpeg', - 'mp4' => 'video/mp4', - 'mp4a' => 'audio/mp4', - 'mp4v' => 'video/mp4', - 'mpe' => 'video/mpeg', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpg4' => 'video/mp4', - 'oga' => 'audio/ogg', - 'ogg' => 'audio/ogg', - 'ogv' => 'video/ogg', - 'ogx' => 'application/ogg', - 'pbm' => 'image/x-portable-bitmap', - 'pdf' => 'application/pdf', - 'pgm' => 'image/x-portable-graymap', - 'png' => 'image/png', - 'pnm' => 'image/x-portable-anymap', - 'ppm' => 'image/x-portable-pixmap', - 'ppt' => 'application/vnd.ms-powerpoint', - 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'ps' => 'application/postscript', - 'qt' => 'video/quicktime', - 'rar' => 'application/x-rar-compressed', - 'ras' => 'image/x-cmu-raster', - 'rss' => 'application/rss+xml', - 'rtf' => 'application/rtf', - 'sgm' => 'text/sgml', - 'sgml' => 'text/sgml', - 'svg' => 'image/svg+xml', - 'swf' => 'application/x-shockwave-flash', - 'tar' => 'application/x-tar', - 'tif' => 'image/tiff', - 'tiff' => 'image/tiff', - 'torrent' => 'application/x-bittorrent', - 'ttf' => 'application/x-font-ttf', - 'txt' => 'text/plain', - 'wav' => 'audio/x-wav', - 'webm' => 'video/webm', - 'wma' => 'audio/x-ms-wma', - 'wmv' => 'video/x-ms-wmv', - 'woff' => 'application/x-font-woff', - 'wsdl' => 'application/wsdl+xml', - 'xbm' => 'image/x-xbitmap', - 'xls' => 'application/vnd.ms-excel', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'xml' => 'application/xml', - 'xpm' => 'image/x-xpixmap', - 'xwd' => 'image/x-xwindowdump', - 'yaml' => 'text/yaml', - 'yml' => 'text/yaml', - 'zip' => 'application/zip', - ); - - $extension = strtolower($extension); - - return isset($mimetypes[$extension]) - ? $mimetypes[$extension] - : null; -} - -/** - * Parses an HTTP message into an associative array. - * - * The array contains the "start-line" key containing the start line of - * the message, "headers" key containing an associative array of header - * array values, and a "body" key containing the body of the message. - * - * @param string $message HTTP request or response to parse. - * - * @return array - * @internal - */ -function _parse_message($message) -{ - if (!$message) { - throw new \InvalidArgumentException('Invalid message'); - } - - // Iterate over each line in the message, accounting for line endings - $lines = preg_split('/(\\r?\\n)/', $message, -1, PREG_SPLIT_DELIM_CAPTURE); - $result = array('start-line' => array_shift($lines), 'headers' => array(), 'body' => ''); - array_shift($lines); - - for ($i = 0, $totalLines = count($lines); $i < $totalLines; $i += 2) { - $line = $lines[$i]; - // If two line breaks were encountered, then this is the end of body - if (empty($line)) { - if ($i < $totalLines - 1) { - $result['body'] = implode('', array_slice($lines, $i + 2)); - } - break; - } - if (strpos($line, ':')) { - $parts = explode(':', $line, 2); - $key = trim($parts[0]); - $value = isset($parts[1]) ? trim($parts[1]) : ''; - $result['headers'][$key][] = $value; - } - } - - return $result; -} - -/** - * Constructs a URI for an HTTP request message. - * - * @param string $path Path from the start-line - * @param array $headers Array of headers (each value an array). - * - * @return string - * @internal - */ -function _parse_request_uri($path, array $headers) -{ - $hostKey = array_filter(array_keys($headers), function ($k) { - return strtolower($k) === 'host'; - }); - - // If no host is found, then a full URI cannot be constructed. - if (!$hostKey) { - return $path; - } - - $host = $headers[reset($hostKey)][0]; - $scheme = substr($host, -4) === ':443' ? 'https' : 'http'; - - return $scheme . '://' . $host . '/' . ltrim($path, '/'); -} - -/** @internal */ -function _caseless_remove($keys, array $data) -{ - $result = array(); - - foreach ($keys as &$key) { - $key = strtolower($key); - } - - foreach ($data as $k => $v) { - if (!in_array(strtolower($k), $keys)) { - $result[$k] = $v; - } - } - - return $result; -} diff --git a/vendor/ringcentral/psr7/src/functions_include.php b/vendor/ringcentral/psr7/src/functions_include.php deleted file mode 100644 index 252e0cfd1..000000000 --- a/vendor/ringcentral/psr7/src/functions_include.php +++ /dev/null @@ -1,6 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Command\CompleteCommand; -use Symfony\Component\Console\Command\DumpCompletionCommand; -use Symfony\Component\Console\Command\HelpCommand; -use Symfony\Component\Console\Command\LazyCommand; -use Symfony\Component\Console\Command\ListCommand; -use Symfony\Component\Console\Command\SignalableCommandInterface; -use Symfony\Component\Console\CommandLoader\CommandLoaderInterface; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Event\ConsoleCommandEvent; -use Symfony\Component\Console\Event\ConsoleErrorEvent; -use Symfony\Component\Console\Event\ConsoleSignalEvent; -use Symfony\Component\Console\Event\ConsoleTerminateEvent; -use Symfony\Component\Console\Exception\CommandNotFoundException; -use Symfony\Component\Console\Exception\ExceptionInterface; -use Symfony\Component\Console\Exception\LogicException; -use Symfony\Component\Console\Exception\NamespaceNotFoundException; -use Symfony\Component\Console\Exception\RuntimeException; -use Symfony\Component\Console\Formatter\OutputFormatter; -use Symfony\Component\Console\Helper\DebugFormatterHelper; -use Symfony\Component\Console\Helper\FormatterHelper; -use Symfony\Component\Console\Helper\Helper; -use Symfony\Component\Console\Helper\HelperSet; -use Symfony\Component\Console\Helper\ProcessHelper; -use Symfony\Component\Console\Helper\QuestionHelper; -use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputAwareInterface; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\ConsoleOutput; -use Symfony\Component\Console\Output\ConsoleOutputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\SignalRegistry\SignalRegistry; -use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\ErrorHandler\ErrorHandler; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; -use Symfony\Contracts\Service\ResetInterface; - -/** - * An Application is the container for a collection of commands. - * - * It is the main entry point of a Console application. - * - * This class is optimized for a standard CLI environment. - * - * Usage: - * - * $app = new Application('myapp', '1.0 (stable)'); - * $app->add(new SimpleCommand()); - * $app->run(); - * - * @author Fabien Potencier - */ -class Application implements ResetInterface -{ - private $commands = []; - private $wantHelps = false; - private $runningCommand; - private $name; - private $version; - private $commandLoader; - private $catchExceptions = true; - private $autoExit = true; - private $definition; - private $helperSet; - private $dispatcher; - private $terminal; - private $defaultCommand; - private $singleCommand = false; - private $initialized; - private $signalRegistry; - private $signalsToDispatchEvent = []; - - public function __construct(string $name = 'UNKNOWN', string $version = 'UNKNOWN') - { - $this->name = $name; - $this->version = $version; - $this->terminal = new Terminal(); - $this->defaultCommand = 'list'; - if (\defined('SIGINT') && SignalRegistry::isSupported()) { - $this->signalRegistry = new SignalRegistry(); - $this->signalsToDispatchEvent = [\SIGINT, \SIGTERM, \SIGUSR1, \SIGUSR2]; - } - } - - /** - * @final - */ - public function setDispatcher(EventDispatcherInterface $dispatcher) - { - $this->dispatcher = $dispatcher; - } - - public function setCommandLoader(CommandLoaderInterface $commandLoader) - { - $this->commandLoader = $commandLoader; - } - - public function getSignalRegistry(): SignalRegistry - { - if (!$this->signalRegistry) { - throw new RuntimeException('Signals are not supported. Make sure that the `pcntl` extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.'); - } - - return $this->signalRegistry; - } - - public function setSignalsToDispatchEvent(int ...$signalsToDispatchEvent) - { - $this->signalsToDispatchEvent = $signalsToDispatchEvent; - } - - /** - * Runs the current application. - * - * @return int 0 if everything went fine, or an error code - * - * @throws \Exception When running fails. Bypass this when {@link setCatchExceptions()}. - */ - public function run(InputInterface $input = null, OutputInterface $output = null) - { - if (\function_exists('putenv')) { - @putenv('LINES='.$this->terminal->getHeight()); - @putenv('COLUMNS='.$this->terminal->getWidth()); - } - - if (null === $input) { - $input = new ArgvInput(); - } - - if (null === $output) { - $output = new ConsoleOutput(); - } - - $renderException = function (\Throwable $e) use ($output) { - if ($output instanceof ConsoleOutputInterface) { - $this->renderThrowable($e, $output->getErrorOutput()); - } else { - $this->renderThrowable($e, $output); - } - }; - if ($phpHandler = set_exception_handler($renderException)) { - restore_exception_handler(); - if (!\is_array($phpHandler) || !$phpHandler[0] instanceof ErrorHandler) { - $errorHandler = true; - } elseif ($errorHandler = $phpHandler[0]->setExceptionHandler($renderException)) { - $phpHandler[0]->setExceptionHandler($errorHandler); - } - } - - $this->configureIO($input, $output); - - try { - $exitCode = $this->doRun($input, $output); - } catch (\Exception $e) { - if (!$this->catchExceptions) { - throw $e; - } - - $renderException($e); - - $exitCode = $e->getCode(); - if (is_numeric($exitCode)) { - $exitCode = (int) $exitCode; - if ($exitCode <= 0) { - $exitCode = 1; - } - } else { - $exitCode = 1; - } - } finally { - // if the exception handler changed, keep it - // otherwise, unregister $renderException - if (!$phpHandler) { - if (set_exception_handler($renderException) === $renderException) { - restore_exception_handler(); - } - restore_exception_handler(); - } elseif (!$errorHandler) { - $finalHandler = $phpHandler[0]->setExceptionHandler(null); - if ($finalHandler !== $renderException) { - $phpHandler[0]->setExceptionHandler($finalHandler); - } - } - } - - if ($this->autoExit) { - if ($exitCode > 255) { - $exitCode = 255; - } - - exit($exitCode); - } - - return $exitCode; - } - - /** - * Runs the current application. - * - * @return int 0 if everything went fine, or an error code - */ - public function doRun(InputInterface $input, OutputInterface $output) - { - if (true === $input->hasParameterOption(['--version', '-V'], true)) { - $output->writeln($this->getLongVersion()); - - return 0; - } - - try { - // Makes ArgvInput::getFirstArgument() able to distinguish an option from an argument. - $input->bind($this->getDefinition()); - } catch (ExceptionInterface $e) { - // Errors must be ignored, full binding/validation happens later when the command is known. - } - - $name = $this->getCommandName($input); - if (true === $input->hasParameterOption(['--help', '-h'], true)) { - if (!$name) { - $name = 'help'; - $input = new ArrayInput(['command_name' => $this->defaultCommand]); - } else { - $this->wantHelps = true; - } - } - - if (!$name) { - $name = $this->defaultCommand; - $definition = $this->getDefinition(); - $definition->setArguments(array_merge( - $definition->getArguments(), - [ - 'command' => new InputArgument('command', InputArgument::OPTIONAL, $definition->getArgument('command')->getDescription(), $name), - ] - )); - } - - try { - $this->runningCommand = null; - // the command name MUST be the first element of the input - $command = $this->find($name); - } catch (\Throwable $e) { - if (!($e instanceof CommandNotFoundException && !$e instanceof NamespaceNotFoundException) || 1 !== \count($alternatives = $e->getAlternatives()) || !$input->isInteractive()) { - if (null !== $this->dispatcher) { - $event = new ConsoleErrorEvent($input, $output, $e); - $this->dispatcher->dispatch($event, ConsoleEvents::ERROR); - - if (0 === $event->getExitCode()) { - return 0; - } - - $e = $event->getError(); - } - - throw $e; - } - - $alternative = $alternatives[0]; - - $style = new SymfonyStyle($input, $output); - $output->writeln(''); - $formattedBlock = (new FormatterHelper())->formatBlock(sprintf('Command "%s" is not defined.', $name), 'error', true); - $output->writeln($formattedBlock); - if (!$style->confirm(sprintf('Do you want to run "%s" instead? ', $alternative), false)) { - if (null !== $this->dispatcher) { - $event = new ConsoleErrorEvent($input, $output, $e); - $this->dispatcher->dispatch($event, ConsoleEvents::ERROR); - - return $event->getExitCode(); - } - - return 1; - } - - $command = $this->find($alternative); - } - - if ($command instanceof LazyCommand) { - $command = $command->getCommand(); - } - - $this->runningCommand = $command; - $exitCode = $this->doRunCommand($command, $input, $output); - $this->runningCommand = null; - - return $exitCode; - } - - /** - * {@inheritdoc} - */ - public function reset() - { - } - - public function setHelperSet(HelperSet $helperSet) - { - $this->helperSet = $helperSet; - } - - /** - * Get the helper set associated with the command. - * - * @return HelperSet - */ - public function getHelperSet() - { - if (!$this->helperSet) { - $this->helperSet = $this->getDefaultHelperSet(); - } - - return $this->helperSet; - } - - public function setDefinition(InputDefinition $definition) - { - $this->definition = $definition; - } - - /** - * Gets the InputDefinition related to this Application. - * - * @return InputDefinition - */ - public function getDefinition() - { - if (!$this->definition) { - $this->definition = $this->getDefaultInputDefinition(); - } - - if ($this->singleCommand) { - $inputDefinition = $this->definition; - $inputDefinition->setArguments(); - - return $inputDefinition; - } - - return $this->definition; - } - - /** - * Adds suggestions to $suggestions for the current completion input (e.g. option or argument). - */ - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - if ( - CompletionInput::TYPE_ARGUMENT_VALUE === $input->getCompletionType() - && 'command' === $input->getCompletionName() - ) { - $commandNames = []; - foreach ($this->all() as $name => $command) { - // skip hidden commands and aliased commands as they already get added below - if ($command->isHidden() || $command->getName() !== $name) { - continue; - } - $commandNames[] = $command->getName(); - foreach ($command->getAliases() as $name) { - $commandNames[] = $name; - } - } - $suggestions->suggestValues(array_filter($commandNames)); - - return; - } - - if (CompletionInput::TYPE_OPTION_NAME === $input->getCompletionType()) { - $suggestions->suggestOptions($this->getDefinition()->getOptions()); - - return; - } - } - - /** - * Gets the help message. - * - * @return string - */ - public function getHelp() - { - return $this->getLongVersion(); - } - - /** - * Gets whether to catch exceptions or not during commands execution. - * - * @return bool - */ - public function areExceptionsCaught() - { - return $this->catchExceptions; - } - - /** - * Sets whether to catch exceptions or not during commands execution. - */ - public function setCatchExceptions(bool $boolean) - { - $this->catchExceptions = $boolean; - } - - /** - * Gets whether to automatically exit after a command execution or not. - * - * @return bool - */ - public function isAutoExitEnabled() - { - return $this->autoExit; - } - - /** - * Sets whether to automatically exit after a command execution or not. - */ - public function setAutoExit(bool $boolean) - { - $this->autoExit = $boolean; - } - - /** - * Gets the name of the application. - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Sets the application name. - **/ - public function setName(string $name) - { - $this->name = $name; - } - - /** - * Gets the application version. - * - * @return string - */ - public function getVersion() - { - return $this->version; - } - - /** - * Sets the application version. - */ - public function setVersion(string $version) - { - $this->version = $version; - } - - /** - * Returns the long version of the application. - * - * @return string - */ - public function getLongVersion() - { - if ('UNKNOWN' !== $this->getName()) { - if ('UNKNOWN' !== $this->getVersion()) { - return sprintf('%s %s', $this->getName(), $this->getVersion()); - } - - return $this->getName(); - } - - return 'Console Tool'; - } - - /** - * Registers a new command. - * - * @return Command - */ - public function register(string $name) - { - return $this->add(new Command($name)); - } - - /** - * Adds an array of command objects. - * - * If a Command is not enabled it will not be added. - * - * @param Command[] $commands An array of commands - */ - public function addCommands(array $commands) - { - foreach ($commands as $command) { - $this->add($command); - } - } - - /** - * Adds a command object. - * - * If a command with the same name already exists, it will be overridden. - * If the command is not enabled it will not be added. - * - * @return Command|null - */ - public function add(Command $command) - { - $this->init(); - - $command->setApplication($this); - - if (!$command->isEnabled()) { - $command->setApplication(null); - - return null; - } - - if (!$command instanceof LazyCommand) { - // Will throw if the command is not correctly initialized. - $command->getDefinition(); - } - - if (!$command->getName()) { - throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_debug_type($command))); - } - - $this->commands[$command->getName()] = $command; - - foreach ($command->getAliases() as $alias) { - $this->commands[$alias] = $command; - } - - return $command; - } - - /** - * Returns a registered command by name or alias. - * - * @return Command - * - * @throws CommandNotFoundException When given command name does not exist - */ - public function get(string $name) - { - $this->init(); - - if (!$this->has($name)) { - throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name)); - } - - // When the command has a different name than the one used at the command loader level - if (!isset($this->commands[$name])) { - throw new CommandNotFoundException(sprintf('The "%s" command cannot be found because it is registered under multiple names. Make sure you don\'t set a different name via constructor or "setName()".', $name)); - } - - $command = $this->commands[$name]; - - if ($this->wantHelps) { - $this->wantHelps = false; - - $helpCommand = $this->get('help'); - $helpCommand->setCommand($command); - - return $helpCommand; - } - - return $command; - } - - /** - * Returns true if the command exists, false otherwise. - * - * @return bool - */ - public function has(string $name) - { - $this->init(); - - return isset($this->commands[$name]) || ($this->commandLoader && $this->commandLoader->has($name) && $this->add($this->commandLoader->get($name))); - } - - /** - * Returns an array of all unique namespaces used by currently registered commands. - * - * It does not return the global namespace which always exists. - * - * @return string[] - */ - public function getNamespaces() - { - $namespaces = []; - foreach ($this->all() as $command) { - if ($command->isHidden()) { - continue; - } - - $namespaces[] = $this->extractAllNamespaces($command->getName()); - - foreach ($command->getAliases() as $alias) { - $namespaces[] = $this->extractAllNamespaces($alias); - } - } - - return array_values(array_unique(array_filter(array_merge([], ...$namespaces)))); - } - - /** - * Finds a registered namespace by a name or an abbreviation. - * - * @return string - * - * @throws NamespaceNotFoundException When namespace is incorrect or ambiguous - */ - public function findNamespace(string $namespace) - { - $allNamespaces = $this->getNamespaces(); - $expr = implode('[^:]*:', array_map('preg_quote', explode(':', $namespace))).'[^:]*'; - $namespaces = preg_grep('{^'.$expr.'}', $allNamespaces); - - if (empty($namespaces)) { - $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); - - if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) { - if (1 == \count($alternatives)) { - $message .= "\n\nDid you mean this?\n "; - } else { - $message .= "\n\nDid you mean one of these?\n "; - } - - $message .= implode("\n ", $alternatives); - } - - throw new NamespaceNotFoundException($message, $alternatives); - } - - $exact = \in_array($namespace, $namespaces, true); - if (\count($namespaces) > 1 && !$exact) { - throw new NamespaceNotFoundException(sprintf("The namespace \"%s\" is ambiguous.\nDid you mean one of these?\n%s.", $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces)); - } - - return $exact ? $namespace : reset($namespaces); - } - - /** - * Finds a command by name or alias. - * - * Contrary to get, this command tries to find the best - * match if you give it an abbreviation of a name or alias. - * - * @return Command - * - * @throws CommandNotFoundException When command name is incorrect or ambiguous - */ - public function find(string $name) - { - $this->init(); - - $aliases = []; - - foreach ($this->commands as $command) { - foreach ($command->getAliases() as $alias) { - if (!$this->has($alias)) { - $this->commands[$alias] = $command; - } - } - } - - if ($this->has($name)) { - return $this->get($name); - } - - $allCommands = $this->commandLoader ? array_merge($this->commandLoader->getNames(), array_keys($this->commands)) : array_keys($this->commands); - $expr = implode('[^:]*:', array_map('preg_quote', explode(':', $name))).'[^:]*'; - $commands = preg_grep('{^'.$expr.'}', $allCommands); - - if (empty($commands)) { - $commands = preg_grep('{^'.$expr.'}i', $allCommands); - } - - // if no commands matched or we just matched namespaces - if (empty($commands) || \count(preg_grep('{^'.$expr.'$}i', $commands)) < 1) { - if (false !== $pos = strrpos($name, ':')) { - // check if a namespace exists and contains commands - $this->findNamespace(substr($name, 0, $pos)); - } - - $message = sprintf('Command "%s" is not defined.', $name); - - if ($alternatives = $this->findAlternatives($name, $allCommands)) { - // remove hidden commands - $alternatives = array_filter($alternatives, function ($name) { - return !$this->get($name)->isHidden(); - }); - - if (1 == \count($alternatives)) { - $message .= "\n\nDid you mean this?\n "; - } else { - $message .= "\n\nDid you mean one of these?\n "; - } - $message .= implode("\n ", $alternatives); - } - - throw new CommandNotFoundException($message, array_values($alternatives)); - } - - // filter out aliases for commands which are already on the list - if (\count($commands) > 1) { - $commandList = $this->commandLoader ? array_merge(array_flip($this->commandLoader->getNames()), $this->commands) : $this->commands; - $commands = array_unique(array_filter($commands, function ($nameOrAlias) use (&$commandList, $commands, &$aliases) { - if (!$commandList[$nameOrAlias] instanceof Command) { - $commandList[$nameOrAlias] = $this->commandLoader->get($nameOrAlias); - } - - $commandName = $commandList[$nameOrAlias]->getName(); - - $aliases[$nameOrAlias] = $commandName; - - return $commandName === $nameOrAlias || !\in_array($commandName, $commands); - })); - } - - if (\count($commands) > 1) { - $usableWidth = $this->terminal->getWidth() - 10; - $abbrevs = array_values($commands); - $maxLen = 0; - foreach ($abbrevs as $abbrev) { - $maxLen = max(Helper::width($abbrev), $maxLen); - } - $abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen, &$commands) { - if ($commandList[$cmd]->isHidden()) { - unset($commands[array_search($cmd, $commands)]); - - return false; - } - - $abbrev = str_pad($cmd, $maxLen, ' ').' '.$commandList[$cmd]->getDescription(); - - return Helper::width($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3).'...' : $abbrev; - }, array_values($commands)); - - if (\count($commands) > 1) { - $suggestions = $this->getAbbreviationSuggestions(array_filter($abbrevs)); - - throw new CommandNotFoundException(sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s.", $name, $suggestions), array_values($commands)); - } - } - - $command = $this->get(reset($commands)); - - if ($command->isHidden()) { - throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name)); - } - - return $command; - } - - /** - * Gets the commands (registered in the given namespace if provided). - * - * The array keys are the full names and the values the command instances. - * - * @return Command[] - */ - public function all(string $namespace = null) - { - $this->init(); - - if (null === $namespace) { - if (!$this->commandLoader) { - return $this->commands; - } - - $commands = $this->commands; - foreach ($this->commandLoader->getNames() as $name) { - if (!isset($commands[$name]) && $this->has($name)) { - $commands[$name] = $this->get($name); - } - } - - return $commands; - } - - $commands = []; - foreach ($this->commands as $name => $command) { - if ($namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) { - $commands[$name] = $command; - } - } - - if ($this->commandLoader) { - foreach ($this->commandLoader->getNames() as $name) { - if (!isset($commands[$name]) && $namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1) && $this->has($name)) { - $commands[$name] = $this->get($name); - } - } - } - - return $commands; - } - - /** - * Returns an array of possible abbreviations given a set of names. - * - * @return string[][] - */ - public static function getAbbreviations(array $names) - { - $abbrevs = []; - foreach ($names as $name) { - for ($len = \strlen($name); $len > 0; --$len) { - $abbrev = substr($name, 0, $len); - $abbrevs[$abbrev][] = $name; - } - } - - return $abbrevs; - } - - public function renderThrowable(\Throwable $e, OutputInterface $output): void - { - $output->writeln('', OutputInterface::VERBOSITY_QUIET); - - $this->doRenderThrowable($e, $output); - - if (null !== $this->runningCommand) { - $output->writeln(sprintf('%s', OutputFormatter::escape(sprintf($this->runningCommand->getSynopsis(), $this->getName()))), OutputInterface::VERBOSITY_QUIET); - $output->writeln('', OutputInterface::VERBOSITY_QUIET); - } - } - - protected function doRenderThrowable(\Throwable $e, OutputInterface $output): void - { - do { - $message = trim($e->getMessage()); - if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { - $class = get_debug_type($e); - $title = sprintf(' [%s%s] ', $class, 0 !== ($code = $e->getCode()) ? ' ('.$code.')' : ''); - $len = Helper::width($title); - } else { - $len = 0; - } - - if (str_contains($message, "@anonymous\0")) { - $message = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { - return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0]; - }, $message); - } - - $width = $this->terminal->getWidth() ? $this->terminal->getWidth() - 1 : \PHP_INT_MAX; - $lines = []; - foreach ('' !== $message ? preg_split('/\r?\n/', $message) : [] as $line) { - foreach ($this->splitStringByWidth($line, $width - 4) as $line) { - // pre-format lines to get the right string length - $lineLength = Helper::width($line) + 4; - $lines[] = [$line, $lineLength]; - - $len = max($lineLength, $len); - } - } - - $messages = []; - if (!$e instanceof ExceptionInterface || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { - $messages[] = sprintf('%s', OutputFormatter::escape(sprintf('In %s line %s:', basename($e->getFile()) ?: 'n/a', $e->getLine() ?: 'n/a'))); - } - $messages[] = $emptyLine = sprintf('%s', str_repeat(' ', $len)); - if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { - $messages[] = sprintf('%s%s', $title, str_repeat(' ', max(0, $len - Helper::width($title)))); - } - foreach ($lines as $line) { - $messages[] = sprintf(' %s %s', OutputFormatter::escape($line[0]), str_repeat(' ', $len - $line[1])); - } - $messages[] = $emptyLine; - $messages[] = ''; - - $output->writeln($messages, OutputInterface::VERBOSITY_QUIET); - - if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { - $output->writeln('Exception trace:', OutputInterface::VERBOSITY_QUIET); - - // exception related properties - $trace = $e->getTrace(); - - array_unshift($trace, [ - 'function' => '', - 'file' => $e->getFile() ?: 'n/a', - 'line' => $e->getLine() ?: 'n/a', - 'args' => [], - ]); - - for ($i = 0, $count = \count($trace); $i < $count; ++$i) { - $class = $trace[$i]['class'] ?? ''; - $type = $trace[$i]['type'] ?? ''; - $function = $trace[$i]['function'] ?? ''; - $file = $trace[$i]['file'] ?? 'n/a'; - $line = $trace[$i]['line'] ?? 'n/a'; - - $output->writeln(sprintf(' %s%s at %s:%s', $class, $function ? $type.$function.'()' : '', $file, $line), OutputInterface::VERBOSITY_QUIET); - } - - $output->writeln('', OutputInterface::VERBOSITY_QUIET); - } - } while ($e = $e->getPrevious()); - } - - /** - * Configures the input and output instances based on the user arguments and options. - */ - protected function configureIO(InputInterface $input, OutputInterface $output) - { - if (true === $input->hasParameterOption(['--ansi'], true)) { - $output->setDecorated(true); - } elseif (true === $input->hasParameterOption(['--no-ansi'], true)) { - $output->setDecorated(false); - } - - if (true === $input->hasParameterOption(['--no-interaction', '-n'], true)) { - $input->setInteractive(false); - } - - switch ($shellVerbosity = (int) getenv('SHELL_VERBOSITY')) { - case -1: - $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); - break; - case 1: - $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); - break; - case 2: - $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE); - break; - case 3: - $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); - break; - default: - $shellVerbosity = 0; - break; - } - - if (true === $input->hasParameterOption(['--quiet', '-q'], true)) { - $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); - $shellVerbosity = -1; - } else { - if ($input->hasParameterOption('-vvv', true) || $input->hasParameterOption('--verbose=3', true) || 3 === $input->getParameterOption('--verbose', false, true)) { - $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); - $shellVerbosity = 3; - } elseif ($input->hasParameterOption('-vv', true) || $input->hasParameterOption('--verbose=2', true) || 2 === $input->getParameterOption('--verbose', false, true)) { - $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE); - $shellVerbosity = 2; - } elseif ($input->hasParameterOption('-v', true) || $input->hasParameterOption('--verbose=1', true) || $input->hasParameterOption('--verbose', true) || $input->getParameterOption('--verbose', false, true)) { - $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); - $shellVerbosity = 1; - } - } - - if (-1 === $shellVerbosity) { - $input->setInteractive(false); - } - - if (\function_exists('putenv')) { - @putenv('SHELL_VERBOSITY='.$shellVerbosity); - } - $_ENV['SHELL_VERBOSITY'] = $shellVerbosity; - $_SERVER['SHELL_VERBOSITY'] = $shellVerbosity; - } - - /** - * Runs the current command. - * - * If an event dispatcher has been attached to the application, - * events are also dispatched during the life-cycle of the command. - * - * @return int 0 if everything went fine, or an error code - */ - protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output) - { - foreach ($command->getHelperSet() as $helper) { - if ($helper instanceof InputAwareInterface) { - $helper->setInput($input); - } - } - - if ($this->signalsToDispatchEvent) { - $commandSignals = $command instanceof SignalableCommandInterface ? $command->getSubscribedSignals() : []; - - if ($commandSignals || null !== $this->dispatcher) { - if (!$this->signalRegistry) { - throw new RuntimeException('Unable to subscribe to signal events. Make sure that the `pcntl` extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.'); - } - - if (Terminal::hasSttyAvailable()) { - $sttyMode = shell_exec('stty -g'); - - foreach ([\SIGINT, \SIGTERM] as $signal) { - $this->signalRegistry->register($signal, static function () use ($sttyMode) { - shell_exec('stty '.$sttyMode); - }); - } - } - } - - if (null !== $this->dispatcher) { - foreach ($this->signalsToDispatchEvent as $signal) { - $event = new ConsoleSignalEvent($command, $input, $output, $signal); - - $this->signalRegistry->register($signal, function ($signal, $hasNext) use ($event) { - $this->dispatcher->dispatch($event, ConsoleEvents::SIGNAL); - - // No more handlers, we try to simulate PHP default behavior - if (!$hasNext) { - if (!\in_array($signal, [\SIGUSR1, \SIGUSR2], true)) { - exit(0); - } - } - }); - } - } - - foreach ($commandSignals as $signal) { - $this->signalRegistry->register($signal, [$command, 'handleSignal']); - } - } - - if (null === $this->dispatcher) { - return $command->run($input, $output); - } - - // bind before the console.command event, so the listeners have access to input options/arguments - try { - $command->mergeApplicationDefinition(); - $input->bind($command->getDefinition()); - } catch (ExceptionInterface $e) { - // ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition - } - - $event = new ConsoleCommandEvent($command, $input, $output); - $e = null; - - try { - $this->dispatcher->dispatch($event, ConsoleEvents::COMMAND); - - if ($event->commandShouldRun()) { - $exitCode = $command->run($input, $output); - } else { - $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED; - } - } catch (\Throwable $e) { - $event = new ConsoleErrorEvent($input, $output, $e, $command); - $this->dispatcher->dispatch($event, ConsoleEvents::ERROR); - $e = $event->getError(); - - if (0 === $exitCode = $event->getExitCode()) { - $e = null; - } - } - - $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode); - $this->dispatcher->dispatch($event, ConsoleEvents::TERMINATE); - - if (null !== $e) { - throw $e; - } - - return $event->getExitCode(); - } - - /** - * Gets the name of the command based on input. - * - * @return string|null - */ - protected function getCommandName(InputInterface $input) - { - return $this->singleCommand ? $this->defaultCommand : $input->getFirstArgument(); - } - - /** - * Gets the default input definition. - * - * @return InputDefinition - */ - protected function getDefaultInputDefinition() - { - return new InputDefinition([ - new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'), - new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display help for the given command. When no command is given display help for the '.$this->defaultCommand.' command'), - new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'), - new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'), - new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version'), - new InputOption('--ansi', '', InputOption::VALUE_NEGATABLE, 'Force (or disable --no-ansi) ANSI output', null), - new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'), - ]); - } - - /** - * Gets the default commands that should always be available. - * - * @return Command[] - */ - protected function getDefaultCommands() - { - return [new HelpCommand(), new ListCommand(), new CompleteCommand(), new DumpCompletionCommand()]; - } - - /** - * Gets the default helper set with the helpers that should always be available. - * - * @return HelperSet - */ - protected function getDefaultHelperSet() - { - return new HelperSet([ - new FormatterHelper(), - new DebugFormatterHelper(), - new ProcessHelper(), - new QuestionHelper(), - ]); - } - - /** - * Returns abbreviated suggestions in string format. - */ - private function getAbbreviationSuggestions(array $abbrevs): string - { - return ' '.implode("\n ", $abbrevs); - } - - /** - * Returns the namespace part of the command name. - * - * This method is not part of public API and should not be used directly. - * - * @return string - */ - public function extractNamespace(string $name, int $limit = null) - { - $parts = explode(':', $name, -1); - - return implode(':', null === $limit ? $parts : \array_slice($parts, 0, $limit)); - } - - /** - * Finds alternative of $name among $collection, - * if nothing is found in $collection, try in $abbrevs. - * - * @return string[] - */ - private function findAlternatives(string $name, iterable $collection): array - { - $threshold = 1e3; - $alternatives = []; - - $collectionParts = []; - foreach ($collection as $item) { - $collectionParts[$item] = explode(':', $item); - } - - foreach (explode(':', $name) as $i => $subname) { - foreach ($collectionParts as $collectionName => $parts) { - $exists = isset($alternatives[$collectionName]); - if (!isset($parts[$i]) && $exists) { - $alternatives[$collectionName] += $threshold; - continue; - } elseif (!isset($parts[$i])) { - continue; - } - - $lev = levenshtein($subname, $parts[$i]); - if ($lev <= \strlen($subname) / 3 || '' !== $subname && str_contains($parts[$i], $subname)) { - $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev; - } elseif ($exists) { - $alternatives[$collectionName] += $threshold; - } - } - } - - foreach ($collection as $item) { - $lev = levenshtein($name, $item); - if ($lev <= \strlen($name) / 3 || str_contains($item, $name)) { - $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev; - } - } - - $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2 * $threshold; }); - ksort($alternatives, \SORT_NATURAL | \SORT_FLAG_CASE); - - return array_keys($alternatives); - } - - /** - * Sets the default Command name. - * - * @return $this - */ - public function setDefaultCommand(string $commandName, bool $isSingleCommand = false) - { - $this->defaultCommand = explode('|', ltrim($commandName, '|'))[0]; - - if ($isSingleCommand) { - // Ensure the command exist - $this->find($commandName); - - $this->singleCommand = true; - } - - return $this; - } - - /** - * @internal - */ - public function isSingleCommand(): bool - { - return $this->singleCommand; - } - - private function splitStringByWidth(string $string, int $width): array - { - // str_split is not suitable for multi-byte characters, we should use preg_split to get char array properly. - // additionally, array_slice() is not enough as some character has doubled width. - // we need a function to split string not by character count but by string width - if (false === $encoding = mb_detect_encoding($string, null, true)) { - return str_split($string, $width); - } - - $utf8String = mb_convert_encoding($string, 'utf8', $encoding); - $lines = []; - $line = ''; - - $offset = 0; - while (preg_match('/.{1,10000}/u', $utf8String, $m, 0, $offset)) { - $offset += \strlen($m[0]); - - foreach (preg_split('//u', $m[0]) as $char) { - // test if $char could be appended to current line - if (mb_strwidth($line.$char, 'utf8') <= $width) { - $line .= $char; - continue; - } - // if not, push current line to array and make new line - $lines[] = str_pad($line, $width); - $line = $char; - } - } - - $lines[] = \count($lines) ? str_pad($line, $width) : $line; - - mb_convert_variables($encoding, 'utf8', $lines); - - return $lines; - } - - /** - * Returns all namespaces of the command name. - * - * @return string[] - */ - private function extractAllNamespaces(string $name): array - { - // -1 as third argument is needed to skip the command short name when exploding - $parts = explode(':', $name, -1); - $namespaces = []; - - foreach ($parts as $part) { - if (\count($namespaces)) { - $namespaces[] = end($namespaces).':'.$part; - } else { - $namespaces[] = $part; - } - } - - return $namespaces; - } - - private function init() - { - if ($this->initialized) { - return; - } - $this->initialized = true; - - foreach ($this->getDefaultCommands() as $command) { - $this->add($command); - } - } -} diff --git a/vendor/symfony/console/Attribute/AsCommand.php b/vendor/symfony/console/Attribute/AsCommand.php deleted file mode 100644 index b337f548f..000000000 --- a/vendor/symfony/console/Attribute/AsCommand.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. - */ - -namespace Symfony\Component\Console\Attribute; - -/** - * Service tag to autoconfigure commands. - */ -#[\Attribute(\Attribute::TARGET_CLASS)] -class AsCommand -{ - public function __construct( - public string $name, - public ?string $description = null, - array $aliases = [], - bool $hidden = false, - ) { - if (!$hidden && !$aliases) { - return; - } - - $name = explode('|', $name); - $name = array_merge($name, $aliases); - - if ($hidden && '' !== $name[0]) { - array_unshift($name, ''); - } - - $this->name = implode('|', $name); - } -} diff --git a/vendor/symfony/console/CI/GithubActionReporter.php b/vendor/symfony/console/CI/GithubActionReporter.php deleted file mode 100644 index a15c1ff18..000000000 --- a/vendor/symfony/console/CI/GithubActionReporter.php +++ /dev/null @@ -1,99 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\CI; - -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Utility class for Github actions. - * - * @author Maxime Steinhausser - */ -class GithubActionReporter -{ - private $output; - - /** - * @see https://github.com/actions/toolkit/blob/5e5e1b7aacba68a53836a34db4a288c3c1c1585b/packages/core/src/command.ts#L80-L85 - */ - private const ESCAPED_DATA = [ - '%' => '%25', - "\r" => '%0D', - "\n" => '%0A', - ]; - - /** - * @see https://github.com/actions/toolkit/blob/5e5e1b7aacba68a53836a34db4a288c3c1c1585b/packages/core/src/command.ts#L87-L94 - */ - private const ESCAPED_PROPERTIES = [ - '%' => '%25', - "\r" => '%0D', - "\n" => '%0A', - ':' => '%3A', - ',' => '%2C', - ]; - - public function __construct(OutputInterface $output) - { - $this->output = $output; - } - - public static function isGithubActionEnvironment(): bool - { - return false !== getenv('GITHUB_ACTIONS'); - } - - /** - * Output an error using the Github annotations format. - * - * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-error-message - */ - public function error(string $message, string $file = null, int $line = null, int $col = null): void - { - $this->log('error', $message, $file, $line, $col); - } - - /** - * Output a warning using the Github annotations format. - * - * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message - */ - public function warning(string $message, string $file = null, int $line = null, int $col = null): void - { - $this->log('warning', $message, $file, $line, $col); - } - - /** - * Output a debug log using the Github annotations format. - * - * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-debug-message - */ - public function debug(string $message, string $file = null, int $line = null, int $col = null): void - { - $this->log('debug', $message, $file, $line, $col); - } - - private function log(string $type, string $message, string $file = null, int $line = null, int $col = null): void - { - // Some values must be encoded. - $message = strtr($message, self::ESCAPED_DATA); - - if (!$file) { - // No file provided, output the message solely: - $this->output->writeln(sprintf('::%s::%s', $type, $message)); - - return; - } - - $this->output->writeln(sprintf('::%s file=%s,line=%s,col=%s::%s', $type, strtr($file, self::ESCAPED_PROPERTIES), strtr($line ?? 1, self::ESCAPED_PROPERTIES), strtr($col ?? 0, self::ESCAPED_PROPERTIES), $message)); - } -} diff --git a/vendor/symfony/console/Color.php b/vendor/symfony/console/Color.php deleted file mode 100644 index 22a4ce9ff..000000000 --- a/vendor/symfony/console/Color.php +++ /dev/null @@ -1,180 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console; - -use Symfony\Component\Console\Exception\InvalidArgumentException; - -/** - * @author Fabien Potencier - */ -final class Color -{ - private const COLORS = [ - 'black' => 0, - 'red' => 1, - 'green' => 2, - 'yellow' => 3, - 'blue' => 4, - 'magenta' => 5, - 'cyan' => 6, - 'white' => 7, - 'default' => 9, - ]; - - private const BRIGHT_COLORS = [ - 'gray' => 0, - 'bright-red' => 1, - 'bright-green' => 2, - 'bright-yellow' => 3, - 'bright-blue' => 4, - 'bright-magenta' => 5, - 'bright-cyan' => 6, - 'bright-white' => 7, - ]; - - private const AVAILABLE_OPTIONS = [ - 'bold' => ['set' => 1, 'unset' => 22], - 'underscore' => ['set' => 4, 'unset' => 24], - 'blink' => ['set' => 5, 'unset' => 25], - 'reverse' => ['set' => 7, 'unset' => 27], - 'conceal' => ['set' => 8, 'unset' => 28], - ]; - - private $foreground; - private $background; - private $options = []; - - public function __construct(string $foreground = '', string $background = '', array $options = []) - { - $this->foreground = $this->parseColor($foreground); - $this->background = $this->parseColor($background, true); - - foreach ($options as $option) { - if (!isset(self::AVAILABLE_OPTIONS[$option])) { - throw new InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s).', $option, implode(', ', array_keys(self::AVAILABLE_OPTIONS)))); - } - - $this->options[$option] = self::AVAILABLE_OPTIONS[$option]; - } - } - - public function apply(string $text): string - { - return $this->set().$text.$this->unset(); - } - - public function set(): string - { - $setCodes = []; - if ('' !== $this->foreground) { - $setCodes[] = $this->foreground; - } - if ('' !== $this->background) { - $setCodes[] = $this->background; - } - foreach ($this->options as $option) { - $setCodes[] = $option['set']; - } - if (0 === \count($setCodes)) { - return ''; - } - - return sprintf("\033[%sm", implode(';', $setCodes)); - } - - public function unset(): string - { - $unsetCodes = []; - if ('' !== $this->foreground) { - $unsetCodes[] = 39; - } - if ('' !== $this->background) { - $unsetCodes[] = 49; - } - foreach ($this->options as $option) { - $unsetCodes[] = $option['unset']; - } - if (0 === \count($unsetCodes)) { - return ''; - } - - return sprintf("\033[%sm", implode(';', $unsetCodes)); - } - - private function parseColor(string $color, bool $background = false): string - { - if ('' === $color) { - return ''; - } - - if ('#' === $color[0]) { - $color = substr($color, 1); - - if (3 === \strlen($color)) { - $color = $color[0].$color[0].$color[1].$color[1].$color[2].$color[2]; - } - - if (6 !== \strlen($color)) { - throw new InvalidArgumentException(sprintf('Invalid "%s" color.', $color)); - } - - return ($background ? '4' : '3').$this->convertHexColorToAnsi(hexdec($color)); - } - - if (isset(self::COLORS[$color])) { - return ($background ? '4' : '3').self::COLORS[$color]; - } - - if (isset(self::BRIGHT_COLORS[$color])) { - return ($background ? '10' : '9').self::BRIGHT_COLORS[$color]; - } - - throw new InvalidArgumentException(sprintf('Invalid "%s" color; expected one of (%s).', $color, implode(', ', array_merge(array_keys(self::COLORS), array_keys(self::BRIGHT_COLORS))))); - } - - private function convertHexColorToAnsi(int $color): string - { - $r = ($color >> 16) & 255; - $g = ($color >> 8) & 255; - $b = $color & 255; - - // see https://github.com/termstandard/colors/ for more information about true color support - if ('truecolor' !== getenv('COLORTERM')) { - return (string) $this->degradeHexColorToAnsi($r, $g, $b); - } - - return sprintf('8;2;%d;%d;%d', $r, $g, $b); - } - - private function degradeHexColorToAnsi(int $r, int $g, int $b): int - { - if (0 === round($this->getSaturation($r, $g, $b) / 50)) { - return 0; - } - - return (round($b / 255) << 2) | (round($g / 255) << 1) | round($r / 255); - } - - private function getSaturation(int $r, int $g, int $b): int - { - $r = $r / 255; - $g = $g / 255; - $b = $b / 255; - $v = max($r, $g, $b); - - if (0 === $diff = $v - min($r, $g, $b)) { - return 0; - } - - return (int) $diff * 100 / $v; - } -} diff --git a/vendor/symfony/console/Command/Command.php b/vendor/symfony/console/Command/Command.php deleted file mode 100644 index e0593e17a..000000000 --- a/vendor/symfony/console/Command/Command.php +++ /dev/null @@ -1,710 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Command; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Attribute\AsCommand; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Exception\ExceptionInterface; -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\LogicException; -use Symfony\Component\Console\Helper\HelperSet; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Base class for all commands. - * - * @author Fabien Potencier - */ -class Command -{ - // see https://tldp.org/LDP/abs/html/exitcodes.html - public const SUCCESS = 0; - public const FAILURE = 1; - public const INVALID = 2; - - /** - * @var string|null The default command name - */ - protected static $defaultName; - - /** - * @var string|null The default command description - */ - protected static $defaultDescription; - - private $application; - private $name; - private $processTitle; - private $aliases = []; - private $definition; - private $hidden = false; - private $help = ''; - private $description = ''; - private $fullDefinition; - private $ignoreValidationErrors = false; - private $code; - private $synopsis = []; - private $usages = []; - private $helperSet; - - /** - * @return string|null - */ - public static function getDefaultName() - { - $class = static::class; - - if (\PHP_VERSION_ID >= 80000 && $attribute = (new \ReflectionClass($class))->getAttributes(AsCommand::class)) { - return $attribute[0]->newInstance()->name; - } - - $r = new \ReflectionProperty($class, 'defaultName'); - - return $class === $r->class ? static::$defaultName : null; - } - - public static function getDefaultDescription(): ?string - { - $class = static::class; - - if (\PHP_VERSION_ID >= 80000 && $attribute = (new \ReflectionClass($class))->getAttributes(AsCommand::class)) { - return $attribute[0]->newInstance()->description; - } - - $r = new \ReflectionProperty($class, 'defaultDescription'); - - return $class === $r->class ? static::$defaultDescription : null; - } - - /** - * @param string|null $name The name of the command; passing null means it must be set in configure() - * - * @throws LogicException When the command name is empty - */ - public function __construct(string $name = null) - { - $this->definition = new InputDefinition(); - - if (null === $name && null !== $name = static::getDefaultName()) { - $aliases = explode('|', $name); - - if ('' === $name = array_shift($aliases)) { - $this->setHidden(true); - $name = array_shift($aliases); - } - - $this->setAliases($aliases); - } - - if (null !== $name) { - $this->setName($name); - } - - if ('' === $this->description) { - $this->setDescription(static::getDefaultDescription() ?? ''); - } - - $this->configure(); - } - - /** - * Ignores validation errors. - * - * This is mainly useful for the help command. - */ - public function ignoreValidationErrors() - { - $this->ignoreValidationErrors = true; - } - - public function setApplication(Application $application = null) - { - $this->application = $application; - if ($application) { - $this->setHelperSet($application->getHelperSet()); - } else { - $this->helperSet = null; - } - - $this->fullDefinition = null; - } - - public function setHelperSet(HelperSet $helperSet) - { - $this->helperSet = $helperSet; - } - - /** - * Gets the helper set. - * - * @return HelperSet|null - */ - public function getHelperSet() - { - return $this->helperSet; - } - - /** - * Gets the application instance for this command. - * - * @return Application|null - */ - public function getApplication() - { - return $this->application; - } - - /** - * Checks whether the command is enabled or not in the current environment. - * - * Override this to check for x or y and return false if the command cannot - * run properly under the current conditions. - * - * @return bool - */ - public function isEnabled() - { - return true; - } - - /** - * Configures the current command. - */ - protected function configure() - { - } - - /** - * Executes the current command. - * - * This method is not abstract because you can use this class - * as a concrete class. In this case, instead of defining the - * execute() method, you set the code to execute by passing - * a Closure to the setCode() method. - * - * @return int 0 if everything went fine, or an exit code - * - * @throws LogicException When this abstract method is not implemented - * - * @see setCode() - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - throw new LogicException('You must override the execute() method in the concrete command class.'); - } - - /** - * Interacts with the user. - * - * This method is executed before the InputDefinition is validated. - * This means that this is the only place where the command can - * interactively ask for values of missing required arguments. - */ - protected function interact(InputInterface $input, OutputInterface $output) - { - } - - /** - * Initializes the command after the input has been bound and before the input - * is validated. - * - * This is mainly useful when a lot of commands extends one main command - * where some things need to be initialized based on the input arguments and options. - * - * @see InputInterface::bind() - * @see InputInterface::validate() - */ - protected function initialize(InputInterface $input, OutputInterface $output) - { - } - - /** - * Runs the command. - * - * The code to execute is either defined directly with the - * setCode() method or by overriding the execute() method - * in a sub-class. - * - * @return int The command exit code - * - * @throws ExceptionInterface When input binding fails. Bypass this by calling {@link ignoreValidationErrors()}. - * - * @see setCode() - * @see execute() - */ - public function run(InputInterface $input, OutputInterface $output) - { - // add the application arguments and options - $this->mergeApplicationDefinition(); - - // bind the input against the command specific arguments/options - try { - $input->bind($this->getDefinition()); - } catch (ExceptionInterface $e) { - if (!$this->ignoreValidationErrors) { - throw $e; - } - } - - $this->initialize($input, $output); - - if (null !== $this->processTitle) { - if (\function_exists('cli_set_process_title')) { - if (!@cli_set_process_title($this->processTitle)) { - if ('Darwin' === \PHP_OS) { - $output->writeln('Running "cli_set_process_title" as an unprivileged user is not supported on MacOS.', OutputInterface::VERBOSITY_VERY_VERBOSE); - } else { - cli_set_process_title($this->processTitle); - } - } - } elseif (\function_exists('setproctitle')) { - setproctitle($this->processTitle); - } elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) { - $output->writeln('Install the proctitle PECL to be able to change the process title.'); - } - } - - if ($input->isInteractive()) { - $this->interact($input, $output); - } - - // The command name argument is often omitted when a command is executed directly with its run() method. - // It would fail the validation if we didn't make sure the command argument is present, - // since it's required by the application. - if ($input->hasArgument('command') && null === $input->getArgument('command')) { - $input->setArgument('command', $this->getName()); - } - - $input->validate(); - - if ($this->code) { - $statusCode = ($this->code)($input, $output); - } else { - $statusCode = $this->execute($input, $output); - - if (!\is_int($statusCode)) { - throw new \TypeError(sprintf('Return value of "%s::execute()" must be of the type int, "%s" returned.', static::class, get_debug_type($statusCode))); - } - } - - return is_numeric($statusCode) ? (int) $statusCode : 0; - } - - /** - * Adds suggestions to $suggestions for the current completion input (e.g. option or argument). - */ - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - } - - /** - * Sets the code to execute when running this command. - * - * If this method is used, it overrides the code defined - * in the execute() method. - * - * @param callable $code A callable(InputInterface $input, OutputInterface $output) - * - * @return $this - * - * @throws InvalidArgumentException - * - * @see execute() - */ - public function setCode(callable $code) - { - if ($code instanceof \Closure) { - $r = new \ReflectionFunction($code); - if (null === $r->getClosureThis()) { - set_error_handler(static function () {}); - try { - if ($c = \Closure::bind($code, $this)) { - $code = $c; - } - } finally { - restore_error_handler(); - } - } - } - - $this->code = $code; - - return $this; - } - - /** - * Merges the application definition with the command definition. - * - * This method is not part of public API and should not be used directly. - * - * @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments - * - * @internal - */ - public function mergeApplicationDefinition(bool $mergeArgs = true) - { - if (null === $this->application) { - return; - } - - $this->fullDefinition = new InputDefinition(); - $this->fullDefinition->setOptions($this->definition->getOptions()); - $this->fullDefinition->addOptions($this->application->getDefinition()->getOptions()); - - if ($mergeArgs) { - $this->fullDefinition->setArguments($this->application->getDefinition()->getArguments()); - $this->fullDefinition->addArguments($this->definition->getArguments()); - } else { - $this->fullDefinition->setArguments($this->definition->getArguments()); - } - } - - /** - * Sets an array of argument and option instances. - * - * @param array|InputDefinition $definition An array of argument and option instances or a definition instance - * - * @return $this - */ - public function setDefinition($definition) - { - if ($definition instanceof InputDefinition) { - $this->definition = $definition; - } else { - $this->definition->setDefinition($definition); - } - - $this->fullDefinition = null; - - return $this; - } - - /** - * Gets the InputDefinition attached to this Command. - * - * @return InputDefinition - */ - public function getDefinition() - { - return $this->fullDefinition ?? $this->getNativeDefinition(); - } - - /** - * Gets the InputDefinition to be used to create representations of this Command. - * - * Can be overridden to provide the original command representation when it would otherwise - * be changed by merging with the application InputDefinition. - * - * This method is not part of public API and should not be used directly. - * - * @return InputDefinition - */ - public function getNativeDefinition() - { - if (null === $this->definition) { - throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', static::class)); - } - - return $this->definition; - } - - /** - * Adds an argument. - * - * @param int|null $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL - * @param mixed $default The default value (for InputArgument::OPTIONAL mode only) - * - * @throws InvalidArgumentException When argument mode is not valid - * - * @return $this - */ - public function addArgument(string $name, int $mode = null, string $description = '', $default = null) - { - $this->definition->addArgument(new InputArgument($name, $mode, $description, $default)); - if (null !== $this->fullDefinition) { - $this->fullDefinition->addArgument(new InputArgument($name, $mode, $description, $default)); - } - - return $this; - } - - /** - * Adds an option. - * - * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts - * @param int|null $mode The option mode: One of the InputOption::VALUE_* constants - * @param mixed $default The default value (must be null for InputOption::VALUE_NONE) - * - * @throws InvalidArgumentException If option mode is invalid or incompatible - * - * @return $this - */ - public function addOption(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null) - { - $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default)); - if (null !== $this->fullDefinition) { - $this->fullDefinition->addOption(new InputOption($name, $shortcut, $mode, $description, $default)); - } - - return $this; - } - - /** - * Sets the name of the command. - * - * This method can set both the namespace and the name if - * you separate them by a colon (:) - * - * $command->setName('foo:bar'); - * - * @return $this - * - * @throws InvalidArgumentException When the name is invalid - */ - public function setName(string $name) - { - $this->validateName($name); - - $this->name = $name; - - return $this; - } - - /** - * Sets the process title of the command. - * - * This feature should be used only when creating a long process command, - * like a daemon. - * - * @return $this - */ - public function setProcessTitle(string $title) - { - $this->processTitle = $title; - - return $this; - } - - /** - * Returns the command name. - * - * @return string|null - */ - public function getName() - { - return $this->name; - } - - /** - * @param bool $hidden Whether or not the command should be hidden from the list of commands - * The default value will be true in Symfony 6.0 - * - * @return $this - * - * @final since Symfony 5.1 - */ - public function setHidden(bool $hidden /* = true */) - { - $this->hidden = $hidden; - - return $this; - } - - /** - * @return bool whether the command should be publicly shown or not - */ - public function isHidden() - { - return $this->hidden; - } - - /** - * Sets the description for the command. - * - * @return $this - */ - public function setDescription(string $description) - { - $this->description = $description; - - return $this; - } - - /** - * Returns the description for the command. - * - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * Sets the help for the command. - * - * @return $this - */ - public function setHelp(string $help) - { - $this->help = $help; - - return $this; - } - - /** - * Returns the help for the command. - * - * @return string - */ - public function getHelp() - { - return $this->help; - } - - /** - * Returns the processed help for the command replacing the %command.name% and - * %command.full_name% patterns with the real values dynamically. - * - * @return string - */ - public function getProcessedHelp() - { - $name = $this->name; - $isSingleCommand = $this->application && $this->application->isSingleCommand(); - - $placeholders = [ - '%command.name%', - '%command.full_name%', - ]; - $replacements = [ - $name, - $isSingleCommand ? $_SERVER['PHP_SELF'] : $_SERVER['PHP_SELF'].' '.$name, - ]; - - return str_replace($placeholders, $replacements, $this->getHelp() ?: $this->getDescription()); - } - - /** - * Sets the aliases for the command. - * - * @param string[] $aliases An array of aliases for the command - * - * @return $this - * - * @throws InvalidArgumentException When an alias is invalid - */ - public function setAliases(iterable $aliases) - { - $list = []; - - foreach ($aliases as $alias) { - $this->validateName($alias); - $list[] = $alias; - } - - $this->aliases = \is_array($aliases) ? $aliases : $list; - - return $this; - } - - /** - * Returns the aliases for the command. - * - * @return array - */ - public function getAliases() - { - return $this->aliases; - } - - /** - * Returns the synopsis for the command. - * - * @param bool $short Whether to show the short version of the synopsis (with options folded) or not - * - * @return string - */ - public function getSynopsis(bool $short = false) - { - $key = $short ? 'short' : 'long'; - - if (!isset($this->synopsis[$key])) { - $this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short))); - } - - return $this->synopsis[$key]; - } - - /** - * Add a command usage example, it'll be prefixed with the command name. - * - * @return $this - */ - public function addUsage(string $usage) - { - if (!str_starts_with($usage, $this->name)) { - $usage = sprintf('%s %s', $this->name, $usage); - } - - $this->usages[] = $usage; - - return $this; - } - - /** - * Returns alternative usages of the command. - * - * @return array - */ - public function getUsages() - { - return $this->usages; - } - - /** - * Gets a helper instance by name. - * - * @return mixed - * - * @throws LogicException if no HelperSet is defined - * @throws InvalidArgumentException if the helper is not defined - */ - public function getHelper(string $name) - { - if (null === $this->helperSet) { - throw new LogicException(sprintf('Cannot retrieve helper "%s" because there is no HelperSet defined. Did you forget to add your command to the application or to set the application on the command using the setApplication() method? You can also set the HelperSet directly using the setHelperSet() method.', $name)); - } - - return $this->helperSet->get($name); - } - - /** - * Validates a command name. - * - * It must be non-empty and parts can optionally be separated by ":". - * - * @throws InvalidArgumentException When the name is invalid - */ - private function validateName(string $name) - { - if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) { - throw new InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name)); - } - } -} diff --git a/vendor/symfony/console/Command/CompleteCommand.php b/vendor/symfony/console/Command/CompleteCommand.php deleted file mode 100644 index 11ada4e44..000000000 --- a/vendor/symfony/console/Command/CompleteCommand.php +++ /dev/null @@ -1,205 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Command; - -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Completion\Output\BashCompletionOutput; -use Symfony\Component\Console\Completion\Output\CompletionOutputInterface; -use Symfony\Component\Console\Exception\CommandNotFoundException; -use Symfony\Component\Console\Exception\ExceptionInterface; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Responsible for providing the values to the shell completion. - * - * @author Wouter de Jong - */ -final class CompleteCommand extends Command -{ - protected static $defaultName = '|_complete'; - protected static $defaultDescription = 'Internal command to provide shell completion suggestions'; - - private $completionOutputs; - - private $isDebug = false; - - /** - * @param array> $completionOutputs A list of additional completion outputs, with shell name as key and FQCN as value - */ - public function __construct(array $completionOutputs = []) - { - // must be set before the parent constructor, as the property value is used in configure() - $this->completionOutputs = $completionOutputs + ['bash' => BashCompletionOutput::class]; - - parent::__construct(); - } - - protected function configure(): void - { - $this - ->addOption('shell', 's', InputOption::VALUE_REQUIRED, 'The shell type ("'.implode('", "', array_keys($this->completionOutputs)).'")') - ->addOption('input', 'i', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'An array of input tokens (e.g. COMP_WORDS or argv)') - ->addOption('current', 'c', InputOption::VALUE_REQUIRED, 'The index of the "input" array that the cursor is in (e.g. COMP_CWORD)') - ->addOption('symfony', 'S', InputOption::VALUE_REQUIRED, 'The version of the completion script') - ; - } - - protected function initialize(InputInterface $input, OutputInterface $output) - { - $this->isDebug = filter_var(getenv('SYMFONY_COMPLETION_DEBUG'), \FILTER_VALIDATE_BOOLEAN); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - try { - // uncomment when a bugfix or BC break has been introduced in the shell completion scripts - // $version = $input->getOption('symfony'); - // if ($version && version_compare($version, 'x.y', '>=')) { - // $message = sprintf('Completion script version is not supported ("%s" given, ">=x.y" required).', $version); - // $this->log($message); - - // $output->writeln($message.' Install the Symfony completion script again by using the "completion" command.'); - - // return 126; - // } - - $shell = $input->getOption('shell'); - if (!$shell) { - throw new \RuntimeException('The "--shell" option must be set.'); - } - - if (!$completionOutput = $this->completionOutputs[$shell] ?? false) { - throw new \RuntimeException(sprintf('Shell completion is not supported for your shell: "%s" (supported: "%s").', $shell, implode('", "', array_keys($this->completionOutputs)))); - } - - $completionInput = $this->createCompletionInput($input); - $suggestions = new CompletionSuggestions(); - - $this->log([ - '', - ''.date('Y-m-d H:i:s').'', - 'Input: ("|" indicates the cursor position)', - ' '.(string) $completionInput, - 'Command:', - ' '.(string) implode(' ', $_SERVER['argv']), - 'Messages:', - ]); - - $command = $this->findCommand($completionInput, $output); - if (null === $command) { - $this->log(' No command found, completing using the Application class.'); - - $this->getApplication()->complete($completionInput, $suggestions); - } elseif ( - $completionInput->mustSuggestArgumentValuesFor('command') - && $command->getName() !== $completionInput->getCompletionValue() - && !\in_array($completionInput->getCompletionValue(), $command->getAliases(), true) - ) { - $this->log(' No command found, completing using the Application class.'); - - // expand shortcut names ("cache:cl") into their full name ("cache:clear") - $suggestions->suggestValues(array_filter(array_merge([$command->getName()], $command->getAliases()))); - } else { - $command->mergeApplicationDefinition(); - $completionInput->bind($command->getDefinition()); - - if (CompletionInput::TYPE_OPTION_NAME === $completionInput->getCompletionType()) { - $this->log(' Completing option names for the '.\get_class($command instanceof LazyCommand ? $command->getCommand() : $command).' command.'); - - $suggestions->suggestOptions($command->getDefinition()->getOptions()); - } else { - $this->log([ - ' Completing using the '.\get_class($command instanceof LazyCommand ? $command->getCommand() : $command).' class.', - ' Completing '.$completionInput->getCompletionType().' for '.$completionInput->getCompletionName().'', - ]); - if (null !== $compval = $completionInput->getCompletionValue()) { - $this->log(' Current value: '.$compval.''); - } - - $command->complete($completionInput, $suggestions); - } - } - - /** @var CompletionOutputInterface $completionOutput */ - $completionOutput = new $completionOutput(); - - $this->log('Suggestions:'); - if ($options = $suggestions->getOptionSuggestions()) { - $this->log(' --'.implode(' --', array_map(function ($o) { return $o->getName(); }, $options))); - } elseif ($values = $suggestions->getValueSuggestions()) { - $this->log(' '.implode(' ', $values)); - } else { - $this->log(' No suggestions were provided'); - } - - $completionOutput->write($suggestions, $output); - } catch (\Throwable $e) { - $this->log([ - 'Error!', - (string) $e, - ]); - - if ($output->isDebug()) { - throw $e; - } - - return self::FAILURE; - } - - return self::SUCCESS; - } - - private function createCompletionInput(InputInterface $input): CompletionInput - { - $currentIndex = $input->getOption('current'); - if (!$currentIndex || !ctype_digit($currentIndex)) { - throw new \RuntimeException('The "--current" option must be set and it must be an integer.'); - } - - $completionInput = CompletionInput::fromTokens($input->getOption('input'), (int) $currentIndex); - - try { - $completionInput->bind($this->getApplication()->getDefinition()); - } catch (ExceptionInterface $e) { - } - - return $completionInput; - } - - private function findCommand(CompletionInput $completionInput, OutputInterface $output): ?Command - { - try { - $inputName = $completionInput->getFirstArgument(); - if (null === $inputName) { - return null; - } - - return $this->getApplication()->find($inputName); - } catch (CommandNotFoundException $e) { - } - - return null; - } - - private function log($messages): void - { - if (!$this->isDebug) { - return; - } - - $commandName = basename($_SERVER['argv'][0]); - file_put_contents(sys_get_temp_dir().'/sf_'.$commandName.'.log', implode(\PHP_EOL, (array) $messages).\PHP_EOL, \FILE_APPEND); - } -} diff --git a/vendor/symfony/console/Command/DumpCompletionCommand.php b/vendor/symfony/console/Command/DumpCompletionCommand.php deleted file mode 100644 index 518d606a0..000000000 --- a/vendor/symfony/console/Command/DumpCompletionCommand.php +++ /dev/null @@ -1,139 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Command; - -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\ConsoleOutputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Process\Process; - -/** - * Dumps the completion script for the current shell. - * - * @author Wouter de Jong - */ -final class DumpCompletionCommand extends Command -{ - protected static $defaultName = 'completion'; - protected static $defaultDescription = 'Dump the shell completion script'; - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - if ($input->mustSuggestArgumentValuesFor('shell')) { - $suggestions->suggestValues($this->getSupportedShells()); - } - } - - protected function configure() - { - $fullCommand = $_SERVER['PHP_SELF']; - $commandName = basename($fullCommand); - $fullCommand = @realpath($fullCommand) ?: $fullCommand; - - $this - ->setHelp(<<%command.name% command dumps the shell completion script required -to use shell autocompletion (currently only bash completion is supported). - -Static installation -------------------- - -Dump the script to a global completion file and restart your shell: - - %command.full_name% bash | sudo tee /etc/bash_completion.d/{$commandName} - -Or dump the script to a local file and source it: - - %command.full_name% bash > completion.sh - - # source the file whenever you use the project - source completion.sh - - # or add this line at the end of your "~/.bashrc" file: - source /path/to/completion.sh - -Dynamic installation --------------------- - -Add this to the end of your shell configuration file (e.g. "~/.bashrc"): - - eval "$({$fullCommand} completion bash)" -EOH - ) - ->addArgument('shell', InputArgument::OPTIONAL, 'The shell type (e.g. "bash"), the value of the "$SHELL" env var will be used if this is not given') - ->addOption('debug', null, InputOption::VALUE_NONE, 'Tail the completion debug log') - ; - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - $commandName = basename($_SERVER['argv'][0]); - - if ($input->getOption('debug')) { - $this->tailDebugLog($commandName, $output); - - return self::SUCCESS; - } - - $shell = $input->getArgument('shell') ?? self::guessShell(); - $completionFile = __DIR__.'/../Resources/completion.'.$shell; - if (!file_exists($completionFile)) { - $supportedShells = $this->getSupportedShells(); - - if ($output instanceof ConsoleOutputInterface) { - $output = $output->getErrorOutput(); - } - if ($shell) { - $output->writeln(sprintf('Detected shell "%s", which is not supported by Symfony shell completion (supported shells: "%s").', $shell, implode('", "', $supportedShells))); - } else { - $output->writeln(sprintf('Shell not detected, Symfony shell completion only supports "%s").', implode('", "', $supportedShells))); - } - - return self::INVALID; - } - - $output->write(str_replace(['{{ COMMAND_NAME }}', '{{ VERSION }}'], [$commandName, $this->getApplication()->getVersion()], file_get_contents($completionFile))); - - return self::SUCCESS; - } - - private static function guessShell(): string - { - return basename($_SERVER['SHELL'] ?? ''); - } - - private function tailDebugLog(string $commandName, OutputInterface $output): void - { - $debugFile = sys_get_temp_dir().'/sf_'.$commandName.'.log'; - if (!file_exists($debugFile)) { - touch($debugFile); - } - $process = new Process(['tail', '-f', $debugFile], null, null, null, 0); - $process->run(function (string $type, string $line) use ($output): void { - $output->write($line); - }); - } - - /** - * @return string[] - */ - private function getSupportedShells(): array - { - return array_map(function ($f) { - return pathinfo($f, \PATHINFO_EXTENSION); - }, glob(__DIR__.'/../Resources/completion.*')); - } -} diff --git a/vendor/symfony/console/Command/HelpCommand.php b/vendor/symfony/console/Command/HelpCommand.php deleted file mode 100644 index c66ef463e..000000000 --- a/vendor/symfony/console/Command/HelpCommand.php +++ /dev/null @@ -1,101 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Command; - -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Descriptor\ApplicationDescription; -use Symfony\Component\Console\Helper\DescriptorHelper; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * HelpCommand displays the help for a given command. - * - * @author Fabien Potencier - */ -class HelpCommand extends Command -{ - private $command; - - /** - * {@inheritdoc} - */ - protected function configure() - { - $this->ignoreValidationErrors(); - - $this - ->setName('help') - ->setDefinition([ - new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'), - new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'), - new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'), - ]) - ->setDescription('Display help for a command') - ->setHelp(<<<'EOF' -The %command.name% command displays help for a given command: - - %command.full_name% list - -You can also output the help in other formats by using the --format option: - - %command.full_name% --format=xml list - -To display the list of available commands, please use the list command. -EOF - ) - ; - } - - public function setCommand(Command $command) - { - $this->command = $command; - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - if (null === $this->command) { - $this->command = $this->getApplication()->find($input->getArgument('command_name')); - } - - $helper = new DescriptorHelper(); - $helper->describe($output, $this->command, [ - 'format' => $input->getOption('format'), - 'raw_text' => $input->getOption('raw'), - ]); - - $this->command = null; - - return 0; - } - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - if ($input->mustSuggestArgumentValuesFor('command_name')) { - $descriptor = new ApplicationDescription($this->getApplication()); - $suggestions->suggestValues(array_keys($descriptor->getCommands())); - - return; - } - - if ($input->mustSuggestOptionValuesFor('format')) { - $helper = new DescriptorHelper(); - $suggestions->suggestValues($helper->getFormats()); - } - } -} diff --git a/vendor/symfony/console/Command/LazyCommand.php b/vendor/symfony/console/Command/LazyCommand.php deleted file mode 100644 index e576ad03f..000000000 --- a/vendor/symfony/console/Command/LazyCommand.php +++ /dev/null @@ -1,218 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Command; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Helper\HelperSet; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * @author Nicolas Grekas - */ -final class LazyCommand extends Command -{ - private $command; - private $isEnabled; - - public function __construct(string $name, array $aliases, string $description, bool $isHidden, \Closure $commandFactory, ?bool $isEnabled = true) - { - $this->setName($name) - ->setAliases($aliases) - ->setHidden($isHidden) - ->setDescription($description); - - $this->command = $commandFactory; - $this->isEnabled = $isEnabled; - } - - public function ignoreValidationErrors(): void - { - $this->getCommand()->ignoreValidationErrors(); - } - - public function setApplication(Application $application = null): void - { - if ($this->command instanceof parent) { - $this->command->setApplication($application); - } - - parent::setApplication($application); - } - - public function setHelperSet(HelperSet $helperSet): void - { - if ($this->command instanceof parent) { - $this->command->setHelperSet($helperSet); - } - - parent::setHelperSet($helperSet); - } - - public function isEnabled(): bool - { - return $this->isEnabled ?? $this->getCommand()->isEnabled(); - } - - public function run(InputInterface $input, OutputInterface $output): int - { - return $this->getCommand()->run($input, $output); - } - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - $this->getCommand()->complete($input, $suggestions); - } - - /** - * @return $this - */ - public function setCode(callable $code): self - { - $this->getCommand()->setCode($code); - - return $this; - } - - /** - * @internal - */ - public function mergeApplicationDefinition(bool $mergeArgs = true): void - { - $this->getCommand()->mergeApplicationDefinition($mergeArgs); - } - - /** - * @return $this - */ - public function setDefinition($definition): self - { - $this->getCommand()->setDefinition($definition); - - return $this; - } - - public function getDefinition(): InputDefinition - { - return $this->getCommand()->getDefinition(); - } - - public function getNativeDefinition(): InputDefinition - { - return $this->getCommand()->getNativeDefinition(); - } - - /** - * @return $this - */ - public function addArgument(string $name, int $mode = null, string $description = '', $default = null): self - { - $this->getCommand()->addArgument($name, $mode, $description, $default); - - return $this; - } - - /** - * @return $this - */ - public function addOption(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null): self - { - $this->getCommand()->addOption($name, $shortcut, $mode, $description, $default); - - return $this; - } - - /** - * @return $this - */ - public function setProcessTitle(string $title): self - { - $this->getCommand()->setProcessTitle($title); - - return $this; - } - - /** - * @return $this - */ - public function setHelp(string $help): self - { - $this->getCommand()->setHelp($help); - - return $this; - } - - public function getHelp(): string - { - return $this->getCommand()->getHelp(); - } - - public function getProcessedHelp(): string - { - return $this->getCommand()->getProcessedHelp(); - } - - public function getSynopsis(bool $short = false): string - { - return $this->getCommand()->getSynopsis($short); - } - - /** - * @return $this - */ - public function addUsage(string $usage): self - { - $this->getCommand()->addUsage($usage); - - return $this; - } - - public function getUsages(): array - { - return $this->getCommand()->getUsages(); - } - - /** - * @return mixed - */ - public function getHelper(string $name) - { - return $this->getCommand()->getHelper($name); - } - - public function getCommand(): parent - { - if (!$this->command instanceof \Closure) { - return $this->command; - } - - $command = $this->command = ($this->command)(); - $command->setApplication($this->getApplication()); - - if (null !== $this->getHelperSet()) { - $command->setHelperSet($this->getHelperSet()); - } - - $command->setName($this->getName()) - ->setAliases($this->getAliases()) - ->setHidden($this->isHidden()) - ->setDescription($this->getDescription()); - - // Will throw if the command is not correctly initialized. - $command->getDefinition(); - - return $command; - } -} diff --git a/vendor/symfony/console/Command/ListCommand.php b/vendor/symfony/console/Command/ListCommand.php deleted file mode 100644 index f04a4ef67..000000000 --- a/vendor/symfony/console/Command/ListCommand.php +++ /dev/null @@ -1,95 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Command; - -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Descriptor\ApplicationDescription; -use Symfony\Component\Console\Helper\DescriptorHelper; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * ListCommand displays the list of all available commands for the application. - * - * @author Fabien Potencier - */ -class ListCommand extends Command -{ - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setName('list') - ->setDefinition([ - new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'), - new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'), - new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'), - new InputOption('short', null, InputOption::VALUE_NONE, 'To skip describing commands\' arguments'), - ]) - ->setDescription('List commands') - ->setHelp(<<<'EOF' -The %command.name% command lists all commands: - - %command.full_name% - -You can also display the commands for a specific namespace: - - %command.full_name% test - -You can also output the information in other formats by using the --format option: - - %command.full_name% --format=xml - -It's also possible to get raw list of commands (useful for embedding command runner): - - %command.full_name% --raw -EOF - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $helper = new DescriptorHelper(); - $helper->describe($output, $this->getApplication(), [ - 'format' => $input->getOption('format'), - 'raw_text' => $input->getOption('raw'), - 'namespace' => $input->getArgument('namespace'), - 'short' => $input->getOption('short'), - ]); - - return 0; - } - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - if ($input->mustSuggestArgumentValuesFor('namespace')) { - $descriptor = new ApplicationDescription($this->getApplication()); - $suggestions->suggestValues(array_keys($descriptor->getNamespaces())); - - return; - } - - if ($input->mustSuggestOptionValuesFor('format')) { - $helper = new DescriptorHelper(); - $suggestions->suggestValues($helper->getFormats()); - } - } -} diff --git a/vendor/symfony/console/Command/LockableTrait.php b/vendor/symfony/console/Command/LockableTrait.php deleted file mode 100644 index b1856dca7..000000000 --- a/vendor/symfony/console/Command/LockableTrait.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Command; - -use Symfony\Component\Console\Exception\LogicException; -use Symfony\Component\Lock\LockFactory; -use Symfony\Component\Lock\LockInterface; -use Symfony\Component\Lock\Store\FlockStore; -use Symfony\Component\Lock\Store\SemaphoreStore; - -/** - * Basic lock feature for commands. - * - * @author Geoffrey Brier - */ -trait LockableTrait -{ - /** @var LockInterface|null */ - private $lock; - - /** - * Locks a command. - */ - private function lock(string $name = null, bool $blocking = false): bool - { - if (!class_exists(SemaphoreStore::class)) { - throw new LogicException('To enable the locking feature you must install the symfony/lock component.'); - } - - if (null !== $this->lock) { - throw new LogicException('A lock is already in place.'); - } - - if (SemaphoreStore::isSupported()) { - $store = new SemaphoreStore(); - } else { - $store = new FlockStore(); - } - - $this->lock = (new LockFactory($store))->createLock($name ?: $this->getName()); - if (!$this->lock->acquire($blocking)) { - $this->lock = null; - - return false; - } - - return true; - } - - /** - * Releases the command lock if there is one. - */ - private function release() - { - if ($this->lock) { - $this->lock->release(); - $this->lock = null; - } - } -} diff --git a/vendor/symfony/console/Command/SignalableCommandInterface.php b/vendor/symfony/console/Command/SignalableCommandInterface.php deleted file mode 100644 index d439728b6..000000000 --- a/vendor/symfony/console/Command/SignalableCommandInterface.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Command; - -/** - * Interface for command reacting to signal. - * - * @author Grégoire Pineau - */ -interface SignalableCommandInterface -{ - /** - * Returns the list of signals to subscribe. - */ - public function getSubscribedSignals(): array; - - /** - * The method will be called when the application is signaled. - */ - public function handleSignal(int $signal): void; -} diff --git a/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php b/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php deleted file mode 100644 index 0adaf886f..000000000 --- a/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\CommandLoader; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Exception\CommandNotFoundException; - -/** - * @author Robin Chalas - */ -interface CommandLoaderInterface -{ - /** - * Loads a command. - * - * @return Command - * - * @throws CommandNotFoundException - */ - public function get(string $name); - - /** - * Checks if a command exists. - * - * @return bool - */ - public function has(string $name); - - /** - * @return string[] - */ - public function getNames(); -} diff --git a/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php b/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php deleted file mode 100644 index ddccb3d45..000000000 --- a/vendor/symfony/console/CommandLoader/ContainerCommandLoader.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. - */ - -namespace Symfony\Component\Console\CommandLoader; - -use Psr\Container\ContainerInterface; -use Symfony\Component\Console\Exception\CommandNotFoundException; - -/** - * Loads commands from a PSR-11 container. - * - * @author Robin Chalas - */ -class ContainerCommandLoader implements CommandLoaderInterface -{ - private $container; - private $commandMap; - - /** - * @param array $commandMap An array with command names as keys and service ids as values - */ - public function __construct(ContainerInterface $container, array $commandMap) - { - $this->container = $container; - $this->commandMap = $commandMap; - } - - /** - * {@inheritdoc} - */ - public function get(string $name) - { - if (!$this->has($name)) { - throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name)); - } - - return $this->container->get($this->commandMap[$name]); - } - - /** - * {@inheritdoc} - */ - public function has(string $name) - { - return isset($this->commandMap[$name]) && $this->container->has($this->commandMap[$name]); - } - - /** - * {@inheritdoc} - */ - public function getNames() - { - return array_keys($this->commandMap); - } -} diff --git a/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php b/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php deleted file mode 100644 index 7e2db3464..000000000 --- a/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php +++ /dev/null @@ -1,62 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\CommandLoader; - -use Symfony\Component\Console\Exception\CommandNotFoundException; - -/** - * A simple command loader using factories to instantiate commands lazily. - * - * @author Maxime Steinhausser - */ -class FactoryCommandLoader implements CommandLoaderInterface -{ - private $factories; - - /** - * @param callable[] $factories Indexed by command names - */ - public function __construct(array $factories) - { - $this->factories = $factories; - } - - /** - * {@inheritdoc} - */ - public function has(string $name) - { - return isset($this->factories[$name]); - } - - /** - * {@inheritdoc} - */ - public function get(string $name) - { - if (!isset($this->factories[$name])) { - throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name)); - } - - $factory = $this->factories[$name]; - - return $factory(); - } - - /** - * {@inheritdoc} - */ - public function getNames() - { - return array_keys($this->factories); - } -} diff --git a/vendor/symfony/console/Completion/CompletionInput.php b/vendor/symfony/console/Completion/CompletionInput.php deleted file mode 100644 index 368b94507..000000000 --- a/vendor/symfony/console/Completion/CompletionInput.php +++ /dev/null @@ -1,249 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Completion; - -use Symfony\Component\Console\Exception\RuntimeException; -use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; - -/** - * An input specialized for shell completion. - * - * This input allows unfinished option names or values and exposes what kind of - * completion is expected. - * - * @author Wouter de Jong - */ -final class CompletionInput extends ArgvInput -{ - public const TYPE_ARGUMENT_VALUE = 'argument_value'; - public const TYPE_OPTION_VALUE = 'option_value'; - public const TYPE_OPTION_NAME = 'option_name'; - public const TYPE_NONE = 'none'; - - private $tokens; - private $currentIndex; - private $completionType; - private $completionName = null; - private $completionValue = ''; - - /** - * Converts a terminal string into tokens. - * - * This is required for shell completions without COMP_WORDS support. - */ - public static function fromString(string $inputStr, int $currentIndex): self - { - preg_match_all('/(?<=^|\s)([\'"]?)(.+?)(?tokens = $tokens; - $input->currentIndex = $currentIndex; - - return $input; - } - - /** - * {@inheritdoc} - */ - public function bind(InputDefinition $definition): void - { - parent::bind($definition); - - $relevantToken = $this->getRelevantToken(); - if ('-' === $relevantToken[0]) { - // the current token is an input option: complete either option name or option value - [$optionToken, $optionValue] = explode('=', $relevantToken, 2) + ['', '']; - - $option = $this->getOptionFromToken($optionToken); - if (null === $option && !$this->isCursorFree()) { - $this->completionType = self::TYPE_OPTION_NAME; - $this->completionValue = $relevantToken; - - return; - } - - if (null !== $option && $option->acceptValue()) { - $this->completionType = self::TYPE_OPTION_VALUE; - $this->completionName = $option->getName(); - $this->completionValue = $optionValue ?: (!str_starts_with($optionToken, '--') ? substr($optionToken, 2) : ''); - - return; - } - } - - $previousToken = $this->tokens[$this->currentIndex - 1]; - if ('-' === $previousToken[0] && '' !== trim($previousToken, '-')) { - // check if previous option accepted a value - $previousOption = $this->getOptionFromToken($previousToken); - if (null !== $previousOption && $previousOption->acceptValue()) { - $this->completionType = self::TYPE_OPTION_VALUE; - $this->completionName = $previousOption->getName(); - $this->completionValue = $relevantToken; - - return; - } - } - - // complete argument value - $this->completionType = self::TYPE_ARGUMENT_VALUE; - - foreach ($this->definition->getArguments() as $argumentName => $argument) { - if (!isset($this->arguments[$argumentName])) { - break; - } - - $argumentValue = $this->arguments[$argumentName]; - $this->completionName = $argumentName; - if (\is_array($argumentValue)) { - $this->completionValue = $argumentValue ? $argumentValue[array_key_last($argumentValue)] : null; - } else { - $this->completionValue = $argumentValue; - } - } - - if ($this->currentIndex >= \count($this->tokens)) { - if (!isset($this->arguments[$argumentName]) || $this->definition->getArgument($argumentName)->isArray()) { - $this->completionName = $argumentName; - $this->completionValue = ''; - } else { - // we've reached the end - $this->completionType = self::TYPE_NONE; - $this->completionName = null; - $this->completionValue = ''; - } - } - } - - /** - * Returns the type of completion required. - * - * TYPE_ARGUMENT_VALUE when completing the value of an input argument - * TYPE_OPTION_VALUE when completing the value of an input option - * TYPE_OPTION_NAME when completing the name of an input option - * TYPE_NONE when nothing should be completed - * - * @return string One of self::TYPE_* constants. TYPE_OPTION_NAME and TYPE_NONE are already implemented by the Console component - */ - public function getCompletionType(): string - { - return $this->completionType; - } - - /** - * The name of the input option or argument when completing a value. - * - * @return string|null returns null when completing an option name - */ - public function getCompletionName(): ?string - { - return $this->completionName; - } - - /** - * The value already typed by the user (or empty string). - */ - public function getCompletionValue(): string - { - return $this->completionValue; - } - - public function mustSuggestOptionValuesFor(string $optionName): bool - { - return self::TYPE_OPTION_VALUE === $this->getCompletionType() && $optionName === $this->getCompletionName(); - } - - public function mustSuggestArgumentValuesFor(string $argumentName): bool - { - return self::TYPE_ARGUMENT_VALUE === $this->getCompletionType() && $argumentName === $this->getCompletionName(); - } - - protected function parseToken(string $token, bool $parseOptions): bool - { - try { - return parent::parseToken($token, $parseOptions); - } catch (RuntimeException $e) { - // suppress errors, completed input is almost never valid - } - - return $parseOptions; - } - - private function getOptionFromToken(string $optionToken): ?InputOption - { - $optionName = ltrim($optionToken, '-'); - if (!$optionName) { - return null; - } - - if ('-' === ($optionToken[1] ?? ' ')) { - // long option name - return $this->definition->hasOption($optionName) ? $this->definition->getOption($optionName) : null; - } - - // short option name - return $this->definition->hasShortcut($optionName[0]) ? $this->definition->getOptionForShortcut($optionName[0]) : null; - } - - /** - * The token of the cursor, or the last token if the cursor is at the end of the input. - */ - private function getRelevantToken(): string - { - return $this->tokens[$this->isCursorFree() ? $this->currentIndex - 1 : $this->currentIndex]; - } - - /** - * Whether the cursor is "free" (i.e. at the end of the input preceded by a space). - */ - private function isCursorFree(): bool - { - $nrOfTokens = \count($this->tokens); - if ($this->currentIndex > $nrOfTokens) { - throw new \LogicException('Current index is invalid, it must be the number of input tokens or one more.'); - } - - return $this->currentIndex >= $nrOfTokens; - } - - public function __toString() - { - $str = ''; - foreach ($this->tokens as $i => $token) { - $str .= $token; - - if ($this->currentIndex === $i) { - $str .= '|'; - } - - $str .= ' '; - } - - if ($this->currentIndex > $i) { - $str .= '|'; - } - - return rtrim($str); - } -} diff --git a/vendor/symfony/console/Completion/CompletionSuggestions.php b/vendor/symfony/console/Completion/CompletionSuggestions.php deleted file mode 100644 index d8905e5ee..000000000 --- a/vendor/symfony/console/Completion/CompletionSuggestions.php +++ /dev/null @@ -1,99 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Completion; - -use Symfony\Component\Console\Input\InputOption; - -/** - * Stores all completion suggestions for the current input. - * - * @author Wouter de Jong - */ -final class CompletionSuggestions -{ - private $valueSuggestions = []; - private $optionSuggestions = []; - - /** - * Add a suggested value for an input option or argument. - * - * @param string|Suggestion $value - * - * @return $this - */ - public function suggestValue($value): self - { - $this->valueSuggestions[] = !$value instanceof Suggestion ? new Suggestion($value) : $value; - - return $this; - } - - /** - * Add multiple suggested values at once for an input option or argument. - * - * @param list $values - * - * @return $this - */ - public function suggestValues(array $values): self - { - foreach ($values as $value) { - $this->suggestValue($value); - } - - return $this; - } - - /** - * Add a suggestion for an input option name. - * - * @return $this - */ - public function suggestOption(InputOption $option): self - { - $this->optionSuggestions[] = $option; - - return $this; - } - - /** - * Add multiple suggestions for input option names at once. - * - * @param InputOption[] $options - * - * @return $this - */ - public function suggestOptions(array $options): self - { - foreach ($options as $option) { - $this->suggestOption($option); - } - - return $this; - } - - /** - * @return InputOption[] - */ - public function getOptionSuggestions(): array - { - return $this->optionSuggestions; - } - - /** - * @return Suggestion[] - */ - public function getValueSuggestions(): array - { - return $this->valueSuggestions; - } -} diff --git a/vendor/symfony/console/Completion/Output/BashCompletionOutput.php b/vendor/symfony/console/Completion/Output/BashCompletionOutput.php deleted file mode 100644 index c6f76eb8f..000000000 --- a/vendor/symfony/console/Completion/Output/BashCompletionOutput.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Completion\Output; - -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * @author Wouter de Jong - */ -class BashCompletionOutput implements CompletionOutputInterface -{ - public function write(CompletionSuggestions $suggestions, OutputInterface $output): void - { - $values = $suggestions->getValueSuggestions(); - foreach ($suggestions->getOptionSuggestions() as $option) { - $values[] = '--'.$option->getName(); - if ($option->isNegatable()) { - $values[] = '--no-'.$option->getName(); - } - } - $output->writeln(implode("\n", $values)); - } -} diff --git a/vendor/symfony/console/Completion/Output/CompletionOutputInterface.php b/vendor/symfony/console/Completion/Output/CompletionOutputInterface.php deleted file mode 100644 index 659e59655..000000000 --- a/vendor/symfony/console/Completion/Output/CompletionOutputInterface.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Completion\Output; - -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Transforms the {@see CompletionSuggestions} object into output readable by the shell completion. - * - * @author Wouter de Jong - */ -interface CompletionOutputInterface -{ - public function write(CompletionSuggestions $suggestions, OutputInterface $output): void; -} diff --git a/vendor/symfony/console/Completion/Suggestion.php b/vendor/symfony/console/Completion/Suggestion.php deleted file mode 100644 index 6c7bc4dc4..000000000 --- a/vendor/symfony/console/Completion/Suggestion.php +++ /dev/null @@ -1,37 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Completion; - -/** - * Represents a single suggested value. - * - * @author Wouter de Jong - */ -class Suggestion -{ - private $value; - - public function __construct(string $value) - { - $this->value = $value; - } - - public function getValue(): string - { - return $this->value; - } - - public function __toString(): string - { - return $this->getValue(); - } -} diff --git a/vendor/symfony/console/ConsoleEvents.php b/vendor/symfony/console/ConsoleEvents.php deleted file mode 100644 index 6ae8f32b8..000000000 --- a/vendor/symfony/console/ConsoleEvents.php +++ /dev/null @@ -1,72 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console; - -use Symfony\Component\Console\Event\ConsoleCommandEvent; -use Symfony\Component\Console\Event\ConsoleErrorEvent; -use Symfony\Component\Console\Event\ConsoleSignalEvent; -use Symfony\Component\Console\Event\ConsoleTerminateEvent; - -/** - * Contains all events dispatched by an Application. - * - * @author Francesco Levorato - */ -final class ConsoleEvents -{ - /** - * The COMMAND event allows you to attach listeners before any command is - * executed by the console. It also allows you to modify the command, input and output - * before they are handed to the command. - * - * @Event("Symfony\Component\Console\Event\ConsoleCommandEvent") - */ - public const COMMAND = 'console.command'; - - /** - * The SIGNAL event allows you to perform some actions - * after the command execution was interrupted. - * - * @Event("Symfony\Component\Console\Event\ConsoleSignalEvent") - */ - public const SIGNAL = 'console.signal'; - - /** - * The TERMINATE event allows you to attach listeners after a command is - * executed by the console. - * - * @Event("Symfony\Component\Console\Event\ConsoleTerminateEvent") - */ - public const TERMINATE = 'console.terminate'; - - /** - * The ERROR event occurs when an uncaught exception or error appears. - * - * This event allows you to deal with the exception/error or - * to modify the thrown exception. - * - * @Event("Symfony\Component\Console\Event\ConsoleErrorEvent") - */ - public const ERROR = 'console.error'; - - /** - * Event aliases. - * - * These aliases can be consumed by RegisterListenersPass. - */ - public const ALIASES = [ - ConsoleCommandEvent::class => self::COMMAND, - ConsoleErrorEvent::class => self::ERROR, - ConsoleSignalEvent::class => self::SIGNAL, - ConsoleTerminateEvent::class => self::TERMINATE, - ]; -} diff --git a/vendor/symfony/console/Cursor.php b/vendor/symfony/console/Cursor.php deleted file mode 100644 index 0c4dafb6c..000000000 --- a/vendor/symfony/console/Cursor.php +++ /dev/null @@ -1,207 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console; - -use Symfony\Component\Console\Output\OutputInterface; - -/** - * @author Pierre du Plessis - */ -final class Cursor -{ - private $output; - private $input; - - /** - * @param resource|null $input - */ - public function __construct(OutputInterface $output, $input = null) - { - $this->output = $output; - $this->input = $input ?? (\defined('STDIN') ? \STDIN : fopen('php://input', 'r+')); - } - - /** - * @return $this - */ - public function moveUp(int $lines = 1): self - { - $this->output->write(sprintf("\x1b[%dA", $lines)); - - return $this; - } - - /** - * @return $this - */ - public function moveDown(int $lines = 1): self - { - $this->output->write(sprintf("\x1b[%dB", $lines)); - - return $this; - } - - /** - * @return $this - */ - public function moveRight(int $columns = 1): self - { - $this->output->write(sprintf("\x1b[%dC", $columns)); - - return $this; - } - - /** - * @return $this - */ - public function moveLeft(int $columns = 1): self - { - $this->output->write(sprintf("\x1b[%dD", $columns)); - - return $this; - } - - /** - * @return $this - */ - public function moveToColumn(int $column): self - { - $this->output->write(sprintf("\x1b[%dG", $column)); - - return $this; - } - - /** - * @return $this - */ - public function moveToPosition(int $column, int $row): self - { - $this->output->write(sprintf("\x1b[%d;%dH", $row + 1, $column)); - - return $this; - } - - /** - * @return $this - */ - public function savePosition(): self - { - $this->output->write("\x1b7"); - - return $this; - } - - /** - * @return $this - */ - public function restorePosition(): self - { - $this->output->write("\x1b8"); - - return $this; - } - - /** - * @return $this - */ - public function hide(): self - { - $this->output->write("\x1b[?25l"); - - return $this; - } - - /** - * @return $this - */ - public function show(): self - { - $this->output->write("\x1b[?25h\x1b[?0c"); - - return $this; - } - - /** - * Clears all the output from the current line. - * - * @return $this - */ - public function clearLine(): self - { - $this->output->write("\x1b[2K"); - - return $this; - } - - /** - * Clears all the output from the current line after the current position. - */ - public function clearLineAfter(): self - { - $this->output->write("\x1b[K"); - - return $this; - } - - /** - * Clears all the output from the cursors' current position to the end of the screen. - * - * @return $this - */ - public function clearOutput(): self - { - $this->output->write("\x1b[0J"); - - return $this; - } - - /** - * Clears the entire screen. - * - * @return $this - */ - public function clearScreen(): self - { - $this->output->write("\x1b[2J"); - - return $this; - } - - /** - * Returns the current cursor position as x,y coordinates. - */ - public function getCurrentPosition(): array - { - static $isTtySupported; - - if (null === $isTtySupported && \function_exists('proc_open')) { - $isTtySupported = (bool) @proc_open('echo 1 >/dev/null', [['file', '/dev/tty', 'r'], ['file', '/dev/tty', 'w'], ['file', '/dev/tty', 'w']], $pipes); - } - - if (!$isTtySupported) { - return [1, 1]; - } - - $sttyMode = shell_exec('stty -g'); - shell_exec('stty -icanon -echo'); - - @fwrite($this->input, "\033[6n"); - - $code = trim(fread($this->input, 1024)); - - shell_exec(sprintf('stty %s', $sttyMode)); - - sscanf($code, "\033[%d;%dR", $row, $col); - - return [$col, $row]; - } -} diff --git a/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php b/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php deleted file mode 100644 index 1fbb212e7..000000000 --- a/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php +++ /dev/null @@ -1,148 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\DependencyInjection; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Command\LazyCommand; -use Symfony\Component\Console\CommandLoader\ContainerCommandLoader; -use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; -use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\DependencyInjection\TypedReference; - -/** - * Registers console commands. - * - * @author Grégoire Pineau - */ -class AddConsoleCommandPass implements CompilerPassInterface -{ - private $commandLoaderServiceId; - private $commandTag; - private $noPreloadTag; - private $privateTagName; - - public function __construct(string $commandLoaderServiceId = 'console.command_loader', string $commandTag = 'console.command', string $noPreloadTag = 'container.no_preload', string $privateTagName = 'container.private') - { - if (0 < \func_num_args()) { - trigger_deprecation('symfony/console', '5.3', 'Configuring "%s" is deprecated.', __CLASS__); - } - - $this->commandLoaderServiceId = $commandLoaderServiceId; - $this->commandTag = $commandTag; - $this->noPreloadTag = $noPreloadTag; - $this->privateTagName = $privateTagName; - } - - public function process(ContainerBuilder $container) - { - $commandServices = $container->findTaggedServiceIds($this->commandTag, true); - $lazyCommandMap = []; - $lazyCommandRefs = []; - $serviceIds = []; - - foreach ($commandServices as $id => $tags) { - $definition = $container->getDefinition($id); - $definition->addTag($this->noPreloadTag); - $class = $container->getParameterBag()->resolveValue($definition->getClass()); - - if (isset($tags[0]['command'])) { - $aliases = $tags[0]['command']; - } else { - if (!$r = $container->getReflectionClass($class)) { - throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); - } - if (!$r->isSubclassOf(Command::class)) { - throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class)); - } - $aliases = str_replace('%', '%%', $class::getDefaultName() ?? ''); - } - - $aliases = explode('|', $aliases ?? ''); - $commandName = array_shift($aliases); - - if ($isHidden = '' === $commandName) { - $commandName = array_shift($aliases); - } - - if (null === $commandName) { - if (!$definition->isPublic() || $definition->isPrivate() || $definition->hasTag($this->privateTagName)) { - $commandId = 'console.command.public_alias.'.$id; - $container->setAlias($commandId, $id)->setPublic(true); - $id = $commandId; - } - $serviceIds[] = $id; - - continue; - } - - $description = $tags[0]['description'] ?? null; - - unset($tags[0]); - $lazyCommandMap[$commandName] = $id; - $lazyCommandRefs[$id] = new TypedReference($id, $class); - - foreach ($aliases as $alias) { - $lazyCommandMap[$alias] = $id; - } - - foreach ($tags as $tag) { - if (isset($tag['command'])) { - $aliases[] = $tag['command']; - $lazyCommandMap[$tag['command']] = $id; - } - - $description = $description ?? $tag['description'] ?? null; - } - - $definition->addMethodCall('setName', [$commandName]); - - if ($aliases) { - $definition->addMethodCall('setAliases', [$aliases]); - } - - if ($isHidden) { - $definition->addMethodCall('setHidden', [true]); - } - - if (!$description) { - if (!$r = $container->getReflectionClass($class)) { - throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); - } - if (!$r->isSubclassOf(Command::class)) { - throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class)); - } - $description = str_replace('%', '%%', $class::getDefaultDescription() ?? ''); - } - - if ($description) { - $definition->addMethodCall('setDescription', [$description]); - - $container->register('.'.$id.'.lazy', LazyCommand::class) - ->setArguments([$commandName, $aliases, $description, $isHidden, new ServiceClosureArgument($lazyCommandRefs[$id])]); - - $lazyCommandRefs[$id] = new Reference('.'.$id.'.lazy'); - } - } - - $container - ->register($this->commandLoaderServiceId, ContainerCommandLoader::class) - ->setPublic(true) - ->addTag($this->noPreloadTag) - ->setArguments([ServiceLocatorTagPass::register($container, $lazyCommandRefs), $lazyCommandMap]); - - $container->setParameter('console.command.ids', $serviceIds); - } -} diff --git a/vendor/symfony/console/Descriptor/ApplicationDescription.php b/vendor/symfony/console/Descriptor/ApplicationDescription.php deleted file mode 100644 index 2a3acc99b..000000000 --- a/vendor/symfony/console/Descriptor/ApplicationDescription.php +++ /dev/null @@ -1,143 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Exception\CommandNotFoundException; - -/** - * @author Jean-François Simon - * - * @internal - */ -class ApplicationDescription -{ - public const GLOBAL_NAMESPACE = '_global'; - - private $application; - private $namespace; - private $showHidden; - - /** - * @var array - */ - private $namespaces; - - /** - * @var array - */ - private $commands; - - /** - * @var array - */ - private $aliases; - - public function __construct(Application $application, string $namespace = null, bool $showHidden = false) - { - $this->application = $application; - $this->namespace = $namespace; - $this->showHidden = $showHidden; - } - - public function getNamespaces(): array - { - if (null === $this->namespaces) { - $this->inspectApplication(); - } - - return $this->namespaces; - } - - /** - * @return Command[] - */ - public function getCommands(): array - { - if (null === $this->commands) { - $this->inspectApplication(); - } - - return $this->commands; - } - - /** - * @throws CommandNotFoundException - */ - public function getCommand(string $name): Command - { - if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) { - throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name)); - } - - return $this->commands[$name] ?? $this->aliases[$name]; - } - - private function inspectApplication() - { - $this->commands = []; - $this->namespaces = []; - - $all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null); - foreach ($this->sortCommands($all) as $namespace => $commands) { - $names = []; - - /** @var Command $command */ - foreach ($commands as $name => $command) { - if (!$command->getName() || (!$this->showHidden && $command->isHidden())) { - continue; - } - - if ($command->getName() === $name) { - $this->commands[$name] = $command; - } else { - $this->aliases[$name] = $command; - } - - $names[] = $name; - } - - $this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names]; - } - } - - private function sortCommands(array $commands): array - { - $namespacedCommands = []; - $globalCommands = []; - $sortedCommands = []; - foreach ($commands as $name => $command) { - $key = $this->application->extractNamespace($name, 1); - if (\in_array($key, ['', self::GLOBAL_NAMESPACE], true)) { - $globalCommands[$name] = $command; - } else { - $namespacedCommands[$key][$name] = $command; - } - } - - if ($globalCommands) { - ksort($globalCommands); - $sortedCommands[self::GLOBAL_NAMESPACE] = $globalCommands; - } - - if ($namespacedCommands) { - ksort($namespacedCommands, \SORT_STRING); - foreach ($namespacedCommands as $key => $commandsSet) { - ksort($commandsSet); - $sortedCommands[$key] = $commandsSet; - } - } - - return $sortedCommands; - } -} diff --git a/vendor/symfony/console/Descriptor/Descriptor.php b/vendor/symfony/console/Descriptor/Descriptor.php deleted file mode 100644 index a3648301f..000000000 --- a/vendor/symfony/console/Descriptor/Descriptor.php +++ /dev/null @@ -1,94 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * @author Jean-François Simon - * - * @internal - */ -abstract class Descriptor implements DescriptorInterface -{ - /** - * @var OutputInterface - */ - protected $output; - - /** - * {@inheritdoc} - */ - public function describe(OutputInterface $output, object $object, array $options = []) - { - $this->output = $output; - - switch (true) { - case $object instanceof InputArgument: - $this->describeInputArgument($object, $options); - break; - case $object instanceof InputOption: - $this->describeInputOption($object, $options); - break; - case $object instanceof InputDefinition: - $this->describeInputDefinition($object, $options); - break; - case $object instanceof Command: - $this->describeCommand($object, $options); - break; - case $object instanceof Application: - $this->describeApplication($object, $options); - break; - default: - throw new InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_debug_type($object))); - } - } - - /** - * Writes content to output. - */ - protected function write(string $content, bool $decorated = false) - { - $this->output->write($content, false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW); - } - - /** - * Describes an InputArgument instance. - */ - abstract protected function describeInputArgument(InputArgument $argument, array $options = []); - - /** - * Describes an InputOption instance. - */ - abstract protected function describeInputOption(InputOption $option, array $options = []); - - /** - * Describes an InputDefinition instance. - */ - abstract protected function describeInputDefinition(InputDefinition $definition, array $options = []); - - /** - * Describes a Command instance. - */ - abstract protected function describeCommand(Command $command, array $options = []); - - /** - * Describes an Application instance. - */ - abstract protected function describeApplication(Application $application, array $options = []); -} diff --git a/vendor/symfony/console/Descriptor/DescriptorInterface.php b/vendor/symfony/console/Descriptor/DescriptorInterface.php deleted file mode 100644 index ebea30367..000000000 --- a/vendor/symfony/console/Descriptor/DescriptorInterface.php +++ /dev/null @@ -1,24 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Descriptor interface. - * - * @author Jean-François Simon - */ -interface DescriptorInterface -{ - public function describe(OutputInterface $output, object $object, array $options = []); -} diff --git a/vendor/symfony/console/Descriptor/JsonDescriptor.php b/vendor/symfony/console/Descriptor/JsonDescriptor.php deleted file mode 100644 index 1d2865941..000000000 --- a/vendor/symfony/console/Descriptor/JsonDescriptor.php +++ /dev/null @@ -1,181 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; - -/** - * JSON descriptor. - * - * @author Jean-François Simon - * - * @internal - */ -class JsonDescriptor extends Descriptor -{ - /** - * {@inheritdoc} - */ - protected function describeInputArgument(InputArgument $argument, array $options = []) - { - $this->writeData($this->getInputArgumentData($argument), $options); - } - - /** - * {@inheritdoc} - */ - protected function describeInputOption(InputOption $option, array $options = []) - { - $this->writeData($this->getInputOptionData($option), $options); - if ($option->isNegatable()) { - $this->writeData($this->getInputOptionData($option, true), $options); - } - } - - /** - * {@inheritdoc} - */ - protected function describeInputDefinition(InputDefinition $definition, array $options = []) - { - $this->writeData($this->getInputDefinitionData($definition), $options); - } - - /** - * {@inheritdoc} - */ - protected function describeCommand(Command $command, array $options = []) - { - $this->writeData($this->getCommandData($command, $options['short'] ?? false), $options); - } - - /** - * {@inheritdoc} - */ - protected function describeApplication(Application $application, array $options = []) - { - $describedNamespace = $options['namespace'] ?? null; - $description = new ApplicationDescription($application, $describedNamespace, true); - $commands = []; - - foreach ($description->getCommands() as $command) { - $commands[] = $this->getCommandData($command, $options['short'] ?? false); - } - - $data = []; - if ('UNKNOWN' !== $application->getName()) { - $data['application']['name'] = $application->getName(); - if ('UNKNOWN' !== $application->getVersion()) { - $data['application']['version'] = $application->getVersion(); - } - } - - $data['commands'] = $commands; - - if ($describedNamespace) { - $data['namespace'] = $describedNamespace; - } else { - $data['namespaces'] = array_values($description->getNamespaces()); - } - - $this->writeData($data, $options); - } - - /** - * Writes data as json. - */ - private function writeData(array $data, array $options) - { - $flags = $options['json_encoding'] ?? 0; - - $this->write(json_encode($data, $flags)); - } - - private function getInputArgumentData(InputArgument $argument): array - { - return [ - 'name' => $argument->getName(), - 'is_required' => $argument->isRequired(), - 'is_array' => $argument->isArray(), - 'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $argument->getDescription()), - 'default' => \INF === $argument->getDefault() ? 'INF' : $argument->getDefault(), - ]; - } - - private function getInputOptionData(InputOption $option, bool $negated = false): array - { - return $negated ? [ - 'name' => '--no-'.$option->getName(), - 'shortcut' => '', - 'accept_value' => false, - 'is_value_required' => false, - 'is_multiple' => false, - 'description' => 'Negate the "--'.$option->getName().'" option', - 'default' => false, - ] : [ - 'name' => '--'.$option->getName(), - 'shortcut' => $option->getShortcut() ? '-'.str_replace('|', '|-', $option->getShortcut()) : '', - 'accept_value' => $option->acceptValue(), - 'is_value_required' => $option->isValueRequired(), - 'is_multiple' => $option->isArray(), - 'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $option->getDescription()), - 'default' => \INF === $option->getDefault() ? 'INF' : $option->getDefault(), - ]; - } - - private function getInputDefinitionData(InputDefinition $definition): array - { - $inputArguments = []; - foreach ($definition->getArguments() as $name => $argument) { - $inputArguments[$name] = $this->getInputArgumentData($argument); - } - - $inputOptions = []; - foreach ($definition->getOptions() as $name => $option) { - $inputOptions[$name] = $this->getInputOptionData($option); - if ($option->isNegatable()) { - $inputOptions['no-'.$name] = $this->getInputOptionData($option, true); - } - } - - return ['arguments' => $inputArguments, 'options' => $inputOptions]; - } - - private function getCommandData(Command $command, bool $short = false): array - { - $data = [ - 'name' => $command->getName(), - 'description' => $command->getDescription(), - ]; - - if ($short) { - $data += [ - 'usage' => $command->getAliases(), - ]; - } else { - $command->mergeApplicationDefinition(false); - - $data += [ - 'usage' => array_merge([$command->getSynopsis()], $command->getUsages(), $command->getAliases()), - 'help' => $command->getProcessedHelp(), - 'definition' => $this->getInputDefinitionData($command->getDefinition()), - ]; - } - - $data['hidden'] = $command->isHidden(); - - return $data; - } -} diff --git a/vendor/symfony/console/Descriptor/MarkdownDescriptor.php b/vendor/symfony/console/Descriptor/MarkdownDescriptor.php deleted file mode 100644 index 21ceca6c2..000000000 --- a/vendor/symfony/console/Descriptor/MarkdownDescriptor.php +++ /dev/null @@ -1,206 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Helper\Helper; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Markdown descriptor. - * - * @author Jean-François Simon - * - * @internal - */ -class MarkdownDescriptor extends Descriptor -{ - /** - * {@inheritdoc} - */ - public function describe(OutputInterface $output, object $object, array $options = []) - { - $decorated = $output->isDecorated(); - $output->setDecorated(false); - - parent::describe($output, $object, $options); - - $output->setDecorated($decorated); - } - - /** - * {@inheritdoc} - */ - protected function write(string $content, bool $decorated = true) - { - parent::write($content, $decorated); - } - - /** - * {@inheritdoc} - */ - protected function describeInputArgument(InputArgument $argument, array $options = []) - { - $this->write( - '#### `'.($argument->getName() ?: '')."`\n\n" - .($argument->getDescription() ? preg_replace('/\s*[\r\n]\s*/', "\n", $argument->getDescription())."\n\n" : '') - .'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n" - .'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n" - .'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`' - ); - } - - /** - * {@inheritdoc} - */ - protected function describeInputOption(InputOption $option, array $options = []) - { - $name = '--'.$option->getName(); - if ($option->isNegatable()) { - $name .= '|--no-'.$option->getName(); - } - if ($option->getShortcut()) { - $name .= '|-'.str_replace('|', '|-', $option->getShortcut()).''; - } - - $this->write( - '#### `'.$name.'`'."\n\n" - .($option->getDescription() ? preg_replace('/\s*[\r\n]\s*/', "\n", $option->getDescription())."\n\n" : '') - .'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n" - .'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n" - .'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n" - .'* Is negatable: '.($option->isNegatable() ? 'yes' : 'no')."\n" - .'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`' - ); - } - - /** - * {@inheritdoc} - */ - protected function describeInputDefinition(InputDefinition $definition, array $options = []) - { - if ($showArguments = \count($definition->getArguments()) > 0) { - $this->write('### Arguments'); - foreach ($definition->getArguments() as $argument) { - $this->write("\n\n"); - if (null !== $describeInputArgument = $this->describeInputArgument($argument)) { - $this->write($describeInputArgument); - } - } - } - - if (\count($definition->getOptions()) > 0) { - if ($showArguments) { - $this->write("\n\n"); - } - - $this->write('### Options'); - foreach ($definition->getOptions() as $option) { - $this->write("\n\n"); - if (null !== $describeInputOption = $this->describeInputOption($option)) { - $this->write($describeInputOption); - } - } - } - } - - /** - * {@inheritdoc} - */ - protected function describeCommand(Command $command, array $options = []) - { - if ($options['short'] ?? false) { - $this->write( - '`'.$command->getName()."`\n" - .str_repeat('-', Helper::width($command->getName()) + 2)."\n\n" - .($command->getDescription() ? $command->getDescription()."\n\n" : '') - .'### Usage'."\n\n" - .array_reduce($command->getAliases(), function ($carry, $usage) { - return $carry.'* `'.$usage.'`'."\n"; - }) - ); - - return; - } - - $command->mergeApplicationDefinition(false); - - $this->write( - '`'.$command->getName()."`\n" - .str_repeat('-', Helper::width($command->getName()) + 2)."\n\n" - .($command->getDescription() ? $command->getDescription()."\n\n" : '') - .'### Usage'."\n\n" - .array_reduce(array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()), function ($carry, $usage) { - return $carry.'* `'.$usage.'`'."\n"; - }) - ); - - if ($help = $command->getProcessedHelp()) { - $this->write("\n"); - $this->write($help); - } - - $definition = $command->getDefinition(); - if ($definition->getOptions() || $definition->getArguments()) { - $this->write("\n\n"); - $this->describeInputDefinition($definition); - } - } - - /** - * {@inheritdoc} - */ - protected function describeApplication(Application $application, array $options = []) - { - $describedNamespace = $options['namespace'] ?? null; - $description = new ApplicationDescription($application, $describedNamespace); - $title = $this->getApplicationTitle($application); - - $this->write($title."\n".str_repeat('=', Helper::width($title))); - - foreach ($description->getNamespaces() as $namespace) { - if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) { - $this->write("\n\n"); - $this->write('**'.$namespace['id'].':**'); - } - - $this->write("\n\n"); - $this->write(implode("\n", array_map(function ($commandName) use ($description) { - return sprintf('* [`%s`](#%s)', $commandName, str_replace(':', '', $description->getCommand($commandName)->getName())); - }, $namespace['commands']))); - } - - foreach ($description->getCommands() as $command) { - $this->write("\n\n"); - if (null !== $describeCommand = $this->describeCommand($command, $options)) { - $this->write($describeCommand); - } - } - } - - private function getApplicationTitle(Application $application): string - { - if ('UNKNOWN' !== $application->getName()) { - if ('UNKNOWN' !== $application->getVersion()) { - return sprintf('%s %s', $application->getName(), $application->getVersion()); - } - - return $application->getName(); - } - - return 'Console Tool'; - } -} diff --git a/vendor/symfony/console/Descriptor/TextDescriptor.php b/vendor/symfony/console/Descriptor/TextDescriptor.php deleted file mode 100644 index fbb140ae7..000000000 --- a/vendor/symfony/console/Descriptor/TextDescriptor.php +++ /dev/null @@ -1,341 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Formatter\OutputFormatter; -use Symfony\Component\Console\Helper\Helper; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; - -/** - * Text descriptor. - * - * @author Jean-François Simon - * - * @internal - */ -class TextDescriptor extends Descriptor -{ - /** - * {@inheritdoc} - */ - protected function describeInputArgument(InputArgument $argument, array $options = []) - { - if (null !== $argument->getDefault() && (!\is_array($argument->getDefault()) || \count($argument->getDefault()))) { - $default = sprintf(' [default: %s]', $this->formatDefaultValue($argument->getDefault())); - } else { - $default = ''; - } - - $totalWidth = $options['total_width'] ?? Helper::width($argument->getName()); - $spacingWidth = $totalWidth - \strlen($argument->getName()); - - $this->writeText(sprintf(' %s %s%s%s', - $argument->getName(), - str_repeat(' ', $spacingWidth), - // + 4 = 2 spaces before , 2 spaces after - preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $argument->getDescription()), - $default - ), $options); - } - - /** - * {@inheritdoc} - */ - protected function describeInputOption(InputOption $option, array $options = []) - { - if ($option->acceptValue() && null !== $option->getDefault() && (!\is_array($option->getDefault()) || \count($option->getDefault()))) { - $default = sprintf(' [default: %s]', $this->formatDefaultValue($option->getDefault())); - } else { - $default = ''; - } - - $value = ''; - if ($option->acceptValue()) { - $value = '='.strtoupper($option->getName()); - - if ($option->isValueOptional()) { - $value = '['.$value.']'; - } - } - - $totalWidth = $options['total_width'] ?? $this->calculateTotalWidthForOptions([$option]); - $synopsis = sprintf('%s%s', - $option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : ' ', - sprintf($option->isNegatable() ? '--%1$s|--no-%1$s' : '--%1$s%2$s', $option->getName(), $value) - ); - - $spacingWidth = $totalWidth - Helper::width($synopsis); - - $this->writeText(sprintf(' %s %s%s%s%s', - $synopsis, - str_repeat(' ', $spacingWidth), - // + 4 = 2 spaces before , 2 spaces after - preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $option->getDescription()), - $default, - $option->isArray() ? ' (multiple values allowed)' : '' - ), $options); - } - - /** - * {@inheritdoc} - */ - protected function describeInputDefinition(InputDefinition $definition, array $options = []) - { - $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions()); - foreach ($definition->getArguments() as $argument) { - $totalWidth = max($totalWidth, Helper::width($argument->getName())); - } - - if ($definition->getArguments()) { - $this->writeText('Arguments:', $options); - $this->writeText("\n"); - foreach ($definition->getArguments() as $argument) { - $this->describeInputArgument($argument, array_merge($options, ['total_width' => $totalWidth])); - $this->writeText("\n"); - } - } - - if ($definition->getArguments() && $definition->getOptions()) { - $this->writeText("\n"); - } - - if ($definition->getOptions()) { - $laterOptions = []; - - $this->writeText('Options:', $options); - foreach ($definition->getOptions() as $option) { - if (\strlen($option->getShortcut() ?? '') > 1) { - $laterOptions[] = $option; - continue; - } - $this->writeText("\n"); - $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth])); - } - foreach ($laterOptions as $option) { - $this->writeText("\n"); - $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth])); - } - } - } - - /** - * {@inheritdoc} - */ - protected function describeCommand(Command $command, array $options = []) - { - $command->mergeApplicationDefinition(false); - - if ($description = $command->getDescription()) { - $this->writeText('Description:', $options); - $this->writeText("\n"); - $this->writeText(' '.$description); - $this->writeText("\n\n"); - } - - $this->writeText('Usage:', $options); - foreach (array_merge([$command->getSynopsis(true)], $command->getAliases(), $command->getUsages()) as $usage) { - $this->writeText("\n"); - $this->writeText(' '.OutputFormatter::escape($usage), $options); - } - $this->writeText("\n"); - - $definition = $command->getDefinition(); - if ($definition->getOptions() || $definition->getArguments()) { - $this->writeText("\n"); - $this->describeInputDefinition($definition, $options); - $this->writeText("\n"); - } - - $help = $command->getProcessedHelp(); - if ($help && $help !== $description) { - $this->writeText("\n"); - $this->writeText('Help:', $options); - $this->writeText("\n"); - $this->writeText(' '.str_replace("\n", "\n ", $help), $options); - $this->writeText("\n"); - } - } - - /** - * {@inheritdoc} - */ - protected function describeApplication(Application $application, array $options = []) - { - $describedNamespace = $options['namespace'] ?? null; - $description = new ApplicationDescription($application, $describedNamespace); - - if (isset($options['raw_text']) && $options['raw_text']) { - $width = $this->getColumnWidth($description->getCommands()); - - foreach ($description->getCommands() as $command) { - $this->writeText(sprintf("%-{$width}s %s", $command->getName(), $command->getDescription()), $options); - $this->writeText("\n"); - } - } else { - if ('' != $help = $application->getHelp()) { - $this->writeText("$help\n\n", $options); - } - - $this->writeText("Usage:\n", $options); - $this->writeText(" command [options] [arguments]\n\n", $options); - - $this->describeInputDefinition(new InputDefinition($application->getDefinition()->getOptions()), $options); - - $this->writeText("\n"); - $this->writeText("\n"); - - $commands = $description->getCommands(); - $namespaces = $description->getNamespaces(); - if ($describedNamespace && $namespaces) { - // make sure all alias commands are included when describing a specific namespace - $describedNamespaceInfo = reset($namespaces); - foreach ($describedNamespaceInfo['commands'] as $name) { - $commands[$name] = $description->getCommand($name); - } - } - - // calculate max. width based on available commands per namespace - $width = $this->getColumnWidth(array_merge(...array_values(array_map(function ($namespace) use ($commands) { - return array_intersect($namespace['commands'], array_keys($commands)); - }, array_values($namespaces))))); - - if ($describedNamespace) { - $this->writeText(sprintf('Available commands for the "%s" namespace:', $describedNamespace), $options); - } else { - $this->writeText('Available commands:', $options); - } - - foreach ($namespaces as $namespace) { - $namespace['commands'] = array_filter($namespace['commands'], function ($name) use ($commands) { - return isset($commands[$name]); - }); - - if (!$namespace['commands']) { - continue; - } - - if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) { - $this->writeText("\n"); - $this->writeText(' '.$namespace['id'].'', $options); - } - - foreach ($namespace['commands'] as $name) { - $this->writeText("\n"); - $spacingWidth = $width - Helper::width($name); - $command = $commands[$name]; - $commandAliases = $name === $command->getName() ? $this->getCommandAliasesText($command) : ''; - $this->writeText(sprintf(' %s%s%s', $name, str_repeat(' ', $spacingWidth), $commandAliases.$command->getDescription()), $options); - } - } - - $this->writeText("\n"); - } - } - - /** - * {@inheritdoc} - */ - private function writeText(string $content, array $options = []) - { - $this->write( - isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content, - isset($options['raw_output']) ? !$options['raw_output'] : true - ); - } - - /** - * Formats command aliases to show them in the command description. - */ - private function getCommandAliasesText(Command $command): string - { - $text = ''; - $aliases = $command->getAliases(); - - if ($aliases) { - $text = '['.implode('|', $aliases).'] '; - } - - return $text; - } - - /** - * Formats input option/argument default value. - * - * @param mixed $default - */ - private function formatDefaultValue($default): string - { - if (\INF === $default) { - return 'INF'; - } - - if (\is_string($default)) { - $default = OutputFormatter::escape($default); - } elseif (\is_array($default)) { - foreach ($default as $key => $value) { - if (\is_string($value)) { - $default[$key] = OutputFormatter::escape($value); - } - } - } - - return str_replace('\\\\', '\\', json_encode($default, \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE)); - } - - /** - * @param array $commands - */ - private function getColumnWidth(array $commands): int - { - $widths = []; - - foreach ($commands as $command) { - if ($command instanceof Command) { - $widths[] = Helper::width($command->getName()); - foreach ($command->getAliases() as $alias) { - $widths[] = Helper::width($alias); - } - } else { - $widths[] = Helper::width($command); - } - } - - return $widths ? max($widths) + 2 : 0; - } - - /** - * @param InputOption[] $options - */ - private function calculateTotalWidthForOptions(array $options): int - { - $totalWidth = 0; - foreach ($options as $option) { - // "-" + shortcut + ", --" + name - $nameLength = 1 + max(Helper::width($option->getShortcut()), 1) + 4 + Helper::width($option->getName()); - if ($option->isNegatable()) { - $nameLength += 6 + Helper::width($option->getName()); // |--no- + name - } elseif ($option->acceptValue()) { - $valueLength = 1 + Helper::width($option->getName()); // = + value - $valueLength += $option->isValueOptional() ? 2 : 0; // [ + ] - - $nameLength += $valueLength; - } - $totalWidth = max($totalWidth, $nameLength); - } - - return $totalWidth; - } -} diff --git a/vendor/symfony/console/Descriptor/XmlDescriptor.php b/vendor/symfony/console/Descriptor/XmlDescriptor.php deleted file mode 100644 index 4f7cd8b3e..000000000 --- a/vendor/symfony/console/Descriptor/XmlDescriptor.php +++ /dev/null @@ -1,247 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Descriptor; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; - -/** - * XML descriptor. - * - * @author Jean-François Simon - * - * @internal - */ -class XmlDescriptor extends Descriptor -{ - public function getInputDefinitionDocument(InputDefinition $definition): \DOMDocument - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - $dom->appendChild($definitionXML = $dom->createElement('definition')); - - $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments')); - foreach ($definition->getArguments() as $argument) { - $this->appendDocument($argumentsXML, $this->getInputArgumentDocument($argument)); - } - - $definitionXML->appendChild($optionsXML = $dom->createElement('options')); - foreach ($definition->getOptions() as $option) { - $this->appendDocument($optionsXML, $this->getInputOptionDocument($option)); - } - - return $dom; - } - - public function getCommandDocument(Command $command, bool $short = false): \DOMDocument - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - $dom->appendChild($commandXML = $dom->createElement('command')); - - $commandXML->setAttribute('id', $command->getName()); - $commandXML->setAttribute('name', $command->getName()); - $commandXML->setAttribute('hidden', $command->isHidden() ? 1 : 0); - - $commandXML->appendChild($usagesXML = $dom->createElement('usages')); - - $commandXML->appendChild($descriptionXML = $dom->createElement('description')); - $descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getDescription()))); - - if ($short) { - foreach ($command->getAliases() as $usage) { - $usagesXML->appendChild($dom->createElement('usage', $usage)); - } - } else { - $command->mergeApplicationDefinition(false); - - foreach (array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()) as $usage) { - $usagesXML->appendChild($dom->createElement('usage', $usage)); - } - - $commandXML->appendChild($helpXML = $dom->createElement('help')); - $helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getProcessedHelp()))); - - $definitionXML = $this->getInputDefinitionDocument($command->getDefinition()); - $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0)); - } - - return $dom; - } - - public function getApplicationDocument(Application $application, string $namespace = null, bool $short = false): \DOMDocument - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - $dom->appendChild($rootXml = $dom->createElement('symfony')); - - if ('UNKNOWN' !== $application->getName()) { - $rootXml->setAttribute('name', $application->getName()); - if ('UNKNOWN' !== $application->getVersion()) { - $rootXml->setAttribute('version', $application->getVersion()); - } - } - - $rootXml->appendChild($commandsXML = $dom->createElement('commands')); - - $description = new ApplicationDescription($application, $namespace, true); - - if ($namespace) { - $commandsXML->setAttribute('namespace', $namespace); - } - - foreach ($description->getCommands() as $command) { - $this->appendDocument($commandsXML, $this->getCommandDocument($command, $short)); - } - - if (!$namespace) { - $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces')); - - foreach ($description->getNamespaces() as $namespaceDescription) { - $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace')); - $namespaceArrayXML->setAttribute('id', $namespaceDescription['id']); - - foreach ($namespaceDescription['commands'] as $name) { - $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command')); - $commandXML->appendChild($dom->createTextNode($name)); - } - } - } - - return $dom; - } - - /** - * {@inheritdoc} - */ - protected function describeInputArgument(InputArgument $argument, array $options = []) - { - $this->writeDocument($this->getInputArgumentDocument($argument)); - } - - /** - * {@inheritdoc} - */ - protected function describeInputOption(InputOption $option, array $options = []) - { - $this->writeDocument($this->getInputOptionDocument($option)); - } - - /** - * {@inheritdoc} - */ - protected function describeInputDefinition(InputDefinition $definition, array $options = []) - { - $this->writeDocument($this->getInputDefinitionDocument($definition)); - } - - /** - * {@inheritdoc} - */ - protected function describeCommand(Command $command, array $options = []) - { - $this->writeDocument($this->getCommandDocument($command, $options['short'] ?? false)); - } - - /** - * {@inheritdoc} - */ - protected function describeApplication(Application $application, array $options = []) - { - $this->writeDocument($this->getApplicationDocument($application, $options['namespace'] ?? null, $options['short'] ?? false)); - } - - /** - * Appends document children to parent node. - */ - private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent) - { - foreach ($importedParent->childNodes as $childNode) { - $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, true)); - } - } - - /** - * Writes DOM document. - */ - private function writeDocument(\DOMDocument $dom) - { - $dom->formatOutput = true; - $this->write($dom->saveXML()); - } - - private function getInputArgumentDocument(InputArgument $argument): \DOMDocument - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - - $dom->appendChild($objectXML = $dom->createElement('argument')); - $objectXML->setAttribute('name', $argument->getName()); - $objectXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0); - $objectXML->setAttribute('is_array', $argument->isArray() ? 1 : 0); - $objectXML->appendChild($descriptionXML = $dom->createElement('description')); - $descriptionXML->appendChild($dom->createTextNode($argument->getDescription())); - - $objectXML->appendChild($defaultsXML = $dom->createElement('defaults')); - $defaults = \is_array($argument->getDefault()) ? $argument->getDefault() : (\is_bool($argument->getDefault()) ? [var_export($argument->getDefault(), true)] : ($argument->getDefault() ? [$argument->getDefault()] : [])); - foreach ($defaults as $default) { - $defaultsXML->appendChild($defaultXML = $dom->createElement('default')); - $defaultXML->appendChild($dom->createTextNode($default)); - } - - return $dom; - } - - private function getInputOptionDocument(InputOption $option): \DOMDocument - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - - $dom->appendChild($objectXML = $dom->createElement('option')); - $objectXML->setAttribute('name', '--'.$option->getName()); - $pos = strpos($option->getShortcut() ?? '', '|'); - if (false !== $pos) { - $objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos)); - $objectXML->setAttribute('shortcuts', '-'.str_replace('|', '|-', $option->getShortcut())); - } else { - $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : ''); - } - $objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0); - $objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0); - $objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0); - $objectXML->appendChild($descriptionXML = $dom->createElement('description')); - $descriptionXML->appendChild($dom->createTextNode($option->getDescription())); - - if ($option->acceptValue()) { - $defaults = \is_array($option->getDefault()) ? $option->getDefault() : (\is_bool($option->getDefault()) ? [var_export($option->getDefault(), true)] : ($option->getDefault() ? [$option->getDefault()] : [])); - $objectXML->appendChild($defaultsXML = $dom->createElement('defaults')); - - if (!empty($defaults)) { - foreach ($defaults as $default) { - $defaultsXML->appendChild($defaultXML = $dom->createElement('default')); - $defaultXML->appendChild($dom->createTextNode($default)); - } - } - } - - if ($option->isNegatable()) { - $dom->appendChild($objectXML = $dom->createElement('option')); - $objectXML->setAttribute('name', '--no-'.$option->getName()); - $objectXML->setAttribute('shortcut', ''); - $objectXML->setAttribute('accept_value', 0); - $objectXML->setAttribute('is_value_required', 0); - $objectXML->setAttribute('is_multiple', 0); - $objectXML->appendChild($descriptionXML = $dom->createElement('description')); - $descriptionXML->appendChild($dom->createTextNode('Negate the "--'.$option->getName().'" option')); - } - - return $dom; - } -} diff --git a/vendor/symfony/console/Event/ConsoleCommandEvent.php b/vendor/symfony/console/Event/ConsoleCommandEvent.php deleted file mode 100644 index 08bd18fd1..000000000 --- a/vendor/symfony/console/Event/ConsoleCommandEvent.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Event; - -/** - * Allows to do things before the command is executed, like skipping the command or changing the input. - * - * @author Fabien Potencier - */ -final class ConsoleCommandEvent extends ConsoleEvent -{ - /** - * The return code for skipped commands, this will also be passed into the terminate event. - */ - public const RETURN_CODE_DISABLED = 113; - - /** - * Indicates if the command should be run or skipped. - */ - private $commandShouldRun = true; - - /** - * Disables the command, so it won't be run. - */ - public function disableCommand(): bool - { - return $this->commandShouldRun = false; - } - - public function enableCommand(): bool - { - return $this->commandShouldRun = true; - } - - /** - * Returns true if the command is runnable, false otherwise. - */ - public function commandShouldRun(): bool - { - return $this->commandShouldRun; - } -} diff --git a/vendor/symfony/console/Event/ConsoleErrorEvent.php b/vendor/symfony/console/Event/ConsoleErrorEvent.php deleted file mode 100644 index 57d9b38ba..000000000 --- a/vendor/symfony/console/Event/ConsoleErrorEvent.php +++ /dev/null @@ -1,58 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Event; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Allows to handle throwables thrown while running a command. - * - * @author Wouter de Jong - */ -final class ConsoleErrorEvent extends ConsoleEvent -{ - private $error; - private $exitCode; - - public function __construct(InputInterface $input, OutputInterface $output, \Throwable $error, Command $command = null) - { - parent::__construct($command, $input, $output); - - $this->error = $error; - } - - public function getError(): \Throwable - { - return $this->error; - } - - public function setError(\Throwable $error): void - { - $this->error = $error; - } - - public function setExitCode(int $exitCode): void - { - $this->exitCode = $exitCode; - - $r = new \ReflectionProperty($this->error, 'code'); - $r->setAccessible(true); - $r->setValue($this->error, $this->exitCode); - } - - public function getExitCode(): int - { - return $this->exitCode ?? (\is_int($this->error->getCode()) && 0 !== $this->error->getCode() ? $this->error->getCode() : 1); - } -} diff --git a/vendor/symfony/console/Event/ConsoleEvent.php b/vendor/symfony/console/Event/ConsoleEvent.php deleted file mode 100644 index be7937d51..000000000 --- a/vendor/symfony/console/Event/ConsoleEvent.php +++ /dev/null @@ -1,67 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Event; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Contracts\EventDispatcher\Event; - -/** - * Allows to inspect input and output of a command. - * - * @author Francesco Levorato - */ -class ConsoleEvent extends Event -{ - protected $command; - - private $input; - private $output; - - public function __construct(?Command $command, InputInterface $input, OutputInterface $output) - { - $this->command = $command; - $this->input = $input; - $this->output = $output; - } - - /** - * Gets the command that is executed. - * - * @return Command|null - */ - public function getCommand() - { - return $this->command; - } - - /** - * Gets the input instance. - * - * @return InputInterface - */ - public function getInput() - { - return $this->input; - } - - /** - * Gets the output instance. - * - * @return OutputInterface - */ - public function getOutput() - { - return $this->output; - } -} diff --git a/vendor/symfony/console/Event/ConsoleSignalEvent.php b/vendor/symfony/console/Event/ConsoleSignalEvent.php deleted file mode 100644 index ef13ed2f5..000000000 --- a/vendor/symfony/console/Event/ConsoleSignalEvent.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Event; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * @author marie - */ -final class ConsoleSignalEvent extends ConsoleEvent -{ - private $handlingSignal; - - public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $handlingSignal) - { - parent::__construct($command, $input, $output); - $this->handlingSignal = $handlingSignal; - } - - public function getHandlingSignal(): int - { - return $this->handlingSignal; - } -} diff --git a/vendor/symfony/console/Event/ConsoleTerminateEvent.php b/vendor/symfony/console/Event/ConsoleTerminateEvent.php deleted file mode 100644 index 190038d1a..000000000 --- a/vendor/symfony/console/Event/ConsoleTerminateEvent.php +++ /dev/null @@ -1,43 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Event; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Allows to manipulate the exit code of a command after its execution. - * - * @author Francesco Levorato - */ -final class ConsoleTerminateEvent extends ConsoleEvent -{ - private $exitCode; - - public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $exitCode) - { - parent::__construct($command, $input, $output); - - $this->setExitCode($exitCode); - } - - public function setExitCode(int $exitCode): void - { - $this->exitCode = $exitCode; - } - - public function getExitCode(): int - { - return $this->exitCode; - } -} diff --git a/vendor/symfony/console/EventListener/ErrorListener.php b/vendor/symfony/console/EventListener/ErrorListener.php deleted file mode 100644 index 897d9853f..000000000 --- a/vendor/symfony/console/EventListener/ErrorListener.php +++ /dev/null @@ -1,95 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\EventListener; - -use Psr\Log\LoggerInterface; -use Symfony\Component\Console\ConsoleEvents; -use Symfony\Component\Console\Event\ConsoleErrorEvent; -use Symfony\Component\Console\Event\ConsoleEvent; -use Symfony\Component\Console\Event\ConsoleTerminateEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -/** - * @author James Halsall - * @author Robin Chalas - */ -class ErrorListener implements EventSubscriberInterface -{ - private $logger; - - public function __construct(LoggerInterface $logger = null) - { - $this->logger = $logger; - } - - public function onConsoleError(ConsoleErrorEvent $event) - { - if (null === $this->logger) { - return; - } - - $error = $event->getError(); - - if (!$inputString = $this->getInputString($event)) { - $this->logger->critical('An error occurred while using the console. Message: "{message}"', ['exception' => $error, 'message' => $error->getMessage()]); - - return; - } - - $this->logger->critical('Error thrown while running command "{command}". Message: "{message}"', ['exception' => $error, 'command' => $inputString, 'message' => $error->getMessage()]); - } - - public function onConsoleTerminate(ConsoleTerminateEvent $event) - { - if (null === $this->logger) { - return; - } - - $exitCode = $event->getExitCode(); - - if (0 === $exitCode) { - return; - } - - if (!$inputString = $this->getInputString($event)) { - $this->logger->debug('The console exited with code "{code}"', ['code' => $exitCode]); - - return; - } - - $this->logger->debug('Command "{command}" exited with code "{code}"', ['command' => $inputString, 'code' => $exitCode]); - } - - public static function getSubscribedEvents() - { - return [ - ConsoleEvents::ERROR => ['onConsoleError', -128], - ConsoleEvents::TERMINATE => ['onConsoleTerminate', -128], - ]; - } - - private static function getInputString(ConsoleEvent $event): ?string - { - $commandName = $event->getCommand() ? $event->getCommand()->getName() : null; - $input = $event->getInput(); - - if (method_exists($input, '__toString')) { - if ($commandName) { - return str_replace(["'$commandName'", "\"$commandName\""], $commandName, (string) $input); - } - - return (string) $input; - } - - return $commandName; - } -} diff --git a/vendor/symfony/console/Exception/CommandNotFoundException.php b/vendor/symfony/console/Exception/CommandNotFoundException.php deleted file mode 100644 index 910ae1928..000000000 --- a/vendor/symfony/console/Exception/CommandNotFoundException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Exception; - -/** - * Represents an incorrect command name typed in the console. - * - * @author Jérôme Tamarelle - */ -class CommandNotFoundException extends \InvalidArgumentException implements ExceptionInterface -{ - private $alternatives; - - /** - * @param string $message Exception message to throw - * @param string[] $alternatives List of similar defined names - * @param int $code Exception code - * @param \Throwable|null $previous Previous exception used for the exception chaining - */ - public function __construct(string $message, array $alternatives = [], int $code = 0, \Throwable $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->alternatives = $alternatives; - } - - /** - * @return string[] - */ - public function getAlternatives() - { - return $this->alternatives; - } -} diff --git a/vendor/symfony/console/Exception/ExceptionInterface.php b/vendor/symfony/console/Exception/ExceptionInterface.php deleted file mode 100644 index 1624e13d0..000000000 --- a/vendor/symfony/console/Exception/ExceptionInterface.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Exception; - -/** - * ExceptionInterface. - * - * @author Jérôme Tamarelle - */ -interface ExceptionInterface extends \Throwable -{ -} diff --git a/vendor/symfony/console/Exception/InvalidArgumentException.php b/vendor/symfony/console/Exception/InvalidArgumentException.php deleted file mode 100644 index 07cc0b61d..000000000 --- a/vendor/symfony/console/Exception/InvalidArgumentException.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Exception; - -/** - * @author Jérôme Tamarelle - */ -class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface -{ -} diff --git a/vendor/symfony/console/Exception/InvalidOptionException.php b/vendor/symfony/console/Exception/InvalidOptionException.php deleted file mode 100644 index 5cf62792e..000000000 --- a/vendor/symfony/console/Exception/InvalidOptionException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Exception; - -/** - * Represents an incorrect option name or value typed in the console. - * - * @author Jérôme Tamarelle - */ -class InvalidOptionException extends \InvalidArgumentException implements ExceptionInterface -{ -} diff --git a/vendor/symfony/console/Exception/LogicException.php b/vendor/symfony/console/Exception/LogicException.php deleted file mode 100644 index fc37b8d8a..000000000 --- a/vendor/symfony/console/Exception/LogicException.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Exception; - -/** - * @author Jérôme Tamarelle - */ -class LogicException extends \LogicException implements ExceptionInterface -{ -} diff --git a/vendor/symfony/console/Exception/MissingInputException.php b/vendor/symfony/console/Exception/MissingInputException.php deleted file mode 100644 index 04f02ade4..000000000 --- a/vendor/symfony/console/Exception/MissingInputException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Exception; - -/** - * Represents failure to read input from stdin. - * - * @author Gabriel Ostrolucký - */ -class MissingInputException extends RuntimeException implements ExceptionInterface -{ -} diff --git a/vendor/symfony/console/Exception/NamespaceNotFoundException.php b/vendor/symfony/console/Exception/NamespaceNotFoundException.php deleted file mode 100644 index dd16e4508..000000000 --- a/vendor/symfony/console/Exception/NamespaceNotFoundException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Exception; - -/** - * Represents an incorrect namespace typed in the console. - * - * @author Pierre du Plessis - */ -class NamespaceNotFoundException extends CommandNotFoundException -{ -} diff --git a/vendor/symfony/console/Exception/RuntimeException.php b/vendor/symfony/console/Exception/RuntimeException.php deleted file mode 100644 index 51d7d80ac..000000000 --- a/vendor/symfony/console/Exception/RuntimeException.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Exception; - -/** - * @author Jérôme Tamarelle - */ -class RuntimeException extends \RuntimeException implements ExceptionInterface -{ -} diff --git a/vendor/symfony/console/Formatter/NullOutputFormatter.php b/vendor/symfony/console/Formatter/NullOutputFormatter.php deleted file mode 100644 index d770e1465..000000000 --- a/vendor/symfony/console/Formatter/NullOutputFormatter.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Formatter; - -/** - * @author Tien Xuan Vo - */ -final class NullOutputFormatter implements OutputFormatterInterface -{ - private $style; - - /** - * {@inheritdoc} - */ - public function format(?string $message): ?string - { - return null; - } - - /** - * {@inheritdoc} - */ - public function getStyle(string $name): OutputFormatterStyleInterface - { - // to comply with the interface we must return a OutputFormatterStyleInterface - return $this->style ?? $this->style = new NullOutputFormatterStyle(); - } - - /** - * {@inheritdoc} - */ - public function hasStyle(string $name): bool - { - return false; - } - - /** - * {@inheritdoc} - */ - public function isDecorated(): bool - { - return false; - } - - /** - * {@inheritdoc} - */ - public function setDecorated(bool $decorated): void - { - // do nothing - } - - /** - * {@inheritdoc} - */ - public function setStyle(string $name, OutputFormatterStyleInterface $style): void - { - // do nothing - } -} diff --git a/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php b/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php deleted file mode 100644 index 9232510f4..000000000 --- a/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php +++ /dev/null @@ -1,66 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Formatter; - -/** - * @author Tien Xuan Vo - */ -final class NullOutputFormatterStyle implements OutputFormatterStyleInterface -{ - /** - * {@inheritdoc} - */ - public function apply(string $text): string - { - return $text; - } - - /** - * {@inheritdoc} - */ - public function setBackground(string $color = null): void - { - // do nothing - } - - /** - * {@inheritdoc} - */ - public function setForeground(string $color = null): void - { - // do nothing - } - - /** - * {@inheritdoc} - */ - public function setOption(string $option): void - { - // do nothing - } - - /** - * {@inheritdoc} - */ - public function setOptions(array $options): void - { - // do nothing - } - - /** - * {@inheritdoc} - */ - public function unsetOption(string $option): void - { - // do nothing - } -} diff --git a/vendor/symfony/console/Formatter/OutputFormatter.php b/vendor/symfony/console/Formatter/OutputFormatter.php deleted file mode 100644 index 603e5dca0..000000000 --- a/vendor/symfony/console/Formatter/OutputFormatter.php +++ /dev/null @@ -1,285 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Formatter; - -use Symfony\Component\Console\Exception\InvalidArgumentException; - -/** - * Formatter class for console output. - * - * @author Konstantin Kudryashov - * @author Roland Franssen - */ -class OutputFormatter implements WrappableOutputFormatterInterface -{ - private $decorated; - private $styles = []; - private $styleStack; - - public function __clone() - { - $this->styleStack = clone $this->styleStack; - foreach ($this->styles as $key => $value) { - $this->styles[$key] = clone $value; - } - } - - /** - * Escapes "<" and ">" special chars in given text. - * - * @return string - */ - public static function escape(string $text) - { - $text = preg_replace('/([^\\\\]|^)([<>])/', '$1\\\\$2', $text); - - return self::escapeTrailingBackslash($text); - } - - /** - * Escapes trailing "\" in given text. - * - * @internal - */ - public static function escapeTrailingBackslash(string $text): string - { - if (str_ends_with($text, '\\')) { - $len = \strlen($text); - $text = rtrim($text, '\\'); - $text = str_replace("\0", '', $text); - $text .= str_repeat("\0", $len - \strlen($text)); - } - - return $text; - } - - /** - * Initializes console output formatter. - * - * @param OutputFormatterStyleInterface[] $styles Array of "name => FormatterStyle" instances - */ - public function __construct(bool $decorated = false, array $styles = []) - { - $this->decorated = $decorated; - - $this->setStyle('error', new OutputFormatterStyle('white', 'red')); - $this->setStyle('info', new OutputFormatterStyle('green')); - $this->setStyle('comment', new OutputFormatterStyle('yellow')); - $this->setStyle('question', new OutputFormatterStyle('black', 'cyan')); - - foreach ($styles as $name => $style) { - $this->setStyle($name, $style); - } - - $this->styleStack = new OutputFormatterStyleStack(); - } - - /** - * {@inheritdoc} - */ - public function setDecorated(bool $decorated) - { - $this->decorated = $decorated; - } - - /** - * {@inheritdoc} - */ - public function isDecorated() - { - return $this->decorated; - } - - /** - * {@inheritdoc} - */ - public function setStyle(string $name, OutputFormatterStyleInterface $style) - { - $this->styles[strtolower($name)] = $style; - } - - /** - * {@inheritdoc} - */ - public function hasStyle(string $name) - { - return isset($this->styles[strtolower($name)]); - } - - /** - * {@inheritdoc} - */ - public function getStyle(string $name) - { - if (!$this->hasStyle($name)) { - throw new InvalidArgumentException(sprintf('Undefined style: "%s".', $name)); - } - - return $this->styles[strtolower($name)]; - } - - /** - * {@inheritdoc} - */ - public function format(?string $message) - { - return $this->formatAndWrap($message, 0); - } - - /** - * {@inheritdoc} - */ - public function formatAndWrap(?string $message, int $width) - { - if (null === $message) { - return ''; - } - - $offset = 0; - $output = ''; - $openTagRegex = '[a-z](?:[^\\\\<>]*+ | \\\\.)*'; - $closeTagRegex = '[a-z][^<>]*+'; - $currentLineLength = 0; - preg_match_all("#<(($openTagRegex) | /($closeTagRegex)?)>#ix", $message, $matches, \PREG_OFFSET_CAPTURE); - foreach ($matches[0] as $i => $match) { - $pos = $match[1]; - $text = $match[0]; - - if (0 != $pos && '\\' == $message[$pos - 1]) { - continue; - } - - // add the text up to the next tag - $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset), $output, $width, $currentLineLength); - $offset = $pos + \strlen($text); - - // opening tag? - if ($open = '/' != $text[1]) { - $tag = $matches[1][$i][0]; - } else { - $tag = $matches[3][$i][0] ?? ''; - } - - if (!$open && !$tag) { - // - $this->styleStack->pop(); - } elseif (null === $style = $this->createStyleFromString($tag)) { - $output .= $this->applyCurrentStyle($text, $output, $width, $currentLineLength); - } elseif ($open) { - $this->styleStack->push($style); - } else { - $this->styleStack->pop($style); - } - } - - $output .= $this->applyCurrentStyle(substr($message, $offset), $output, $width, $currentLineLength); - - return strtr($output, ["\0" => '\\', '\\<' => '<', '\\>' => '>']); - } - - /** - * @return OutputFormatterStyleStack - */ - public function getStyleStack() - { - return $this->styleStack; - } - - /** - * Tries to create new style instance from string. - */ - private function createStyleFromString(string $string): ?OutputFormatterStyleInterface - { - if (isset($this->styles[$string])) { - return $this->styles[$string]; - } - - if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', $string, $matches, \PREG_SET_ORDER)) { - return null; - } - - $style = new OutputFormatterStyle(); - foreach ($matches as $match) { - array_shift($match); - $match[0] = strtolower($match[0]); - - if ('fg' == $match[0]) { - $style->setForeground(strtolower($match[1])); - } elseif ('bg' == $match[0]) { - $style->setBackground(strtolower($match[1])); - } elseif ('href' === $match[0]) { - $url = preg_replace('{\\\\([<>])}', '$1', $match[1]); - $style->setHref($url); - } elseif ('options' === $match[0]) { - preg_match_all('([^,;]+)', strtolower($match[1]), $options); - $options = array_shift($options); - foreach ($options as $option) { - $style->setOption($option); - } - } else { - return null; - } - } - - return $style; - } - - /** - * Applies current style from stack to text, if must be applied. - */ - private function applyCurrentStyle(string $text, string $current, int $width, int &$currentLineLength): string - { - if ('' === $text) { - return ''; - } - - if (!$width) { - return $this->isDecorated() ? $this->styleStack->getCurrent()->apply($text) : $text; - } - - if (!$currentLineLength && '' !== $current) { - $text = ltrim($text); - } - - if ($currentLineLength) { - $prefix = substr($text, 0, $i = $width - $currentLineLength)."\n"; - $text = substr($text, $i); - } else { - $prefix = ''; - } - - preg_match('~(\\n)$~', $text, $matches); - $text = $prefix.preg_replace('~([^\\n]{'.$width.'})\\ *~', "\$1\n", $text); - $text = rtrim($text, "\n").($matches[1] ?? ''); - - if (!$currentLineLength && '' !== $current && "\n" !== substr($current, -1)) { - $text = "\n".$text; - } - - $lines = explode("\n", $text); - - foreach ($lines as $line) { - $currentLineLength += \strlen($line); - if ($width <= $currentLineLength) { - $currentLineLength = 0; - } - } - - if ($this->isDecorated()) { - foreach ($lines as $i => $line) { - $lines[$i] = $this->styleStack->getCurrent()->apply($line); - } - } - - return implode("\n", $lines); - } -} diff --git a/vendor/symfony/console/Formatter/OutputFormatterInterface.php b/vendor/symfony/console/Formatter/OutputFormatterInterface.php deleted file mode 100644 index 0b5f839a2..000000000 --- a/vendor/symfony/console/Formatter/OutputFormatterInterface.php +++ /dev/null @@ -1,60 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Formatter; - -/** - * Formatter interface for console output. - * - * @author Konstantin Kudryashov - */ -interface OutputFormatterInterface -{ - /** - * Sets the decorated flag. - */ - public function setDecorated(bool $decorated); - - /** - * Whether the output will decorate messages. - * - * @return bool - */ - public function isDecorated(); - - /** - * Sets a new style. - */ - public function setStyle(string $name, OutputFormatterStyleInterface $style); - - /** - * Checks if output formatter has style with specified name. - * - * @return bool - */ - public function hasStyle(string $name); - - /** - * Gets style options from style with specified name. - * - * @return OutputFormatterStyleInterface - * - * @throws \InvalidArgumentException When style isn't defined - */ - public function getStyle(string $name); - - /** - * Formats a message according to the given styles. - * - * @return string|null - */ - public function format(?string $message); -} diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyle.php b/vendor/symfony/console/Formatter/OutputFormatterStyle.php deleted file mode 100644 index 0fb36ac63..000000000 --- a/vendor/symfony/console/Formatter/OutputFormatterStyle.php +++ /dev/null @@ -1,108 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Formatter; - -use Symfony\Component\Console\Color; - -/** - * Formatter style class for defining styles. - * - * @author Konstantin Kudryashov - */ -class OutputFormatterStyle implements OutputFormatterStyleInterface -{ - private $color; - private $foreground; - private $background; - private $options; - private $href; - private $handlesHrefGracefully; - - /** - * Initializes output formatter style. - * - * @param string|null $foreground The style foreground color name - * @param string|null $background The style background color name - */ - public function __construct(string $foreground = null, string $background = null, array $options = []) - { - $this->color = new Color($this->foreground = $foreground ?: '', $this->background = $background ?: '', $this->options = $options); - } - - /** - * {@inheritdoc} - */ - public function setForeground(string $color = null) - { - $this->color = new Color($this->foreground = $color ?: '', $this->background, $this->options); - } - - /** - * {@inheritdoc} - */ - public function setBackground(string $color = null) - { - $this->color = new Color($this->foreground, $this->background = $color ?: '', $this->options); - } - - public function setHref(string $url): void - { - $this->href = $url; - } - - /** - * {@inheritdoc} - */ - public function setOption(string $option) - { - $this->options[] = $option; - $this->color = new Color($this->foreground, $this->background, $this->options); - } - - /** - * {@inheritdoc} - */ - public function unsetOption(string $option) - { - $pos = array_search($option, $this->options); - if (false !== $pos) { - unset($this->options[$pos]); - } - - $this->color = new Color($this->foreground, $this->background, $this->options); - } - - /** - * {@inheritdoc} - */ - public function setOptions(array $options) - { - $this->color = new Color($this->foreground, $this->background, $this->options = $options); - } - - /** - * {@inheritdoc} - */ - public function apply(string $text) - { - if (null === $this->handlesHrefGracefully) { - $this->handlesHrefGracefully = 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR') - && (!getenv('KONSOLE_VERSION') || (int) getenv('KONSOLE_VERSION') > 201100); - } - - if (null !== $this->href && $this->handlesHrefGracefully) { - $text = "\033]8;;$this->href\033\\$text\033]8;;\033\\"; - } - - return $this->color->apply($text); - } -} diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php b/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php deleted file mode 100644 index b30560d22..000000000 --- a/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Formatter; - -/** - * Formatter style interface for defining styles. - * - * @author Konstantin Kudryashov - */ -interface OutputFormatterStyleInterface -{ - /** - * Sets style foreground color. - */ - public function setForeground(string $color = null); - - /** - * Sets style background color. - */ - public function setBackground(string $color = null); - - /** - * Sets some specific style option. - */ - public function setOption(string $option); - - /** - * Unsets some specific style option. - */ - public function unsetOption(string $option); - - /** - * Sets multiple style options at once. - */ - public function setOptions(array $options); - - /** - * Applies the style to a given text. - * - * @return string - */ - public function apply(string $text); -} diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php b/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php deleted file mode 100644 index fc48dc0e1..000000000 --- a/vendor/symfony/console/Formatter/OutputFormatterStyleStack.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. - */ - -namespace Symfony\Component\Console\Formatter; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Contracts\Service\ResetInterface; - -/** - * @author Jean-François Simon - */ -class OutputFormatterStyleStack implements ResetInterface -{ - /** - * @var OutputFormatterStyleInterface[] - */ - private $styles; - - private $emptyStyle; - - public function __construct(OutputFormatterStyleInterface $emptyStyle = null) - { - $this->emptyStyle = $emptyStyle ?? new OutputFormatterStyle(); - $this->reset(); - } - - /** - * Resets stack (ie. empty internal arrays). - */ - public function reset() - { - $this->styles = []; - } - - /** - * Pushes a style in the stack. - */ - public function push(OutputFormatterStyleInterface $style) - { - $this->styles[] = $style; - } - - /** - * Pops a style from the stack. - * - * @return OutputFormatterStyleInterface - * - * @throws InvalidArgumentException When style tags incorrectly nested - */ - public function pop(OutputFormatterStyleInterface $style = null) - { - if (empty($this->styles)) { - return $this->emptyStyle; - } - - if (null === $style) { - return array_pop($this->styles); - } - - foreach (array_reverse($this->styles, true) as $index => $stackedStyle) { - if ($style->apply('') === $stackedStyle->apply('')) { - $this->styles = \array_slice($this->styles, 0, $index); - - return $stackedStyle; - } - } - - throw new InvalidArgumentException('Incorrectly nested style tag found.'); - } - - /** - * Computes current style with stacks top codes. - * - * @return OutputFormatterStyle - */ - public function getCurrent() - { - if (empty($this->styles)) { - return $this->emptyStyle; - } - - return $this->styles[\count($this->styles) - 1]; - } - - /** - * @return $this - */ - public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle) - { - $this->emptyStyle = $emptyStyle; - - return $this; - } - - /** - * @return OutputFormatterStyleInterface - */ - public function getEmptyStyle() - { - return $this->emptyStyle; - } -} diff --git a/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php b/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php deleted file mode 100644 index 42319ee55..000000000 --- a/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Formatter; - -/** - * Formatter interface for console output that supports word wrapping. - * - * @author Roland Franssen - */ -interface WrappableOutputFormatterInterface extends OutputFormatterInterface -{ - /** - * Formats a message according to the given styles, wrapping at `$width` (0 means no wrapping). - */ - public function formatAndWrap(?string $message, int $width); -} diff --git a/vendor/symfony/console/Helper/DebugFormatterHelper.php b/vendor/symfony/console/Helper/DebugFormatterHelper.php deleted file mode 100644 index e258ba050..000000000 --- a/vendor/symfony/console/Helper/DebugFormatterHelper.php +++ /dev/null @@ -1,107 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -/** - * Helps outputting debug information when running an external program from a command. - * - * An external program can be a Process, an HTTP request, or anything else. - * - * @author Fabien Potencier - */ -class DebugFormatterHelper extends Helper -{ - private const COLORS = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default']; - private $started = []; - private $count = -1; - - /** - * Starts a debug formatting session. - * - * @return string - */ - public function start(string $id, string $message, string $prefix = 'RUN') - { - $this->started[$id] = ['border' => ++$this->count % \count(self::COLORS)]; - - return sprintf("%s %s %s\n", $this->getBorder($id), $prefix, $message); - } - - /** - * Adds progress to a formatting session. - * - * @return string - */ - public function progress(string $id, string $buffer, bool $error = false, string $prefix = 'OUT', string $errorPrefix = 'ERR') - { - $message = ''; - - if ($error) { - if (isset($this->started[$id]['out'])) { - $message .= "\n"; - unset($this->started[$id]['out']); - } - if (!isset($this->started[$id]['err'])) { - $message .= sprintf('%s %s ', $this->getBorder($id), $errorPrefix); - $this->started[$id]['err'] = true; - } - - $message .= str_replace("\n", sprintf("\n%s %s ", $this->getBorder($id), $errorPrefix), $buffer); - } else { - if (isset($this->started[$id]['err'])) { - $message .= "\n"; - unset($this->started[$id]['err']); - } - if (!isset($this->started[$id]['out'])) { - $message .= sprintf('%s %s ', $this->getBorder($id), $prefix); - $this->started[$id]['out'] = true; - } - - $message .= str_replace("\n", sprintf("\n%s %s ", $this->getBorder($id), $prefix), $buffer); - } - - return $message; - } - - /** - * Stops a formatting session. - * - * @return string - */ - public function stop(string $id, string $message, bool $successful, string $prefix = 'RES') - { - $trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : ''; - - if ($successful) { - return sprintf("%s%s %s %s\n", $trailingEOL, $this->getBorder($id), $prefix, $message); - } - - $message = sprintf("%s%s %s %s\n", $trailingEOL, $this->getBorder($id), $prefix, $message); - - unset($this->started[$id]['out'], $this->started[$id]['err']); - - return $message; - } - - private function getBorder(string $id): string - { - return sprintf(' ', self::COLORS[$this->started[$id]['border']]); - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'debug_formatter'; - } -} diff --git a/vendor/symfony/console/Helper/DescriptorHelper.php b/vendor/symfony/console/Helper/DescriptorHelper.php deleted file mode 100644 index af85e9c0a..000000000 --- a/vendor/symfony/console/Helper/DescriptorHelper.php +++ /dev/null @@ -1,92 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Descriptor\DescriptorInterface; -use Symfony\Component\Console\Descriptor\JsonDescriptor; -use Symfony\Component\Console\Descriptor\MarkdownDescriptor; -use Symfony\Component\Console\Descriptor\TextDescriptor; -use Symfony\Component\Console\Descriptor\XmlDescriptor; -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * This class adds helper method to describe objects in various formats. - * - * @author Jean-François Simon - */ -class DescriptorHelper extends Helper -{ - /** - * @var DescriptorInterface[] - */ - private $descriptors = []; - - public function __construct() - { - $this - ->register('txt', new TextDescriptor()) - ->register('xml', new XmlDescriptor()) - ->register('json', new JsonDescriptor()) - ->register('md', new MarkdownDescriptor()) - ; - } - - /** - * Describes an object if supported. - * - * Available options are: - * * format: string, the output format name - * * raw_text: boolean, sets output type as raw - * - * @throws InvalidArgumentException when the given format is not supported - */ - public function describe(OutputInterface $output, ?object $object, array $options = []) - { - $options = array_merge([ - 'raw_text' => false, - 'format' => 'txt', - ], $options); - - if (!isset($this->descriptors[$options['format']])) { - throw new InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format'])); - } - - $descriptor = $this->descriptors[$options['format']]; - $descriptor->describe($output, $object, $options); - } - - /** - * Registers a descriptor. - * - * @return $this - */ - public function register(string $format, DescriptorInterface $descriptor) - { - $this->descriptors[$format] = $descriptor; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'descriptor'; - } - - public function getFormats(): array - { - return array_keys($this->descriptors); - } -} diff --git a/vendor/symfony/console/Helper/Dumper.php b/vendor/symfony/console/Helper/Dumper.php deleted file mode 100644 index b013b6c52..000000000 --- a/vendor/symfony/console/Helper/Dumper.php +++ /dev/null @@ -1,64 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\VarDumper\Cloner\ClonerInterface; -use Symfony\Component\VarDumper\Cloner\VarCloner; -use Symfony\Component\VarDumper\Dumper\CliDumper; - -/** - * @author Roland Franssen - */ -final class Dumper -{ - private $output; - private $dumper; - private $cloner; - private $handler; - - public function __construct(OutputInterface $output, CliDumper $dumper = null, ClonerInterface $cloner = null) - { - $this->output = $output; - $this->dumper = $dumper; - $this->cloner = $cloner; - - if (class_exists(CliDumper::class)) { - $this->handler = function ($var): string { - $dumper = $this->dumper ?? $this->dumper = new CliDumper(null, null, CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_COMMA_SEPARATOR); - $dumper->setColors($this->output->isDecorated()); - - return rtrim($dumper->dump(($this->cloner ?? $this->cloner = new VarCloner())->cloneVar($var)->withRefHandles(false), true)); - }; - } else { - $this->handler = function ($var): string { - switch (true) { - case null === $var: - return 'null'; - case true === $var: - return 'true'; - case false === $var: - return 'false'; - case \is_string($var): - return '"'.$var.'"'; - default: - return rtrim(print_r($var, true)); - } - }; - } - } - - public function __invoke($var): string - { - return ($this->handler)($var); - } -} diff --git a/vendor/symfony/console/Helper/FormatterHelper.php b/vendor/symfony/console/Helper/FormatterHelper.php deleted file mode 100644 index 92d8dc724..000000000 --- a/vendor/symfony/console/Helper/FormatterHelper.php +++ /dev/null @@ -1,92 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Formatter\OutputFormatter; - -/** - * The Formatter class provides helpers to format messages. - * - * @author Fabien Potencier - */ -class FormatterHelper extends Helper -{ - /** - * Formats a message within a section. - * - * @return string - */ - public function formatSection(string $section, string $message, string $style = 'info') - { - return sprintf('<%s>[%s] %s', $style, $section, $style, $message); - } - - /** - * Formats a message as a block of text. - * - * @param string|array $messages The message to write in the block - * - * @return string - */ - public function formatBlock($messages, string $style, bool $large = false) - { - if (!\is_array($messages)) { - $messages = [$messages]; - } - - $len = 0; - $lines = []; - foreach ($messages as $message) { - $message = OutputFormatter::escape($message); - $lines[] = sprintf($large ? ' %s ' : ' %s ', $message); - $len = max(self::width($message) + ($large ? 4 : 2), $len); - } - - $messages = $large ? [str_repeat(' ', $len)] : []; - for ($i = 0; isset($lines[$i]); ++$i) { - $messages[] = $lines[$i].str_repeat(' ', $len - self::width($lines[$i])); - } - if ($large) { - $messages[] = str_repeat(' ', $len); - } - - for ($i = 0; isset($messages[$i]); ++$i) { - $messages[$i] = sprintf('<%s>%s', $style, $messages[$i], $style); - } - - return implode("\n", $messages); - } - - /** - * Truncates a message to the given length. - * - * @return string - */ - public function truncate(string $message, int $length, string $suffix = '...') - { - $computedLength = $length - self::width($suffix); - - if ($computedLength > self::width($message)) { - return $message; - } - - return self::substr($message, 0, $length).$suffix; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'formatter'; - } -} diff --git a/vendor/symfony/console/Helper/Helper.php b/vendor/symfony/console/Helper/Helper.php deleted file mode 100644 index c7d3e25d0..000000000 --- a/vendor/symfony/console/Helper/Helper.php +++ /dev/null @@ -1,180 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Formatter\OutputFormatterInterface; -use Symfony\Component\String\UnicodeString; - -/** - * Helper is the base class for all helper classes. - * - * @author Fabien Potencier - */ -abstract class Helper implements HelperInterface -{ - protected $helperSet = null; - - /** - * {@inheritdoc} - */ - public function setHelperSet(HelperSet $helperSet = null) - { - $this->helperSet = $helperSet; - } - - /** - * {@inheritdoc} - */ - public function getHelperSet() - { - return $this->helperSet; - } - - /** - * Returns the length of a string, using mb_strwidth if it is available. - * - * @deprecated since Symfony 5.3 - * - * @return int - */ - public static function strlen(?string $string) - { - trigger_deprecation('symfony/console', '5.3', 'Method "%s()" is deprecated and will be removed in Symfony 6.0. Use Helper::width() or Helper::length() instead.', __METHOD__); - - return self::width($string); - } - - /** - * Returns the width of a string, using mb_strwidth if it is available. - * The width is how many characters positions the string will use. - */ - public static function width(?string $string): int - { - $string ?? $string = ''; - - if (preg_match('//u', $string)) { - return (new UnicodeString($string))->width(false); - } - - if (false === $encoding = mb_detect_encoding($string, null, true)) { - return \strlen($string); - } - - return mb_strwidth($string, $encoding); - } - - /** - * Returns the length of a string, using mb_strlen if it is available. - * The length is related to how many bytes the string will use. - */ - public static function length(?string $string): int - { - $string ?? $string = ''; - - if (preg_match('//u', $string)) { - return (new UnicodeString($string))->length(); - } - - if (false === $encoding = mb_detect_encoding($string, null, true)) { - return \strlen($string); - } - - return mb_strlen($string, $encoding); - } - - /** - * Returns the subset of a string, using mb_substr if it is available. - * - * @return string - */ - public static function substr(?string $string, int $from, int $length = null) - { - $string ?? $string = ''; - - if (false === $encoding = mb_detect_encoding($string, null, true)) { - return substr($string, $from, $length); - } - - return mb_substr($string, $from, $length, $encoding); - } - - public static function formatTime($secs) - { - static $timeFormats = [ - [0, '< 1 sec'], - [1, '1 sec'], - [2, 'secs', 1], - [60, '1 min'], - [120, 'mins', 60], - [3600, '1 hr'], - [7200, 'hrs', 3600], - [86400, '1 day'], - [172800, 'days', 86400], - ]; - - foreach ($timeFormats as $index => $format) { - if ($secs >= $format[0]) { - if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0]) - || $index == \count($timeFormats) - 1 - ) { - if (2 == \count($format)) { - return $format[1]; - } - - return floor($secs / $format[2]).' '.$format[1]; - } - } - } - } - - public static function formatMemory(int $memory) - { - if ($memory >= 1024 * 1024 * 1024) { - return sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024); - } - - if ($memory >= 1024 * 1024) { - return sprintf('%.1f MiB', $memory / 1024 / 1024); - } - - if ($memory >= 1024) { - return sprintf('%d KiB', $memory / 1024); - } - - return sprintf('%d B', $memory); - } - - /** - * @deprecated since Symfony 5.3 - */ - public static function strlenWithoutDecoration(OutputFormatterInterface $formatter, ?string $string) - { - trigger_deprecation('symfony/console', '5.3', 'Method "%s()" is deprecated and will be removed in Symfony 6.0. Use Helper::removeDecoration() instead.', __METHOD__); - - return self::width(self::removeDecoration($formatter, $string)); - } - - public static function removeDecoration(OutputFormatterInterface $formatter, ?string $string) - { - $isDecorated = $formatter->isDecorated(); - $formatter->setDecorated(false); - // remove <...> formatting - $string = $formatter->format($string ?? ''); - // remove already formatted characters - $string = preg_replace("/\033\[[^m]*m/", '', $string ?? ''); - // remove terminal hyperlinks - $string = preg_replace('/\\033]8;[^;]*;[^\\033]*\\033\\\\/', '', $string ?? ''); - $formatter->setDecorated($isDecorated); - - return $string; - } -} diff --git a/vendor/symfony/console/Helper/HelperInterface.php b/vendor/symfony/console/Helper/HelperInterface.php deleted file mode 100644 index fc952b486..000000000 --- a/vendor/symfony/console/Helper/HelperInterface.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. - */ - -namespace Symfony\Component\Console\Helper; - -/** - * HelperInterface is the interface all helpers must implement. - * - * @author Fabien Potencier - */ -interface HelperInterface -{ - /** - * Sets the helper set associated with this helper. - */ - public function setHelperSet(HelperSet $helperSet = null); - - /** - * Gets the helper set associated with this helper. - * - * @return HelperSet|null - */ - public function getHelperSet(); - - /** - * Returns the canonical name of this helper. - * - * @return string - */ - public function getName(); -} diff --git a/vendor/symfony/console/Helper/HelperSet.php b/vendor/symfony/console/Helper/HelperSet.php deleted file mode 100644 index 719762d24..000000000 --- a/vendor/symfony/console/Helper/HelperSet.php +++ /dev/null @@ -1,108 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Exception\InvalidArgumentException; - -/** - * HelperSet represents a set of helpers to be used with a command. - * - * @author Fabien Potencier - * - * @implements \IteratorAggregate - */ -class HelperSet implements \IteratorAggregate -{ - /** @var array */ - private $helpers = []; - private $command; - - /** - * @param Helper[] $helpers An array of helper - */ - public function __construct(array $helpers = []) - { - foreach ($helpers as $alias => $helper) { - $this->set($helper, \is_int($alias) ? null : $alias); - } - } - - public function set(HelperInterface $helper, string $alias = null) - { - $this->helpers[$helper->getName()] = $helper; - if (null !== $alias) { - $this->helpers[$alias] = $helper; - } - - $helper->setHelperSet($this); - } - - /** - * Returns true if the helper if defined. - * - * @return bool - */ - public function has(string $name) - { - return isset($this->helpers[$name]); - } - - /** - * Gets a helper value. - * - * @return HelperInterface - * - * @throws InvalidArgumentException if the helper is not defined - */ - public function get(string $name) - { - if (!$this->has($name)) { - throw new InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name)); - } - - return $this->helpers[$name]; - } - - /** - * @deprecated since Symfony 5.4 - */ - public function setCommand(Command $command = null) - { - trigger_deprecation('symfony/console', '5.4', 'Method "%s()" is deprecated.', __METHOD__); - - $this->command = $command; - } - - /** - * Gets the command associated with this helper set. - * - * @return Command - * - * @deprecated since Symfony 5.4 - */ - public function getCommand() - { - trigger_deprecation('symfony/console', '5.4', 'Method "%s()" is deprecated.', __METHOD__); - - return $this->command; - } - - /** - * @return \Traversable - */ - #[\ReturnTypeWillChange] - public function getIterator() - { - return new \ArrayIterator($this->helpers); - } -} diff --git a/vendor/symfony/console/Helper/InputAwareHelper.php b/vendor/symfony/console/Helper/InputAwareHelper.php deleted file mode 100644 index 0d0dba23e..000000000 --- a/vendor/symfony/console/Helper/InputAwareHelper.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Input\InputAwareInterface; -use Symfony\Component\Console\Input\InputInterface; - -/** - * An implementation of InputAwareInterface for Helpers. - * - * @author Wouter J - */ -abstract class InputAwareHelper extends Helper implements InputAwareInterface -{ - protected $input; - - /** - * {@inheritdoc} - */ - public function setInput(InputInterface $input) - { - $this->input = $input; - } -} diff --git a/vendor/symfony/console/Helper/ProcessHelper.php b/vendor/symfony/console/Helper/ProcessHelper.php deleted file mode 100644 index 4ea3d724d..000000000 --- a/vendor/symfony/console/Helper/ProcessHelper.php +++ /dev/null @@ -1,144 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Output\ConsoleOutputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Process\Exception\ProcessFailedException; -use Symfony\Component\Process\Process; - -/** - * The ProcessHelper class provides helpers to run external processes. - * - * @author Fabien Potencier - * - * @final - */ -class ProcessHelper extends Helper -{ - /** - * Runs an external process. - * - * @param array|Process $cmd An instance of Process or an array of the command and arguments - * @param callable|null $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR - */ - public function run(OutputInterface $output, $cmd, string $error = null, callable $callback = null, int $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE): Process - { - if (!class_exists(Process::class)) { - throw new \LogicException('The ProcessHelper cannot be run as the Process component is not installed. Try running "compose require symfony/process".'); - } - - if ($output instanceof ConsoleOutputInterface) { - $output = $output->getErrorOutput(); - } - - $formatter = $this->getHelperSet()->get('debug_formatter'); - - if ($cmd instanceof Process) { - $cmd = [$cmd]; - } - - if (!\is_array($cmd)) { - throw new \TypeError(sprintf('The "command" argument of "%s()" must be an array or a "%s" instance, "%s" given.', __METHOD__, Process::class, get_debug_type($cmd))); - } - - if (\is_string($cmd[0] ?? null)) { - $process = new Process($cmd); - $cmd = []; - } elseif (($cmd[0] ?? null) instanceof Process) { - $process = $cmd[0]; - unset($cmd[0]); - } else { - throw new \InvalidArgumentException(sprintf('Invalid command provided to "%s()": the command should be an array whose first element is either the path to the binary to run or a "Process" object.', __METHOD__)); - } - - if ($verbosity <= $output->getVerbosity()) { - $output->write($formatter->start(spl_object_hash($process), $this->escapeString($process->getCommandLine()))); - } - - if ($output->isDebug()) { - $callback = $this->wrapCallback($output, $process, $callback); - } - - $process->run($callback, $cmd); - - if ($verbosity <= $output->getVerbosity()) { - $message = $process->isSuccessful() ? 'Command ran successfully' : sprintf('%s Command did not run successfully', $process->getExitCode()); - $output->write($formatter->stop(spl_object_hash($process), $message, $process->isSuccessful())); - } - - if (!$process->isSuccessful() && null !== $error) { - $output->writeln(sprintf('%s', $this->escapeString($error))); - } - - return $process; - } - - /** - * Runs the process. - * - * This is identical to run() except that an exception is thrown if the process - * exits with a non-zero exit code. - * - * @param array|Process $cmd An instance of Process or a command to run - * @param callable|null $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR - * - * @throws ProcessFailedException - * - * @see run() - */ - public function mustRun(OutputInterface $output, $cmd, string $error = null, callable $callback = null): Process - { - $process = $this->run($output, $cmd, $error, $callback); - - if (!$process->isSuccessful()) { - throw new ProcessFailedException($process); - } - - return $process; - } - - /** - * Wraps a Process callback to add debugging output. - */ - public function wrapCallback(OutputInterface $output, Process $process, callable $callback = null): callable - { - if ($output instanceof ConsoleOutputInterface) { - $output = $output->getErrorOutput(); - } - - $formatter = $this->getHelperSet()->get('debug_formatter'); - - return function ($type, $buffer) use ($output, $process, $callback, $formatter) { - $output->write($formatter->progress(spl_object_hash($process), $this->escapeString($buffer), Process::ERR === $type)); - - if (null !== $callback) { - $callback($type, $buffer); - } - }; - } - - private function escapeString(string $str): string - { - return str_replace('<', '\\<', $str); - } - - /** - * {@inheritdoc} - */ - public function getName(): string - { - return 'process'; - } -} diff --git a/vendor/symfony/console/Helper/ProgressBar.php b/vendor/symfony/console/Helper/ProgressBar.php deleted file mode 100644 index eb6aacb1a..000000000 --- a/vendor/symfony/console/Helper/ProgressBar.php +++ /dev/null @@ -1,609 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Cursor; -use Symfony\Component\Console\Exception\LogicException; -use Symfony\Component\Console\Output\ConsoleOutputInterface; -use Symfony\Component\Console\Output\ConsoleSectionOutput; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Terminal; - -/** - * The ProgressBar provides helpers to display progress output. - * - * @author Fabien Potencier - * @author Chris Jones - */ -final class ProgressBar -{ - public const FORMAT_VERBOSE = 'verbose'; - public const FORMAT_VERY_VERBOSE = 'very_verbose'; - public const FORMAT_DEBUG = 'debug'; - public const FORMAT_NORMAL = 'normal'; - - private const FORMAT_VERBOSE_NOMAX = 'verbose_nomax'; - private const FORMAT_VERY_VERBOSE_NOMAX = 'very_verbose_nomax'; - private const FORMAT_DEBUG_NOMAX = 'debug_nomax'; - private const FORMAT_NORMAL_NOMAX = 'normal_nomax'; - - private $barWidth = 28; - private $barChar; - private $emptyBarChar = '-'; - private $progressChar = '>'; - private $format; - private $internalFormat; - private $redrawFreq = 1; - private $writeCount; - private $lastWriteTime; - private $minSecondsBetweenRedraws = 0; - private $maxSecondsBetweenRedraws = 1; - private $output; - private $step = 0; - private $max; - private $startTime; - private $stepWidth; - private $percent = 0.0; - private $messages = []; - private $overwrite = true; - private $terminal; - private $previousMessage; - private $cursor; - - private static $formatters; - private static $formats; - - /** - * @param int $max Maximum steps (0 if unknown) - */ - public function __construct(OutputInterface $output, int $max = 0, float $minSecondsBetweenRedraws = 1 / 25) - { - if ($output instanceof ConsoleOutputInterface) { - $output = $output->getErrorOutput(); - } - - $this->output = $output; - $this->setMaxSteps($max); - $this->terminal = new Terminal(); - - if (0 < $minSecondsBetweenRedraws) { - $this->redrawFreq = null; - $this->minSecondsBetweenRedraws = $minSecondsBetweenRedraws; - } - - if (!$this->output->isDecorated()) { - // disable overwrite when output does not support ANSI codes. - $this->overwrite = false; - - // set a reasonable redraw frequency so output isn't flooded - $this->redrawFreq = null; - } - - $this->startTime = time(); - $this->cursor = new Cursor($output); - } - - /** - * Sets a placeholder formatter for a given name. - * - * This method also allow you to override an existing placeholder. - * - * @param string $name The placeholder name (including the delimiter char like %) - * @param callable $callable A PHP callable - */ - public static function setPlaceholderFormatterDefinition(string $name, callable $callable): void - { - if (!self::$formatters) { - self::$formatters = self::initPlaceholderFormatters(); - } - - self::$formatters[$name] = $callable; - } - - /** - * Gets the placeholder formatter for a given name. - * - * @param string $name The placeholder name (including the delimiter char like %) - */ - public static function getPlaceholderFormatterDefinition(string $name): ?callable - { - if (!self::$formatters) { - self::$formatters = self::initPlaceholderFormatters(); - } - - return self::$formatters[$name] ?? null; - } - - /** - * Sets a format for a given name. - * - * This method also allow you to override an existing format. - * - * @param string $name The format name - * @param string $format A format string - */ - public static function setFormatDefinition(string $name, string $format): void - { - if (!self::$formats) { - self::$formats = self::initFormats(); - } - - self::$formats[$name] = $format; - } - - /** - * Gets the format for a given name. - * - * @param string $name The format name - */ - public static function getFormatDefinition(string $name): ?string - { - if (!self::$formats) { - self::$formats = self::initFormats(); - } - - return self::$formats[$name] ?? null; - } - - /** - * Associates a text with a named placeholder. - * - * The text is displayed when the progress bar is rendered but only - * when the corresponding placeholder is part of the custom format line - * (by wrapping the name with %). - * - * @param string $message The text to associate with the placeholder - * @param string $name The name of the placeholder - */ - public function setMessage(string $message, string $name = 'message') - { - $this->messages[$name] = $message; - } - - public function getMessage(string $name = 'message') - { - return $this->messages[$name]; - } - - public function getStartTime(): int - { - return $this->startTime; - } - - public function getMaxSteps(): int - { - return $this->max; - } - - public function getProgress(): int - { - return $this->step; - } - - private function getStepWidth(): int - { - return $this->stepWidth; - } - - public function getProgressPercent(): float - { - return $this->percent; - } - - public function getBarOffset(): float - { - return floor($this->max ? $this->percent * $this->barWidth : (null === $this->redrawFreq ? (int) (min(5, $this->barWidth / 15) * $this->writeCount) : $this->step) % $this->barWidth); - } - - public function getEstimated(): float - { - if (!$this->step) { - return 0; - } - - return round((time() - $this->startTime) / $this->step * $this->max); - } - - public function getRemaining(): float - { - if (!$this->step) { - return 0; - } - - return round((time() - $this->startTime) / $this->step * ($this->max - $this->step)); - } - - public function setBarWidth(int $size) - { - $this->barWidth = max(1, $size); - } - - public function getBarWidth(): int - { - return $this->barWidth; - } - - public function setBarCharacter(string $char) - { - $this->barChar = $char; - } - - public function getBarCharacter(): string - { - return $this->barChar ?? ($this->max ? '=' : $this->emptyBarChar); - } - - public function setEmptyBarCharacter(string $char) - { - $this->emptyBarChar = $char; - } - - public function getEmptyBarCharacter(): string - { - return $this->emptyBarChar; - } - - public function setProgressCharacter(string $char) - { - $this->progressChar = $char; - } - - public function getProgressCharacter(): string - { - return $this->progressChar; - } - - public function setFormat(string $format) - { - $this->format = null; - $this->internalFormat = $format; - } - - /** - * Sets the redraw frequency. - * - * @param int|null $freq The frequency in steps - */ - public function setRedrawFrequency(?int $freq) - { - $this->redrawFreq = null !== $freq ? max(1, $freq) : null; - } - - public function minSecondsBetweenRedraws(float $seconds): void - { - $this->minSecondsBetweenRedraws = $seconds; - } - - public function maxSecondsBetweenRedraws(float $seconds): void - { - $this->maxSecondsBetweenRedraws = $seconds; - } - - /** - * Returns an iterator that will automatically update the progress bar when iterated. - * - * @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable - */ - public function iterate(iterable $iterable, int $max = null): iterable - { - $this->start($max ?? (is_countable($iterable) ? \count($iterable) : 0)); - - foreach ($iterable as $key => $value) { - yield $key => $value; - - $this->advance(); - } - - $this->finish(); - } - - /** - * Starts the progress output. - * - * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged - */ - public function start(int $max = null) - { - $this->startTime = time(); - $this->step = 0; - $this->percent = 0.0; - - if (null !== $max) { - $this->setMaxSteps($max); - } - - $this->display(); - } - - /** - * Advances the progress output X steps. - * - * @param int $step Number of steps to advance - */ - public function advance(int $step = 1) - { - $this->setProgress($this->step + $step); - } - - /** - * Sets whether to overwrite the progressbar, false for new line. - */ - public function setOverwrite(bool $overwrite) - { - $this->overwrite = $overwrite; - } - - public function setProgress(int $step) - { - if ($this->max && $step > $this->max) { - $this->max = $step; - } elseif ($step < 0) { - $step = 0; - } - - $redrawFreq = $this->redrawFreq ?? (($this->max ?: 10) / 10); - $prevPeriod = (int) ($this->step / $redrawFreq); - $currPeriod = (int) ($step / $redrawFreq); - $this->step = $step; - $this->percent = $this->max ? (float) $this->step / $this->max : 0; - $timeInterval = microtime(true) - $this->lastWriteTime; - - // Draw regardless of other limits - if ($this->max === $step) { - $this->display(); - - return; - } - - // Throttling - if ($timeInterval < $this->minSecondsBetweenRedraws) { - return; - } - - // Draw each step period, but not too late - if ($prevPeriod !== $currPeriod || $timeInterval >= $this->maxSecondsBetweenRedraws) { - $this->display(); - } - } - - public function setMaxSteps(int $max) - { - $this->format = null; - $this->max = max(0, $max); - $this->stepWidth = $this->max ? Helper::width((string) $this->max) : 4; - } - - /** - * Finishes the progress output. - */ - public function finish(): void - { - if (!$this->max) { - $this->max = $this->step; - } - - if ($this->step === $this->max && !$this->overwrite) { - // prevent double 100% output - return; - } - - $this->setProgress($this->max); - } - - /** - * Outputs the current progress string. - */ - public function display(): void - { - if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) { - return; - } - - if (null === $this->format) { - $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat()); - } - - $this->overwrite($this->buildLine()); - } - - /** - * Removes the progress bar from the current line. - * - * This is useful if you wish to write some output - * while a progress bar is running. - * Call display() to show the progress bar again. - */ - public function clear(): void - { - if (!$this->overwrite) { - return; - } - - if (null === $this->format) { - $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat()); - } - - $this->overwrite(''); - } - - private function setRealFormat(string $format) - { - // try to use the _nomax variant if available - if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) { - $this->format = self::getFormatDefinition($format.'_nomax'); - } elseif (null !== self::getFormatDefinition($format)) { - $this->format = self::getFormatDefinition($format); - } else { - $this->format = $format; - } - } - - /** - * Overwrites a previous message to the output. - */ - private function overwrite(string $message): void - { - if ($this->previousMessage === $message) { - return; - } - - $originalMessage = $message; - - if ($this->overwrite) { - if (null !== $this->previousMessage) { - if ($this->output instanceof ConsoleSectionOutput) { - $messageLines = explode("\n", $this->previousMessage); - $lineCount = \count($messageLines); - foreach ($messageLines as $messageLine) { - $messageLineLength = Helper::width(Helper::removeDecoration($this->output->getFormatter(), $messageLine)); - if ($messageLineLength > $this->terminal->getWidth()) { - $lineCount += floor($messageLineLength / $this->terminal->getWidth()); - } - } - $this->output->clear($lineCount); - } else { - $lineCount = substr_count($this->previousMessage, "\n"); - for ($i = 0; $i < $lineCount; ++$i) { - $this->cursor->moveToColumn(1); - $this->cursor->clearLine(); - $this->cursor->moveUp(); - } - - $this->cursor->moveToColumn(1); - $this->cursor->clearLine(); - } - } - } elseif ($this->step > 0) { - $message = \PHP_EOL.$message; - } - - $this->previousMessage = $originalMessage; - $this->lastWriteTime = microtime(true); - - $this->output->write($message); - ++$this->writeCount; - } - - private function determineBestFormat(): string - { - switch ($this->output->getVerbosity()) { - // OutputInterface::VERBOSITY_QUIET: display is disabled anyway - case OutputInterface::VERBOSITY_VERBOSE: - return $this->max ? self::FORMAT_VERBOSE : self::FORMAT_VERBOSE_NOMAX; - case OutputInterface::VERBOSITY_VERY_VERBOSE: - return $this->max ? self::FORMAT_VERY_VERBOSE : self::FORMAT_VERY_VERBOSE_NOMAX; - case OutputInterface::VERBOSITY_DEBUG: - return $this->max ? self::FORMAT_DEBUG : self::FORMAT_DEBUG_NOMAX; - default: - return $this->max ? self::FORMAT_NORMAL : self::FORMAT_NORMAL_NOMAX; - } - } - - private static function initPlaceholderFormatters(): array - { - return [ - 'bar' => function (self $bar, OutputInterface $output) { - $completeBars = $bar->getBarOffset(); - $display = str_repeat($bar->getBarCharacter(), $completeBars); - if ($completeBars < $bar->getBarWidth()) { - $emptyBars = $bar->getBarWidth() - $completeBars - Helper::length(Helper::removeDecoration($output->getFormatter(), $bar->getProgressCharacter())); - $display .= $bar->getProgressCharacter().str_repeat($bar->getEmptyBarCharacter(), $emptyBars); - } - - return $display; - }, - 'elapsed' => function (self $bar) { - return Helper::formatTime(time() - $bar->getStartTime()); - }, - 'remaining' => function (self $bar) { - if (!$bar->getMaxSteps()) { - throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.'); - } - - return Helper::formatTime($bar->getRemaining()); - }, - 'estimated' => function (self $bar) { - if (!$bar->getMaxSteps()) { - throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.'); - } - - return Helper::formatTime($bar->getEstimated()); - }, - 'memory' => function (self $bar) { - return Helper::formatMemory(memory_get_usage(true)); - }, - 'current' => function (self $bar) { - return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', \STR_PAD_LEFT); - }, - 'max' => function (self $bar) { - return $bar->getMaxSteps(); - }, - 'percent' => function (self $bar) { - return floor($bar->getProgressPercent() * 100); - }, - ]; - } - - private static function initFormats(): array - { - return [ - self::FORMAT_NORMAL => ' %current%/%max% [%bar%] %percent:3s%%', - self::FORMAT_NORMAL_NOMAX => ' %current% [%bar%]', - - self::FORMAT_VERBOSE => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%', - self::FORMAT_VERBOSE_NOMAX => ' %current% [%bar%] %elapsed:6s%', - - self::FORMAT_VERY_VERBOSE => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%', - self::FORMAT_VERY_VERBOSE_NOMAX => ' %current% [%bar%] %elapsed:6s%', - - self::FORMAT_DEBUG => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%', - self::FORMAT_DEBUG_NOMAX => ' %current% [%bar%] %elapsed:6s% %memory:6s%', - ]; - } - - private function buildLine(): string - { - $regex = "{%([a-z\-_]+)(?:\:([^%]+))?%}i"; - $callback = function ($matches) { - if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) { - $text = $formatter($this, $this->output); - } elseif (isset($this->messages[$matches[1]])) { - $text = $this->messages[$matches[1]]; - } else { - return $matches[0]; - } - - if (isset($matches[2])) { - $text = sprintf('%'.$matches[2], $text); - } - - return $text; - }; - $line = preg_replace_callback($regex, $callback, $this->format); - - // gets string length for each sub line with multiline format - $linesLength = array_map(function ($subLine) { - return Helper::width(Helper::removeDecoration($this->output->getFormatter(), rtrim($subLine, "\r"))); - }, explode("\n", $line)); - - $linesWidth = max($linesLength); - - $terminalWidth = $this->terminal->getWidth(); - if ($linesWidth <= $terminalWidth) { - return $line; - } - - $this->setBarWidth($this->barWidth - $linesWidth + $terminalWidth); - - return preg_replace_callback($regex, $callback, $this->format); - } -} diff --git a/vendor/symfony/console/Helper/ProgressIndicator.php b/vendor/symfony/console/Helper/ProgressIndicator.php deleted file mode 100644 index 3482343fc..000000000 --- a/vendor/symfony/console/Helper/ProgressIndicator.php +++ /dev/null @@ -1,249 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\LogicException; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * @author Kevin Bond - */ -class ProgressIndicator -{ - private const FORMATS = [ - 'normal' => ' %indicator% %message%', - 'normal_no_ansi' => ' %message%', - - 'verbose' => ' %indicator% %message% (%elapsed:6s%)', - 'verbose_no_ansi' => ' %message% (%elapsed:6s%)', - - 'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)', - 'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)', - ]; - - private $output; - private $startTime; - private $format; - private $message; - private $indicatorValues; - private $indicatorCurrent; - private $indicatorChangeInterval; - private $indicatorUpdateTime; - private $started = false; - - /** - * @var array - */ - private static $formatters; - - /** - * @param int $indicatorChangeInterval Change interval in milliseconds - * @param array|null $indicatorValues Animated indicator characters - */ - public function __construct(OutputInterface $output, string $format = null, int $indicatorChangeInterval = 100, array $indicatorValues = null) - { - $this->output = $output; - - if (null === $format) { - $format = $this->determineBestFormat(); - } - - if (null === $indicatorValues) { - $indicatorValues = ['-', '\\', '|', '/']; - } - - $indicatorValues = array_values($indicatorValues); - - if (2 > \count($indicatorValues)) { - throw new InvalidArgumentException('Must have at least 2 indicator value characters.'); - } - - $this->format = self::getFormatDefinition($format); - $this->indicatorChangeInterval = $indicatorChangeInterval; - $this->indicatorValues = $indicatorValues; - $this->startTime = time(); - } - - /** - * Sets the current indicator message. - */ - public function setMessage(?string $message) - { - $this->message = $message; - - $this->display(); - } - - /** - * Starts the indicator output. - */ - public function start(string $message) - { - if ($this->started) { - throw new LogicException('Progress indicator already started.'); - } - - $this->message = $message; - $this->started = true; - $this->startTime = time(); - $this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval; - $this->indicatorCurrent = 0; - - $this->display(); - } - - /** - * Advances the indicator. - */ - public function advance() - { - if (!$this->started) { - throw new LogicException('Progress indicator has not yet been started.'); - } - - if (!$this->output->isDecorated()) { - return; - } - - $currentTime = $this->getCurrentTimeInMilliseconds(); - - if ($currentTime < $this->indicatorUpdateTime) { - return; - } - - $this->indicatorUpdateTime = $currentTime + $this->indicatorChangeInterval; - ++$this->indicatorCurrent; - - $this->display(); - } - - /** - * Finish the indicator with message. - * - * @param $message - */ - public function finish(string $message) - { - if (!$this->started) { - throw new LogicException('Progress indicator has not yet been started.'); - } - - $this->message = $message; - $this->display(); - $this->output->writeln(''); - $this->started = false; - } - - /** - * Gets the format for a given name. - * - * @return string|null - */ - public static function getFormatDefinition(string $name) - { - return self::FORMATS[$name] ?? null; - } - - /** - * Sets a placeholder formatter for a given name. - * - * This method also allow you to override an existing placeholder. - */ - public static function setPlaceholderFormatterDefinition(string $name, callable $callable) - { - if (!self::$formatters) { - self::$formatters = self::initPlaceholderFormatters(); - } - - self::$formatters[$name] = $callable; - } - - /** - * Gets the placeholder formatter for a given name (including the delimiter char like %). - * - * @return callable|null - */ - public static function getPlaceholderFormatterDefinition(string $name) - { - if (!self::$formatters) { - self::$formatters = self::initPlaceholderFormatters(); - } - - return self::$formatters[$name] ?? null; - } - - private function display() - { - if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) { - return; - } - - $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) { - if ($formatter = self::getPlaceholderFormatterDefinition($matches[1])) { - return $formatter($this); - } - - return $matches[0]; - }, $this->format ?? '')); - } - - private function determineBestFormat(): string - { - switch ($this->output->getVerbosity()) { - // OutputInterface::VERBOSITY_QUIET: display is disabled anyway - case OutputInterface::VERBOSITY_VERBOSE: - return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi'; - case OutputInterface::VERBOSITY_VERY_VERBOSE: - case OutputInterface::VERBOSITY_DEBUG: - return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi'; - default: - return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi'; - } - } - - /** - * Overwrites a previous message to the output. - */ - private function overwrite(string $message) - { - if ($this->output->isDecorated()) { - $this->output->write("\x0D\x1B[2K"); - $this->output->write($message); - } else { - $this->output->writeln($message); - } - } - - private function getCurrentTimeInMilliseconds(): float - { - return round(microtime(true) * 1000); - } - - private static function initPlaceholderFormatters(): array - { - return [ - 'indicator' => function (self $indicator) { - return $indicator->indicatorValues[$indicator->indicatorCurrent % \count($indicator->indicatorValues)]; - }, - 'message' => function (self $indicator) { - return $indicator->message; - }, - 'elapsed' => function (self $indicator) { - return Helper::formatTime(time() - $indicator->startTime); - }, - 'memory' => function () { - return Helper::formatMemory(memory_get_usage(true)); - }, - ]; - } -} diff --git a/vendor/symfony/console/Helper/QuestionHelper.php b/vendor/symfony/console/Helper/QuestionHelper.php deleted file mode 100644 index 10602038c..000000000 --- a/vendor/symfony/console/Helper/QuestionHelper.php +++ /dev/null @@ -1,616 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Cursor; -use Symfony\Component\Console\Exception\MissingInputException; -use Symfony\Component\Console\Exception\RuntimeException; -use Symfony\Component\Console\Formatter\OutputFormatter; -use Symfony\Component\Console\Formatter\OutputFormatterStyle; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\StreamableInputInterface; -use Symfony\Component\Console\Output\ConsoleOutputInterface; -use Symfony\Component\Console\Output\ConsoleSectionOutput; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Question\ChoiceQuestion; -use Symfony\Component\Console\Question\Question; -use Symfony\Component\Console\Terminal; - -use function Symfony\Component\String\s; - -/** - * The QuestionHelper class provides helpers to interact with the user. - * - * @author Fabien Potencier - */ -class QuestionHelper extends Helper -{ - /** - * @var resource|null - */ - private $inputStream; - - private static $stty = true; - private static $stdinIsInteractive; - - /** - * Asks a question to the user. - * - * @return mixed The user answer - * - * @throws RuntimeException If there is no data to read in the input stream - */ - public function ask(InputInterface $input, OutputInterface $output, Question $question) - { - if ($output instanceof ConsoleOutputInterface) { - $output = $output->getErrorOutput(); - } - - if (!$input->isInteractive()) { - return $this->getDefaultAnswer($question); - } - - if ($input instanceof StreamableInputInterface && $stream = $input->getStream()) { - $this->inputStream = $stream; - } - - try { - if (!$question->getValidator()) { - return $this->doAsk($output, $question); - } - - $interviewer = function () use ($output, $question) { - return $this->doAsk($output, $question); - }; - - return $this->validateAttempts($interviewer, $output, $question); - } catch (MissingInputException $exception) { - $input->setInteractive(false); - - if (null === $fallbackOutput = $this->getDefaultAnswer($question)) { - throw $exception; - } - - return $fallbackOutput; - } - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'question'; - } - - /** - * Prevents usage of stty. - */ - public static function disableStty() - { - self::$stty = false; - } - - /** - * Asks the question to the user. - * - * @return mixed - * - * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden - */ - private function doAsk(OutputInterface $output, Question $question) - { - $this->writePrompt($output, $question); - - $inputStream = $this->inputStream ?: \STDIN; - $autocomplete = $question->getAutocompleterCallback(); - - if (null === $autocomplete || !self::$stty || !Terminal::hasSttyAvailable()) { - $ret = false; - if ($question->isHidden()) { - try { - $hiddenResponse = $this->getHiddenResponse($output, $inputStream, $question->isTrimmable()); - $ret = $question->isTrimmable() ? trim($hiddenResponse) : $hiddenResponse; - } catch (RuntimeException $e) { - if (!$question->isHiddenFallback()) { - throw $e; - } - } - } - - if (false === $ret) { - $ret = $this->readInput($inputStream, $question); - if (false === $ret) { - throw new MissingInputException('Aborted.'); - } - if ($question->isTrimmable()) { - $ret = trim($ret); - } - } - } else { - $autocomplete = $this->autocomplete($output, $question, $inputStream, $autocomplete); - $ret = $question->isTrimmable() ? trim($autocomplete) : $autocomplete; - } - - if ($output instanceof ConsoleSectionOutput) { - $output->addContent($ret); - } - - $ret = \strlen($ret) > 0 ? $ret : $question->getDefault(); - - if ($normalizer = $question->getNormalizer()) { - return $normalizer($ret); - } - - return $ret; - } - - /** - * @return mixed - */ - private function getDefaultAnswer(Question $question) - { - $default = $question->getDefault(); - - if (null === $default) { - return $default; - } - - if ($validator = $question->getValidator()) { - return \call_user_func($question->getValidator(), $default); - } elseif ($question instanceof ChoiceQuestion) { - $choices = $question->getChoices(); - - if (!$question->isMultiselect()) { - return $choices[$default] ?? $default; - } - - $default = explode(',', $default); - foreach ($default as $k => $v) { - $v = $question->isTrimmable() ? trim($v) : $v; - $default[$k] = $choices[$v] ?? $v; - } - } - - return $default; - } - - /** - * Outputs the question prompt. - */ - protected function writePrompt(OutputInterface $output, Question $question) - { - $message = $question->getQuestion(); - - if ($question instanceof ChoiceQuestion) { - $output->writeln(array_merge([ - $question->getQuestion(), - ], $this->formatChoiceQuestionChoices($question, 'info'))); - - $message = $question->getPrompt(); - } - - $output->write($message); - } - - /** - * @return string[] - */ - protected function formatChoiceQuestionChoices(ChoiceQuestion $question, string $tag) - { - $messages = []; - - $maxWidth = max(array_map([__CLASS__, 'width'], array_keys($choices = $question->getChoices()))); - - foreach ($choices as $key => $value) { - $padding = str_repeat(' ', $maxWidth - self::width($key)); - - $messages[] = sprintf(" [<$tag>%s$padding] %s", $key, $value); - } - - return $messages; - } - - /** - * Outputs an error message. - */ - protected function writeError(OutputInterface $output, \Exception $error) - { - if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) { - $message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error'); - } else { - $message = ''.$error->getMessage().''; - } - - $output->writeln($message); - } - - /** - * Autocompletes a question. - * - * @param resource $inputStream - */ - private function autocomplete(OutputInterface $output, Question $question, $inputStream, callable $autocomplete): string - { - $cursor = new Cursor($output, $inputStream); - - $fullChoice = ''; - $ret = ''; - - $i = 0; - $ofs = -1; - $matches = $autocomplete($ret); - $numMatches = \count($matches); - - $sttyMode = shell_exec('stty -g'); - $isStdin = 'php://stdin' === (stream_get_meta_data($inputStream)['uri'] ?? null); - $r = [$inputStream]; - $w = []; - - // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead) - shell_exec('stty -icanon -echo'); - - // Add highlighted text style - $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white')); - - // Read a keypress - while (!feof($inputStream)) { - while ($isStdin && 0 === @stream_select($r, $w, $w, 0, 100)) { - // Give signal handlers a chance to run - $r = [$inputStream]; - } - $c = fread($inputStream, 1); - - // as opposed to fgets(), fread() returns an empty string when the stream content is empty, not false. - if (false === $c || ('' === $ret && '' === $c && null === $question->getDefault())) { - shell_exec('stty '.$sttyMode); - throw new MissingInputException('Aborted.'); - } elseif ("\177" === $c) { // Backspace Character - if (0 === $numMatches && 0 !== $i) { - --$i; - $cursor->moveLeft(s($fullChoice)->slice(-1)->width(false)); - - $fullChoice = self::substr($fullChoice, 0, $i); - } - - if (0 === $i) { - $ofs = -1; - $matches = $autocomplete($ret); - $numMatches = \count($matches); - } else { - $numMatches = 0; - } - - // Pop the last character off the end of our string - $ret = self::substr($ret, 0, $i); - } elseif ("\033" === $c) { - // Did we read an escape sequence? - $c .= fread($inputStream, 2); - - // A = Up Arrow. B = Down Arrow - if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) { - if ('A' === $c[2] && -1 === $ofs) { - $ofs = 0; - } - - if (0 === $numMatches) { - continue; - } - - $ofs += ('A' === $c[2]) ? -1 : 1; - $ofs = ($numMatches + $ofs) % $numMatches; - } - } elseif (\ord($c) < 32) { - if ("\t" === $c || "\n" === $c) { - if ($numMatches > 0 && -1 !== $ofs) { - $ret = (string) $matches[$ofs]; - // Echo out remaining chars for current match - $remainingCharacters = substr($ret, \strlen(trim($this->mostRecentlyEnteredValue($fullChoice)))); - $output->write($remainingCharacters); - $fullChoice .= $remainingCharacters; - $i = (false === $encoding = mb_detect_encoding($fullChoice, null, true)) ? \strlen($fullChoice) : mb_strlen($fullChoice, $encoding); - - $matches = array_filter( - $autocomplete($ret), - function ($match) use ($ret) { - return '' === $ret || str_starts_with($match, $ret); - } - ); - $numMatches = \count($matches); - $ofs = -1; - } - - if ("\n" === $c) { - $output->write($c); - break; - } - - $numMatches = 0; - } - - continue; - } else { - if ("\x80" <= $c) { - $c .= fread($inputStream, ["\xC0" => 1, "\xD0" => 1, "\xE0" => 2, "\xF0" => 3][$c & "\xF0"]); - } - - $output->write($c); - $ret .= $c; - $fullChoice .= $c; - ++$i; - - $tempRet = $ret; - - if ($question instanceof ChoiceQuestion && $question->isMultiselect()) { - $tempRet = $this->mostRecentlyEnteredValue($fullChoice); - } - - $numMatches = 0; - $ofs = 0; - - foreach ($autocomplete($ret) as $value) { - // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle) - if (str_starts_with($value, $tempRet)) { - $matches[$numMatches++] = $value; - } - } - } - - $cursor->clearLineAfter(); - - if ($numMatches > 0 && -1 !== $ofs) { - $cursor->savePosition(); - // Write highlighted text, complete the partially entered response - $charactersEntered = \strlen(trim($this->mostRecentlyEnteredValue($fullChoice))); - $output->write(''.OutputFormatter::escapeTrailingBackslash(substr($matches[$ofs], $charactersEntered)).''); - $cursor->restorePosition(); - } - } - - // Reset stty so it behaves normally again - shell_exec('stty '.$sttyMode); - - return $fullChoice; - } - - private function mostRecentlyEnteredValue(string $entered): string - { - // Determine the most recent value that the user entered - if (!str_contains($entered, ',')) { - return $entered; - } - - $choices = explode(',', $entered); - if ('' !== $lastChoice = trim($choices[\count($choices) - 1])) { - return $lastChoice; - } - - return $entered; - } - - /** - * Gets a hidden response from user. - * - * @param resource $inputStream The handler resource - * @param bool $trimmable Is the answer trimmable - * - * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden - */ - private function getHiddenResponse(OutputInterface $output, $inputStream, bool $trimmable = true): string - { - if ('\\' === \DIRECTORY_SEPARATOR) { - $exe = __DIR__.'/../Resources/bin/hiddeninput.exe'; - - // handle code running from a phar - if ('phar:' === substr(__FILE__, 0, 5)) { - $tmpExe = sys_get_temp_dir().'/hiddeninput.exe'; - copy($exe, $tmpExe); - $exe = $tmpExe; - } - - $sExec = shell_exec('"'.$exe.'"'); - $value = $trimmable ? rtrim($sExec) : $sExec; - $output->writeln(''); - - if (isset($tmpExe)) { - unlink($tmpExe); - } - - return $value; - } - - if (self::$stty && Terminal::hasSttyAvailable()) { - $sttyMode = shell_exec('stty -g'); - shell_exec('stty -echo'); - } elseif ($this->isInteractiveInput($inputStream)) { - throw new RuntimeException('Unable to hide the response.'); - } - - $value = fgets($inputStream, 4096); - - if (self::$stty && Terminal::hasSttyAvailable()) { - shell_exec('stty '.$sttyMode); - } - - if (false === $value) { - throw new MissingInputException('Aborted.'); - } - if ($trimmable) { - $value = trim($value); - } - $output->writeln(''); - - return $value; - } - - /** - * Validates an attempt. - * - * @param callable $interviewer A callable that will ask for a question and return the result - * - * @return mixed The validated response - * - * @throws \Exception In case the max number of attempts has been reached and no valid response has been given - */ - private function validateAttempts(callable $interviewer, OutputInterface $output, Question $question) - { - $error = null; - $attempts = $question->getMaxAttempts(); - - while (null === $attempts || $attempts--) { - if (null !== $error) { - $this->writeError($output, $error); - } - - try { - return $question->getValidator()($interviewer()); - } catch (RuntimeException $e) { - throw $e; - } catch (\Exception $error) { - } - } - - throw $error; - } - - private function isInteractiveInput($inputStream): bool - { - if ('php://stdin' !== (stream_get_meta_data($inputStream)['uri'] ?? null)) { - return false; - } - - if (null !== self::$stdinIsInteractive) { - return self::$stdinIsInteractive; - } - - if (\function_exists('stream_isatty')) { - return self::$stdinIsInteractive = @stream_isatty(fopen('php://stdin', 'r')); - } - - if (\function_exists('posix_isatty')) { - return self::$stdinIsInteractive = @posix_isatty(fopen('php://stdin', 'r')); - } - - if (!\function_exists('exec')) { - return self::$stdinIsInteractive = true; - } - - exec('stty 2> /dev/null', $output, $status); - - return self::$stdinIsInteractive = 1 !== $status; - } - - /** - * Reads one or more lines of input and returns what is read. - * - * @param resource $inputStream The handler resource - * @param Question $question The question being asked - * - * @return string|false The input received, false in case input could not be read - */ - private function readInput($inputStream, Question $question) - { - if (!$question->isMultiline()) { - $cp = $this->setIOCodepage(); - $ret = fgets($inputStream, 4096); - - return $this->resetIOCodepage($cp, $ret); - } - - $multiLineStreamReader = $this->cloneInputStream($inputStream); - if (null === $multiLineStreamReader) { - return false; - } - - $ret = ''; - $cp = $this->setIOCodepage(); - while (false !== ($char = fgetc($multiLineStreamReader))) { - if (\PHP_EOL === "{$ret}{$char}") { - break; - } - $ret .= $char; - } - - return $this->resetIOCodepage($cp, $ret); - } - - /** - * Sets console I/O to the host code page. - * - * @return int Previous code page in IBM/EBCDIC format - */ - private function setIOCodepage(): int - { - if (\function_exists('sapi_windows_cp_set')) { - $cp = sapi_windows_cp_get(); - sapi_windows_cp_set(sapi_windows_cp_get('oem')); - - return $cp; - } - - return 0; - } - - /** - * Sets console I/O to the specified code page and converts the user input. - * - * @param string|false $input - * - * @return string|false - */ - private function resetIOCodepage(int $cp, $input) - { - if (0 !== $cp) { - sapi_windows_cp_set($cp); - - if (false !== $input && '' !== $input) { - $input = sapi_windows_cp_conv(sapi_windows_cp_get('oem'), $cp, $input); - } - } - - return $input; - } - - /** - * Clones an input stream in order to act on one instance of the same - * stream without affecting the other instance. - * - * @param resource $inputStream The handler resource - * - * @return resource|null The cloned resource, null in case it could not be cloned - */ - private function cloneInputStream($inputStream) - { - $streamMetaData = stream_get_meta_data($inputStream); - $seekable = $streamMetaData['seekable'] ?? false; - $mode = $streamMetaData['mode'] ?? 'rb'; - $uri = $streamMetaData['uri'] ?? null; - - if (null === $uri) { - return null; - } - - $cloneStream = fopen($uri, $mode); - - // For seekable and writable streams, add all the same data to the - // cloned stream and then seek to the same offset. - if (true === $seekable && !\in_array($mode, ['r', 'rb', 'rt'])) { - $offset = ftell($inputStream); - rewind($inputStream); - stream_copy_to_stream($inputStream, $cloneStream); - fseek($inputStream, $offset); - fseek($cloneStream, $offset); - } - - return $cloneStream; - } -} diff --git a/vendor/symfony/console/Helper/SymfonyQuestionHelper.php b/vendor/symfony/console/Helper/SymfonyQuestionHelper.php deleted file mode 100644 index 01f94aba4..000000000 --- a/vendor/symfony/console/Helper/SymfonyQuestionHelper.php +++ /dev/null @@ -1,109 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Formatter\OutputFormatter; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Question\ChoiceQuestion; -use Symfony\Component\Console\Question\ConfirmationQuestion; -use Symfony\Component\Console\Question\Question; -use Symfony\Component\Console\Style\SymfonyStyle; - -/** - * Symfony Style Guide compliant question helper. - * - * @author Kevin Bond - */ -class SymfonyQuestionHelper extends QuestionHelper -{ - /** - * {@inheritdoc} - */ - protected function writePrompt(OutputInterface $output, Question $question) - { - $text = OutputFormatter::escapeTrailingBackslash($question->getQuestion()); - $default = $question->getDefault(); - - if ($question->isMultiline()) { - $text .= sprintf(' (press %s to continue)', $this->getEofShortcut()); - } - - switch (true) { - case null === $default: - $text = sprintf(' %s:', $text); - - break; - - case $question instanceof ConfirmationQuestion: - $text = sprintf(' %s (yes/no) [%s]:', $text, $default ? 'yes' : 'no'); - - break; - - case $question instanceof ChoiceQuestion && $question->isMultiselect(): - $choices = $question->getChoices(); - $default = explode(',', $default); - - foreach ($default as $key => $value) { - $default[$key] = $choices[trim($value)]; - } - - $text = sprintf(' %s [%s]:', $text, OutputFormatter::escape(implode(', ', $default))); - - break; - - case $question instanceof ChoiceQuestion: - $choices = $question->getChoices(); - $text = sprintf(' %s [%s]:', $text, OutputFormatter::escape($choices[$default] ?? $default)); - - break; - - default: - $text = sprintf(' %s [%s]:', $text, OutputFormatter::escape($default)); - } - - $output->writeln($text); - - $prompt = ' > '; - - if ($question instanceof ChoiceQuestion) { - $output->writeln($this->formatChoiceQuestionChoices($question, 'comment')); - - $prompt = $question->getPrompt(); - } - - $output->write($prompt); - } - - /** - * {@inheritdoc} - */ - protected function writeError(OutputInterface $output, \Exception $error) - { - if ($output instanceof SymfonyStyle) { - $output->newLine(); - $output->error($error->getMessage()); - - return; - } - - parent::writeError($output, $error); - } - - private function getEofShortcut(): string - { - if ('Windows' === \PHP_OS_FAMILY) { - return 'Ctrl+Z then Enter'; - } - - return 'Ctrl+D'; - } -} diff --git a/vendor/symfony/console/Helper/Table.php b/vendor/symfony/console/Helper/Table.php deleted file mode 100644 index 3f2d99145..000000000 --- a/vendor/symfony/console/Helper/Table.php +++ /dev/null @@ -1,915 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\RuntimeException; -use Symfony\Component\Console\Formatter\OutputFormatter; -use Symfony\Component\Console\Formatter\WrappableOutputFormatterInterface; -use Symfony\Component\Console\Output\ConsoleSectionOutput; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Provides helpers to display a table. - * - * @author Fabien Potencier - * @author Саша Стаменковић - * @author Abdellatif Ait boudad - * @author Max Grigorian - * @author Dany Maillard - */ -class Table -{ - private const SEPARATOR_TOP = 0; - private const SEPARATOR_TOP_BOTTOM = 1; - private const SEPARATOR_MID = 2; - private const SEPARATOR_BOTTOM = 3; - private const BORDER_OUTSIDE = 0; - private const BORDER_INSIDE = 1; - - private $headerTitle; - private $footerTitle; - - /** - * Table headers. - */ - private $headers = []; - - /** - * Table rows. - */ - private $rows = []; - private $horizontal = false; - - /** - * Column widths cache. - */ - private $effectiveColumnWidths = []; - - /** - * Number of columns cache. - * - * @var int - */ - private $numberOfColumns; - - /** - * @var OutputInterface - */ - private $output; - - /** - * @var TableStyle - */ - private $style; - - /** - * @var array - */ - private $columnStyles = []; - - /** - * User set column widths. - * - * @var array - */ - private $columnWidths = []; - private $columnMaxWidths = []; - - /** - * @var array|null - */ - private static $styles; - - private $rendered = false; - - public function __construct(OutputInterface $output) - { - $this->output = $output; - - if (!self::$styles) { - self::$styles = self::initStyles(); - } - - $this->setStyle('default'); - } - - /** - * Sets a style definition. - */ - public static function setStyleDefinition(string $name, TableStyle $style) - { - if (!self::$styles) { - self::$styles = self::initStyles(); - } - - self::$styles[$name] = $style; - } - - /** - * Gets a style definition by name. - * - * @return TableStyle - */ - public static function getStyleDefinition(string $name) - { - if (!self::$styles) { - self::$styles = self::initStyles(); - } - - if (isset(self::$styles[$name])) { - return self::$styles[$name]; - } - - throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name)); - } - - /** - * Sets table style. - * - * @param TableStyle|string $name The style name or a TableStyle instance - * - * @return $this - */ - public function setStyle($name) - { - $this->style = $this->resolveStyle($name); - - return $this; - } - - /** - * Gets the current table style. - * - * @return TableStyle - */ - public function getStyle() - { - return $this->style; - } - - /** - * Sets table column style. - * - * @param TableStyle|string $name The style name or a TableStyle instance - * - * @return $this - */ - public function setColumnStyle(int $columnIndex, $name) - { - $this->columnStyles[$columnIndex] = $this->resolveStyle($name); - - return $this; - } - - /** - * Gets the current style for a column. - * - * If style was not set, it returns the global table style. - * - * @return TableStyle - */ - public function getColumnStyle(int $columnIndex) - { - return $this->columnStyles[$columnIndex] ?? $this->getStyle(); - } - - /** - * Sets the minimum width of a column. - * - * @return $this - */ - public function setColumnWidth(int $columnIndex, int $width) - { - $this->columnWidths[$columnIndex] = $width; - - return $this; - } - - /** - * Sets the minimum width of all columns. - * - * @return $this - */ - public function setColumnWidths(array $widths) - { - $this->columnWidths = []; - foreach ($widths as $index => $width) { - $this->setColumnWidth($index, $width); - } - - return $this; - } - - /** - * Sets the maximum width of a column. - * - * Any cell within this column which contents exceeds the specified width will be wrapped into multiple lines, while - * formatted strings are preserved. - * - * @return $this - */ - public function setColumnMaxWidth(int $columnIndex, int $width): self - { - if (!$this->output->getFormatter() instanceof WrappableOutputFormatterInterface) { - throw new \LogicException(sprintf('Setting a maximum column width is only supported when using a "%s" formatter, got "%s".', WrappableOutputFormatterInterface::class, get_debug_type($this->output->getFormatter()))); - } - - $this->columnMaxWidths[$columnIndex] = $width; - - return $this; - } - - /** - * @return $this - */ - public function setHeaders(array $headers) - { - $headers = array_values($headers); - if (!empty($headers) && !\is_array($headers[0])) { - $headers = [$headers]; - } - - $this->headers = $headers; - - return $this; - } - - public function setRows(array $rows) - { - $this->rows = []; - - return $this->addRows($rows); - } - - /** - * @return $this - */ - public function addRows(array $rows) - { - foreach ($rows as $row) { - $this->addRow($row); - } - - return $this; - } - - /** - * @return $this - */ - public function addRow($row) - { - if ($row instanceof TableSeparator) { - $this->rows[] = $row; - - return $this; - } - - if (!\is_array($row)) { - throw new InvalidArgumentException('A row must be an array or a TableSeparator instance.'); - } - - $this->rows[] = array_values($row); - - return $this; - } - - /** - * Adds a row to the table, and re-renders the table. - * - * @return $this - */ - public function appendRow($row): self - { - if (!$this->output instanceof ConsoleSectionOutput) { - throw new RuntimeException(sprintf('Output should be an instance of "%s" when calling "%s".', ConsoleSectionOutput::class, __METHOD__)); - } - - if ($this->rendered) { - $this->output->clear($this->calculateRowCount()); - } - - $this->addRow($row); - $this->render(); - - return $this; - } - - /** - * @return $this - */ - public function setRow($column, array $row) - { - $this->rows[$column] = $row; - - return $this; - } - - /** - * @return $this - */ - public function setHeaderTitle(?string $title): self - { - $this->headerTitle = $title; - - return $this; - } - - /** - * @return $this - */ - public function setFooterTitle(?string $title): self - { - $this->footerTitle = $title; - - return $this; - } - - /** - * @return $this - */ - public function setHorizontal(bool $horizontal = true): self - { - $this->horizontal = $horizontal; - - return $this; - } - - /** - * Renders table to output. - * - * Example: - * - * +---------------+-----------------------+------------------+ - * | ISBN | Title | Author | - * +---------------+-----------------------+------------------+ - * | 99921-58-10-7 | Divine Comedy | Dante Alighieri | - * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | - * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | - * +---------------+-----------------------+------------------+ - */ - public function render() - { - $divider = new TableSeparator(); - if ($this->horizontal) { - $rows = []; - foreach ($this->headers[0] ?? [] as $i => $header) { - $rows[$i] = [$header]; - foreach ($this->rows as $row) { - if ($row instanceof TableSeparator) { - continue; - } - if (isset($row[$i])) { - $rows[$i][] = $row[$i]; - } elseif ($rows[$i][0] instanceof TableCell && $rows[$i][0]->getColspan() >= 2) { - // Noop, there is a "title" - } else { - $rows[$i][] = null; - } - } - } - } else { - $rows = array_merge($this->headers, [$divider], $this->rows); - } - - $this->calculateNumberOfColumns($rows); - - $rowGroups = $this->buildTableRows($rows); - $this->calculateColumnsWidth($rowGroups); - - $isHeader = !$this->horizontal; - $isFirstRow = $this->horizontal; - $hasTitle = (bool) $this->headerTitle; - - foreach ($rowGroups as $rowGroup) { - $isHeaderSeparatorRendered = false; - - foreach ($rowGroup as $row) { - if ($divider === $row) { - $isHeader = false; - $isFirstRow = true; - - continue; - } - - if ($row instanceof TableSeparator) { - $this->renderRowSeparator(); - - continue; - } - - if (!$row) { - continue; - } - - if ($isHeader && !$isHeaderSeparatorRendered) { - $this->renderRowSeparator( - $isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM, - $hasTitle ? $this->headerTitle : null, - $hasTitle ? $this->style->getHeaderTitleFormat() : null - ); - $hasTitle = false; - $isHeaderSeparatorRendered = true; - } - - if ($isFirstRow) { - $this->renderRowSeparator( - $isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM, - $hasTitle ? $this->headerTitle : null, - $hasTitle ? $this->style->getHeaderTitleFormat() : null - ); - $isFirstRow = false; - $hasTitle = false; - } - - if ($this->horizontal) { - $this->renderRow($row, $this->style->getCellRowFormat(), $this->style->getCellHeaderFormat()); - } else { - $this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat()); - } - } - } - $this->renderRowSeparator(self::SEPARATOR_BOTTOM, $this->footerTitle, $this->style->getFooterTitleFormat()); - - $this->cleanup(); - $this->rendered = true; - } - - /** - * Renders horizontal header separator. - * - * Example: - * - * +-----+-----------+-------+ - */ - private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $title = null, string $titleFormat = null) - { - if (0 === $count = $this->numberOfColumns) { - return; - } - - $borders = $this->style->getBorderChars(); - if (!$borders[0] && !$borders[2] && !$this->style->getCrossingChar()) { - return; - } - - $crossings = $this->style->getCrossingChars(); - if (self::SEPARATOR_MID === $type) { - [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[2], $crossings[8], $crossings[0], $crossings[4]]; - } elseif (self::SEPARATOR_TOP === $type) { - [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[1], $crossings[2], $crossings[3]]; - } elseif (self::SEPARATOR_TOP_BOTTOM === $type) { - [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[9], $crossings[10], $crossings[11]]; - } else { - [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[7], $crossings[6], $crossings[5]]; - } - - $markup = $leftChar; - for ($column = 0; $column < $count; ++$column) { - $markup .= str_repeat($horizontal, $this->effectiveColumnWidths[$column]); - $markup .= $column === $count - 1 ? $rightChar : $midChar; - } - - if (null !== $title) { - $titleLength = Helper::width(Helper::removeDecoration($formatter = $this->output->getFormatter(), $formattedTitle = sprintf($titleFormat, $title))); - $markupLength = Helper::width($markup); - if ($titleLength > $limit = $markupLength - 4) { - $titleLength = $limit; - $formatLength = Helper::width(Helper::removeDecoration($formatter, sprintf($titleFormat, ''))); - $formattedTitle = sprintf($titleFormat, Helper::substr($title, 0, $limit - $formatLength - 3).'...'); - } - - $titleStart = intdiv($markupLength - $titleLength, 2); - if (false === mb_detect_encoding($markup, null, true)) { - $markup = substr_replace($markup, $formattedTitle, $titleStart, $titleLength); - } else { - $markup = mb_substr($markup, 0, $titleStart).$formattedTitle.mb_substr($markup, $titleStart + $titleLength); - } - } - - $this->output->writeln(sprintf($this->style->getBorderFormat(), $markup)); - } - - /** - * Renders vertical column separator. - */ - private function renderColumnSeparator(int $type = self::BORDER_OUTSIDE): string - { - $borders = $this->style->getBorderChars(); - - return sprintf($this->style->getBorderFormat(), self::BORDER_OUTSIDE === $type ? $borders[1] : $borders[3]); - } - - /** - * Renders table row. - * - * Example: - * - * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | - */ - private function renderRow(array $row, string $cellFormat, string $firstCellFormat = null) - { - $rowContent = $this->renderColumnSeparator(self::BORDER_OUTSIDE); - $columns = $this->getRowColumns($row); - $last = \count($columns) - 1; - foreach ($columns as $i => $column) { - if ($firstCellFormat && 0 === $i) { - $rowContent .= $this->renderCell($row, $column, $firstCellFormat); - } else { - $rowContent .= $this->renderCell($row, $column, $cellFormat); - } - $rowContent .= $this->renderColumnSeparator($last === $i ? self::BORDER_OUTSIDE : self::BORDER_INSIDE); - } - $this->output->writeln($rowContent); - } - - /** - * Renders table cell with padding. - */ - private function renderCell(array $row, int $column, string $cellFormat): string - { - $cell = $row[$column] ?? ''; - $width = $this->effectiveColumnWidths[$column]; - if ($cell instanceof TableCell && $cell->getColspan() > 1) { - // add the width of the following columns(numbers of colspan). - foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) { - $width += $this->getColumnSeparatorWidth() + $this->effectiveColumnWidths[$nextColumn]; - } - } - - // str_pad won't work properly with multi-byte strings, we need to fix the padding - if (false !== $encoding = mb_detect_encoding($cell, null, true)) { - $width += \strlen($cell) - mb_strwidth($cell, $encoding); - } - - $style = $this->getColumnStyle($column); - - if ($cell instanceof TableSeparator) { - return sprintf($style->getBorderFormat(), str_repeat($style->getBorderChars()[2], $width)); - } - - $width += Helper::length($cell) - Helper::length(Helper::removeDecoration($this->output->getFormatter(), $cell)); - $content = sprintf($style->getCellRowContentFormat(), $cell); - - $padType = $style->getPadType(); - if ($cell instanceof TableCell && $cell->getStyle() instanceof TableCellStyle) { - $isNotStyledByTag = !preg_match('/^<(\w+|(\w+=[\w,]+;?)*)>.+<\/(\w+|(\w+=\w+;?)*)?>$/', $cell); - if ($isNotStyledByTag) { - $cellFormat = $cell->getStyle()->getCellFormat(); - if (!\is_string($cellFormat)) { - $tag = http_build_query($cell->getStyle()->getTagOptions(), '', ';'); - $cellFormat = '<'.$tag.'>%s'; - } - - if (strstr($content, '')) { - $content = str_replace('', '', $content); - $width -= 3; - } - if (strstr($content, '')) { - $content = str_replace('', '', $content); - $width -= \strlen(''); - } - } - - $padType = $cell->getStyle()->getPadByAlign(); - } - - return sprintf($cellFormat, str_pad($content, $width, $style->getPaddingChar(), $padType)); - } - - /** - * Calculate number of columns for this table. - */ - private function calculateNumberOfColumns(array $rows) - { - $columns = [0]; - foreach ($rows as $row) { - if ($row instanceof TableSeparator) { - continue; - } - - $columns[] = $this->getNumberOfColumns($row); - } - - $this->numberOfColumns = max($columns); - } - - private function buildTableRows(array $rows): TableRows - { - /** @var WrappableOutputFormatterInterface $formatter */ - $formatter = $this->output->getFormatter(); - $unmergedRows = []; - for ($rowKey = 0; $rowKey < \count($rows); ++$rowKey) { - $rows = $this->fillNextRows($rows, $rowKey); - - // Remove any new line breaks and replace it with a new line - foreach ($rows[$rowKey] as $column => $cell) { - $colspan = $cell instanceof TableCell ? $cell->getColspan() : 1; - - if (isset($this->columnMaxWidths[$column]) && Helper::width(Helper::removeDecoration($formatter, $cell)) > $this->columnMaxWidths[$column]) { - $cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan); - } - if (!strstr($cell ?? '', "\n")) { - continue; - } - $escaped = implode("\n", array_map([OutputFormatter::class, 'escapeTrailingBackslash'], explode("\n", $cell))); - $cell = $cell instanceof TableCell ? new TableCell($escaped, ['colspan' => $cell->getColspan()]) : $escaped; - $lines = explode("\n", str_replace("\n", "\n", $cell)); - foreach ($lines as $lineKey => $line) { - if ($colspan > 1) { - $line = new TableCell($line, ['colspan' => $colspan]); - } - if (0 === $lineKey) { - $rows[$rowKey][$column] = $line; - } else { - if (!\array_key_exists($rowKey, $unmergedRows) || !\array_key_exists($lineKey, $unmergedRows[$rowKey])) { - $unmergedRows[$rowKey][$lineKey] = $this->copyRow($rows, $rowKey); - } - $unmergedRows[$rowKey][$lineKey][$column] = $line; - } - } - } - } - - return new TableRows(function () use ($rows, $unmergedRows): \Traversable { - foreach ($rows as $rowKey => $row) { - $rowGroup = [$row instanceof TableSeparator ? $row : $this->fillCells($row)]; - - if (isset($unmergedRows[$rowKey])) { - foreach ($unmergedRows[$rowKey] as $row) { - $rowGroup[] = $row instanceof TableSeparator ? $row : $this->fillCells($row); - } - } - yield $rowGroup; - } - }); - } - - private function calculateRowCount(): int - { - $numberOfRows = \count(iterator_to_array($this->buildTableRows(array_merge($this->headers, [new TableSeparator()], $this->rows)))); - - if ($this->headers) { - ++$numberOfRows; // Add row for header separator - } - - if (\count($this->rows) > 0) { - ++$numberOfRows; // Add row for footer separator - } - - return $numberOfRows; - } - - /** - * fill rows that contains rowspan > 1. - * - * @throws InvalidArgumentException - */ - private function fillNextRows(array $rows, int $line): array - { - $unmergedRows = []; - foreach ($rows[$line] as $column => $cell) { - if (null !== $cell && !$cell instanceof TableCell && !\is_scalar($cell) && !(\is_object($cell) && method_exists($cell, '__toString'))) { - throw new InvalidArgumentException(sprintf('A cell must be a TableCell, a scalar or an object implementing "__toString()", "%s" given.', get_debug_type($cell))); - } - if ($cell instanceof TableCell && $cell->getRowspan() > 1) { - $nbLines = $cell->getRowspan() - 1; - $lines = [$cell]; - if (strstr($cell, "\n")) { - $lines = explode("\n", str_replace("\n", "\n", $cell)); - $nbLines = \count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines; - - $rows[$line][$column] = new TableCell($lines[0], ['colspan' => $cell->getColspan(), 'style' => $cell->getStyle()]); - unset($lines[0]); - } - - // create a two dimensional array (rowspan x colspan) - $unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, []), $unmergedRows); - foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { - $value = $lines[$unmergedRowKey - $line] ?? ''; - $unmergedRows[$unmergedRowKey][$column] = new TableCell($value, ['colspan' => $cell->getColspan(), 'style' => $cell->getStyle()]); - if ($nbLines === $unmergedRowKey - $line) { - break; - } - } - } - } - - foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { - // we need to know if $unmergedRow will be merged or inserted into $rows - if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) { - foreach ($unmergedRow as $cellKey => $cell) { - // insert cell into row at cellKey position - array_splice($rows[$unmergedRowKey], $cellKey, 0, [$cell]); - } - } else { - $row = $this->copyRow($rows, $unmergedRowKey - 1); - foreach ($unmergedRow as $column => $cell) { - if (!empty($cell)) { - $row[$column] = $unmergedRow[$column]; - } - } - array_splice($rows, $unmergedRowKey, 0, [$row]); - } - } - - return $rows; - } - - /** - * fill cells for a row that contains colspan > 1. - */ - private function fillCells(iterable $row) - { - $newRow = []; - - foreach ($row as $column => $cell) { - $newRow[] = $cell; - if ($cell instanceof TableCell && $cell->getColspan() > 1) { - foreach (range($column + 1, $column + $cell->getColspan() - 1) as $position) { - // insert empty value at column position - $newRow[] = ''; - } - } - } - - return $newRow ?: $row; - } - - private function copyRow(array $rows, int $line): array - { - $row = $rows[$line]; - foreach ($row as $cellKey => $cellValue) { - $row[$cellKey] = ''; - if ($cellValue instanceof TableCell) { - $row[$cellKey] = new TableCell('', ['colspan' => $cellValue->getColspan()]); - } - } - - return $row; - } - - /** - * Gets number of columns by row. - */ - private function getNumberOfColumns(array $row): int - { - $columns = \count($row); - foreach ($row as $column) { - $columns += $column instanceof TableCell ? ($column->getColspan() - 1) : 0; - } - - return $columns; - } - - /** - * Gets list of columns for the given row. - */ - private function getRowColumns(array $row): array - { - $columns = range(0, $this->numberOfColumns - 1); - foreach ($row as $cellKey => $cell) { - if ($cell instanceof TableCell && $cell->getColspan() > 1) { - // exclude grouped columns. - $columns = array_diff($columns, range($cellKey + 1, $cellKey + $cell->getColspan() - 1)); - } - } - - return $columns; - } - - /** - * Calculates columns widths. - */ - private function calculateColumnsWidth(iterable $groups) - { - for ($column = 0; $column < $this->numberOfColumns; ++$column) { - $lengths = []; - foreach ($groups as $group) { - foreach ($group as $row) { - if ($row instanceof TableSeparator) { - continue; - } - - foreach ($row as $i => $cell) { - if ($cell instanceof TableCell) { - $textContent = Helper::removeDecoration($this->output->getFormatter(), $cell); - $textLength = Helper::width($textContent); - if ($textLength > 0) { - $contentColumns = str_split($textContent, ceil($textLength / $cell->getColspan())); - foreach ($contentColumns as $position => $content) { - $row[$i + $position] = $content; - } - } - } - } - - $lengths[] = $this->getCellWidth($row, $column); - } - } - - $this->effectiveColumnWidths[$column] = max($lengths) + Helper::width($this->style->getCellRowContentFormat()) - 2; - } - } - - private function getColumnSeparatorWidth(): int - { - return Helper::width(sprintf($this->style->getBorderFormat(), $this->style->getBorderChars()[3])); - } - - private function getCellWidth(array $row, int $column): int - { - $cellWidth = 0; - - if (isset($row[$column])) { - $cell = $row[$column]; - $cellWidth = Helper::width(Helper::removeDecoration($this->output->getFormatter(), $cell)); - } - - $columnWidth = $this->columnWidths[$column] ?? 0; - $cellWidth = max($cellWidth, $columnWidth); - - return isset($this->columnMaxWidths[$column]) ? min($this->columnMaxWidths[$column], $cellWidth) : $cellWidth; - } - - /** - * Called after rendering to cleanup cache data. - */ - private function cleanup() - { - $this->effectiveColumnWidths = []; - $this->numberOfColumns = null; - } - - /** - * @return array - */ - private static function initStyles(): array - { - $borderless = new TableStyle(); - $borderless - ->setHorizontalBorderChars('=') - ->setVerticalBorderChars(' ') - ->setDefaultCrossingChar(' ') - ; - - $compact = new TableStyle(); - $compact - ->setHorizontalBorderChars('') - ->setVerticalBorderChars('') - ->setDefaultCrossingChar('') - ->setCellRowContentFormat('%s ') - ; - - $styleGuide = new TableStyle(); - $styleGuide - ->setHorizontalBorderChars('-') - ->setVerticalBorderChars(' ') - ->setDefaultCrossingChar(' ') - ->setCellHeaderFormat('%s') - ; - - $box = (new TableStyle()) - ->setHorizontalBorderChars('─') - ->setVerticalBorderChars('│') - ->setCrossingChars('┼', '┌', '┬', '┐', '┤', '┘', '┴', '└', '├') - ; - - $boxDouble = (new TableStyle()) - ->setHorizontalBorderChars('═', '─') - ->setVerticalBorderChars('║', '│') - ->setCrossingChars('┼', '╔', '╤', '╗', '╢', '╝', '╧', '╚', '╟', '╠', '╪', '╣') - ; - - return [ - 'default' => new TableStyle(), - 'borderless' => $borderless, - 'compact' => $compact, - 'symfony-style-guide' => $styleGuide, - 'box' => $box, - 'box-double' => $boxDouble, - ]; - } - - private function resolveStyle($name): TableStyle - { - if ($name instanceof TableStyle) { - return $name; - } - - if (isset(self::$styles[$name])) { - return self::$styles[$name]; - } - - throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name)); - } -} diff --git a/vendor/symfony/console/Helper/TableCell.php b/vendor/symfony/console/Helper/TableCell.php deleted file mode 100644 index 1a7bc6ede..000000000 --- a/vendor/symfony/console/Helper/TableCell.php +++ /dev/null @@ -1,78 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Exception\InvalidArgumentException; - -/** - * @author Abdellatif Ait boudad - */ -class TableCell -{ - private $value; - private $options = [ - 'rowspan' => 1, - 'colspan' => 1, - 'style' => null, - ]; - - public function __construct(string $value = '', array $options = []) - { - $this->value = $value; - - // check option names - if ($diff = array_diff(array_keys($options), array_keys($this->options))) { - throw new InvalidArgumentException(sprintf('The TableCell does not support the following options: \'%s\'.', implode('\', \'', $diff))); - } - - if (isset($options['style']) && !$options['style'] instanceof TableCellStyle) { - throw new InvalidArgumentException('The style option must be an instance of "TableCellStyle".'); - } - - $this->options = array_merge($this->options, $options); - } - - /** - * Returns the cell value. - * - * @return string - */ - public function __toString() - { - return $this->value; - } - - /** - * Gets number of colspan. - * - * @return int - */ - public function getColspan() - { - return (int) $this->options['colspan']; - } - - /** - * Gets number of rowspan. - * - * @return int - */ - public function getRowspan() - { - return (int) $this->options['rowspan']; - } - - public function getStyle(): ?TableCellStyle - { - return $this->options['style']; - } -} diff --git a/vendor/symfony/console/Helper/TableCellStyle.php b/vendor/symfony/console/Helper/TableCellStyle.php deleted file mode 100644 index 19cd0ffc6..000000000 --- a/vendor/symfony/console/Helper/TableCellStyle.php +++ /dev/null @@ -1,89 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Exception\InvalidArgumentException; - -/** - * @author Yewhen Khoptynskyi - */ -class TableCellStyle -{ - public const DEFAULT_ALIGN = 'left'; - - private const TAG_OPTIONS = [ - 'fg', - 'bg', - 'options', - ]; - - private const ALIGN_MAP = [ - 'left' => \STR_PAD_RIGHT, - 'center' => \STR_PAD_BOTH, - 'right' => \STR_PAD_LEFT, - ]; - - private $options = [ - 'fg' => 'default', - 'bg' => 'default', - 'options' => null, - 'align' => self::DEFAULT_ALIGN, - 'cellFormat' => null, - ]; - - public function __construct(array $options = []) - { - if ($diff = array_diff(array_keys($options), array_keys($this->options))) { - throw new InvalidArgumentException(sprintf('The TableCellStyle does not support the following options: \'%s\'.', implode('\', \'', $diff))); - } - - if (isset($options['align']) && !\array_key_exists($options['align'], self::ALIGN_MAP)) { - throw new InvalidArgumentException(sprintf('Wrong align value. Value must be following: \'%s\'.', implode('\', \'', array_keys(self::ALIGN_MAP)))); - } - - $this->options = array_merge($this->options, $options); - } - - public function getOptions(): array - { - return $this->options; - } - - /** - * Gets options we need for tag for example fg, bg. - * - * @return string[] - */ - public function getTagOptions() - { - return array_filter( - $this->getOptions(), - function ($key) { - return \in_array($key, self::TAG_OPTIONS) && isset($this->options[$key]); - }, - \ARRAY_FILTER_USE_KEY - ); - } - - /** - * @return int - */ - public function getPadByAlign() - { - return self::ALIGN_MAP[$this->getOptions()['align']]; - } - - public function getCellFormat(): ?string - { - return $this->getOptions()['cellFormat']; - } -} diff --git a/vendor/symfony/console/Helper/TableRows.php b/vendor/symfony/console/Helper/TableRows.php deleted file mode 100644 index cbc07d294..000000000 --- a/vendor/symfony/console/Helper/TableRows.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -/** - * @internal - */ -class TableRows implements \IteratorAggregate -{ - private $generator; - - public function __construct(\Closure $generator) - { - $this->generator = $generator; - } - - public function getIterator(): \Traversable - { - return ($this->generator)(); - } -} diff --git a/vendor/symfony/console/Helper/TableSeparator.php b/vendor/symfony/console/Helper/TableSeparator.php deleted file mode 100644 index e541c5315..000000000 --- a/vendor/symfony/console/Helper/TableSeparator.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -/** - * Marks a row as being a separator. - * - * @author Fabien Potencier - */ -class TableSeparator extends TableCell -{ - public function __construct(array $options = []) - { - parent::__construct('', $options); - } -} diff --git a/vendor/symfony/console/Helper/TableStyle.php b/vendor/symfony/console/Helper/TableStyle.php deleted file mode 100644 index dfc41e6a4..000000000 --- a/vendor/symfony/console/Helper/TableStyle.php +++ /dev/null @@ -1,376 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\LogicException; - -/** - * Defines the styles for a Table. - * - * @author Fabien Potencier - * @author Саша Стаменковић - * @author Dany Maillard - */ -class TableStyle -{ - private $paddingChar = ' '; - private $horizontalOutsideBorderChar = '-'; - private $horizontalInsideBorderChar = '-'; - private $verticalOutsideBorderChar = '|'; - private $verticalInsideBorderChar = '|'; - private $crossingChar = '+'; - private $crossingTopRightChar = '+'; - private $crossingTopMidChar = '+'; - private $crossingTopLeftChar = '+'; - private $crossingMidRightChar = '+'; - private $crossingBottomRightChar = '+'; - private $crossingBottomMidChar = '+'; - private $crossingBottomLeftChar = '+'; - private $crossingMidLeftChar = '+'; - private $crossingTopLeftBottomChar = '+'; - private $crossingTopMidBottomChar = '+'; - private $crossingTopRightBottomChar = '+'; - private $headerTitleFormat = ' %s '; - private $footerTitleFormat = ' %s '; - private $cellHeaderFormat = '%s'; - private $cellRowFormat = '%s'; - private $cellRowContentFormat = ' %s '; - private $borderFormat = '%s'; - private $padType = \STR_PAD_RIGHT; - - /** - * Sets padding character, used for cell padding. - * - * @return $this - */ - public function setPaddingChar(string $paddingChar) - { - if (!$paddingChar) { - throw new LogicException('The padding char must not be empty.'); - } - - $this->paddingChar = $paddingChar; - - return $this; - } - - /** - * Gets padding character, used for cell padding. - * - * @return string - */ - public function getPaddingChar() - { - return $this->paddingChar; - } - - /** - * Sets horizontal border characters. - * - * - * ╔═══════════════╤══════════════════════════╤══════════════════╗ - * 1 ISBN 2 Title │ Author ║ - * ╠═══════════════╪══════════════════════════╪══════════════════╣ - * ║ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri ║ - * ║ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens ║ - * ║ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien ║ - * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie ║ - * ╚═══════════════╧══════════════════════════╧══════════════════╝ - * - * - * @return $this - */ - public function setHorizontalBorderChars(string $outside, string $inside = null): self - { - $this->horizontalOutsideBorderChar = $outside; - $this->horizontalInsideBorderChar = $inside ?? $outside; - - return $this; - } - - /** - * Sets vertical border characters. - * - * - * ╔═══════════════╤══════════════════════════╤══════════════════╗ - * ║ ISBN │ Title │ Author ║ - * ╠═══════1═══════╪══════════════════════════╪══════════════════╣ - * ║ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri ║ - * ║ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens ║ - * ╟───────2───────┼──────────────────────────┼──────────────────╢ - * ║ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien ║ - * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie ║ - * ╚═══════════════╧══════════════════════════╧══════════════════╝ - * - * - * @return $this - */ - public function setVerticalBorderChars(string $outside, string $inside = null): self - { - $this->verticalOutsideBorderChar = $outside; - $this->verticalInsideBorderChar = $inside ?? $outside; - - return $this; - } - - /** - * Gets border characters. - * - * @internal - */ - public function getBorderChars(): array - { - return [ - $this->horizontalOutsideBorderChar, - $this->verticalOutsideBorderChar, - $this->horizontalInsideBorderChar, - $this->verticalInsideBorderChar, - ]; - } - - /** - * Sets crossing characters. - * - * Example: - * - * 1═══════════════2══════════════════════════2══════════════════3 - * ║ ISBN │ Title │ Author ║ - * 8'══════════════0'═════════════════════════0'═════════════════4' - * ║ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri ║ - * ║ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens ║ - * 8───────────────0──────────────────────────0──────────────────4 - * ║ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien ║ - * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie ║ - * 7═══════════════6══════════════════════════6══════════════════5 - * - * - * @param string $cross Crossing char (see #0 of example) - * @param string $topLeft Top left char (see #1 of example) - * @param string $topMid Top mid char (see #2 of example) - * @param string $topRight Top right char (see #3 of example) - * @param string $midRight Mid right char (see #4 of example) - * @param string $bottomRight Bottom right char (see #5 of example) - * @param string $bottomMid Bottom mid char (see #6 of example) - * @param string $bottomLeft Bottom left char (see #7 of example) - * @param string $midLeft Mid left char (see #8 of example) - * @param string|null $topLeftBottom Top left bottom char (see #8' of example), equals to $midLeft if null - * @param string|null $topMidBottom Top mid bottom char (see #0' of example), equals to $cross if null - * @param string|null $topRightBottom Top right bottom char (see #4' of example), equals to $midRight if null - * - * @return $this - */ - public function setCrossingChars(string $cross, string $topLeft, string $topMid, string $topRight, string $midRight, string $bottomRight, string $bottomMid, string $bottomLeft, string $midLeft, string $topLeftBottom = null, string $topMidBottom = null, string $topRightBottom = null): self - { - $this->crossingChar = $cross; - $this->crossingTopLeftChar = $topLeft; - $this->crossingTopMidChar = $topMid; - $this->crossingTopRightChar = $topRight; - $this->crossingMidRightChar = $midRight; - $this->crossingBottomRightChar = $bottomRight; - $this->crossingBottomMidChar = $bottomMid; - $this->crossingBottomLeftChar = $bottomLeft; - $this->crossingMidLeftChar = $midLeft; - $this->crossingTopLeftBottomChar = $topLeftBottom ?? $midLeft; - $this->crossingTopMidBottomChar = $topMidBottom ?? $cross; - $this->crossingTopRightBottomChar = $topRightBottom ?? $midRight; - - return $this; - } - - /** - * Sets default crossing character used for each cross. - * - * @see {@link setCrossingChars()} for setting each crossing individually. - */ - public function setDefaultCrossingChar(string $char): self - { - return $this->setCrossingChars($char, $char, $char, $char, $char, $char, $char, $char, $char); - } - - /** - * Gets crossing character. - * - * @return string - */ - public function getCrossingChar() - { - return $this->crossingChar; - } - - /** - * Gets crossing characters. - * - * @internal - */ - public function getCrossingChars(): array - { - return [ - $this->crossingChar, - $this->crossingTopLeftChar, - $this->crossingTopMidChar, - $this->crossingTopRightChar, - $this->crossingMidRightChar, - $this->crossingBottomRightChar, - $this->crossingBottomMidChar, - $this->crossingBottomLeftChar, - $this->crossingMidLeftChar, - $this->crossingTopLeftBottomChar, - $this->crossingTopMidBottomChar, - $this->crossingTopRightBottomChar, - ]; - } - - /** - * Sets header cell format. - * - * @return $this - */ - public function setCellHeaderFormat(string $cellHeaderFormat) - { - $this->cellHeaderFormat = $cellHeaderFormat; - - return $this; - } - - /** - * Gets header cell format. - * - * @return string - */ - public function getCellHeaderFormat() - { - return $this->cellHeaderFormat; - } - - /** - * Sets row cell format. - * - * @return $this - */ - public function setCellRowFormat(string $cellRowFormat) - { - $this->cellRowFormat = $cellRowFormat; - - return $this; - } - - /** - * Gets row cell format. - * - * @return string - */ - public function getCellRowFormat() - { - return $this->cellRowFormat; - } - - /** - * Sets row cell content format. - * - * @return $this - */ - public function setCellRowContentFormat(string $cellRowContentFormat) - { - $this->cellRowContentFormat = $cellRowContentFormat; - - return $this; - } - - /** - * Gets row cell content format. - * - * @return string - */ - public function getCellRowContentFormat() - { - return $this->cellRowContentFormat; - } - - /** - * Sets table border format. - * - * @return $this - */ - public function setBorderFormat(string $borderFormat) - { - $this->borderFormat = $borderFormat; - - return $this; - } - - /** - * Gets table border format. - * - * @return string - */ - public function getBorderFormat() - { - return $this->borderFormat; - } - - /** - * Sets cell padding type. - * - * @return $this - */ - public function setPadType(int $padType) - { - if (!\in_array($padType, [\STR_PAD_LEFT, \STR_PAD_RIGHT, \STR_PAD_BOTH], true)) { - throw new InvalidArgumentException('Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH).'); - } - - $this->padType = $padType; - - return $this; - } - - /** - * Gets cell padding type. - * - * @return int - */ - public function getPadType() - { - return $this->padType; - } - - public function getHeaderTitleFormat(): string - { - return $this->headerTitleFormat; - } - - /** - * @return $this - */ - public function setHeaderTitleFormat(string $format): self - { - $this->headerTitleFormat = $format; - - return $this; - } - - public function getFooterTitleFormat(): string - { - return $this->footerTitleFormat; - } - - /** - * @return $this - */ - public function setFooterTitleFormat(string $format): self - { - $this->footerTitleFormat = $format; - - return $this; - } -} diff --git a/vendor/symfony/console/Input/ArgvInput.php b/vendor/symfony/console/Input/ArgvInput.php deleted file mode 100644 index 675b9ef58..000000000 --- a/vendor/symfony/console/Input/ArgvInput.php +++ /dev/null @@ -1,378 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -use Symfony\Component\Console\Exception\RuntimeException; - -/** - * ArgvInput represents an input coming from the CLI arguments. - * - * Usage: - * - * $input = new ArgvInput(); - * - * By default, the `$_SERVER['argv']` array is used for the input values. - * - * This can be overridden by explicitly passing the input values in the constructor: - * - * $input = new ArgvInput($_SERVER['argv']); - * - * If you pass it yourself, don't forget that the first element of the array - * is the name of the running application. - * - * When passing an argument to the constructor, be sure that it respects - * the same rules as the argv one. It's almost always better to use the - * `StringInput` when you want to provide your own input. - * - * @author Fabien Potencier - * - * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html - * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02 - */ -class ArgvInput extends Input -{ - private $tokens; - private $parsed; - - public function __construct(array $argv = null, InputDefinition $definition = null) - { - $argv = $argv ?? $_SERVER['argv'] ?? []; - - // strip the application name - array_shift($argv); - - $this->tokens = $argv; - - parent::__construct($definition); - } - - protected function setTokens(array $tokens) - { - $this->tokens = $tokens; - } - - /** - * {@inheritdoc} - */ - protected function parse() - { - $parseOptions = true; - $this->parsed = $this->tokens; - while (null !== $token = array_shift($this->parsed)) { - $parseOptions = $this->parseToken($token, $parseOptions); - } - } - - protected function parseToken(string $token, bool $parseOptions): bool - { - if ($parseOptions && '' == $token) { - $this->parseArgument($token); - } elseif ($parseOptions && '--' == $token) { - return false; - } elseif ($parseOptions && str_starts_with($token, '--')) { - $this->parseLongOption($token); - } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) { - $this->parseShortOption($token); - } else { - $this->parseArgument($token); - } - - return $parseOptions; - } - - /** - * Parses a short option. - */ - private function parseShortOption(string $token) - { - $name = substr($token, 1); - - if (\strlen($name) > 1) { - if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) { - // an option with a value (with no space) - $this->addShortOption($name[0], substr($name, 1)); - } else { - $this->parseShortOptionSet($name); - } - } else { - $this->addShortOption($name, null); - } - } - - /** - * Parses a short option set. - * - * @throws RuntimeException When option given doesn't exist - */ - private function parseShortOptionSet(string $name) - { - $len = \strlen($name); - for ($i = 0; $i < $len; ++$i) { - if (!$this->definition->hasShortcut($name[$i])) { - $encoding = mb_detect_encoding($name, null, true); - throw new RuntimeException(sprintf('The "-%s" option does not exist.', false === $encoding ? $name[$i] : mb_substr($name, $i, 1, $encoding))); - } - - $option = $this->definition->getOptionForShortcut($name[$i]); - if ($option->acceptValue()) { - $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1)); - - break; - } else { - $this->addLongOption($option->getName(), null); - } - } - } - - /** - * Parses a long option. - */ - private function parseLongOption(string $token) - { - $name = substr($token, 2); - - if (false !== $pos = strpos($name, '=')) { - if ('' === $value = substr($name, $pos + 1)) { - array_unshift($this->parsed, $value); - } - $this->addLongOption(substr($name, 0, $pos), $value); - } else { - $this->addLongOption($name, null); - } - } - - /** - * Parses an argument. - * - * @throws RuntimeException When too many arguments are given - */ - private function parseArgument(string $token) - { - $c = \count($this->arguments); - - // if input is expecting another argument, add it - if ($this->definition->hasArgument($c)) { - $arg = $this->definition->getArgument($c); - $this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token; - - // if last argument isArray(), append token to last argument - } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) { - $arg = $this->definition->getArgument($c - 1); - $this->arguments[$arg->getName()][] = $token; - - // unexpected argument - } else { - $all = $this->definition->getArguments(); - $symfonyCommandName = null; - if (($inputArgument = $all[$key = array_key_first($all)] ?? null) && 'command' === $inputArgument->getName()) { - $symfonyCommandName = $this->arguments['command'] ?? null; - unset($all[$key]); - } - - if (\count($all)) { - if ($symfonyCommandName) { - $message = sprintf('Too many arguments to "%s" command, expected arguments "%s".', $symfonyCommandName, implode('" "', array_keys($all))); - } else { - $message = sprintf('Too many arguments, expected arguments "%s".', implode('" "', array_keys($all))); - } - } elseif ($symfonyCommandName) { - $message = sprintf('No arguments expected for "%s" command, got "%s".', $symfonyCommandName, $token); - } else { - $message = sprintf('No arguments expected, got "%s".', $token); - } - - throw new RuntimeException($message); - } - } - - /** - * Adds a short option value. - * - * @throws RuntimeException When option given doesn't exist - */ - private function addShortOption(string $shortcut, $value) - { - if (!$this->definition->hasShortcut($shortcut)) { - throw new RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut)); - } - - $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value); - } - - /** - * Adds a long option value. - * - * @throws RuntimeException When option given doesn't exist - */ - private function addLongOption(string $name, $value) - { - if (!$this->definition->hasOption($name)) { - if (!$this->definition->hasNegation($name)) { - throw new RuntimeException(sprintf('The "--%s" option does not exist.', $name)); - } - - $optionName = $this->definition->negationToName($name); - if (null !== $value) { - throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name)); - } - $this->options[$optionName] = false; - - return; - } - - $option = $this->definition->getOption($name); - - if (null !== $value && !$option->acceptValue()) { - throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name)); - } - - if (\in_array($value, ['', null], true) && $option->acceptValue() && \count($this->parsed)) { - // if option accepts an optional or mandatory argument - // let's see if there is one provided - $next = array_shift($this->parsed); - if ((isset($next[0]) && '-' !== $next[0]) || \in_array($next, ['', null], true)) { - $value = $next; - } else { - array_unshift($this->parsed, $next); - } - } - - if (null === $value) { - if ($option->isValueRequired()) { - throw new RuntimeException(sprintf('The "--%s" option requires a value.', $name)); - } - - if (!$option->isArray() && !$option->isValueOptional()) { - $value = true; - } - } - - if ($option->isArray()) { - $this->options[$name][] = $value; - } else { - $this->options[$name] = $value; - } - } - - /** - * {@inheritdoc} - */ - public function getFirstArgument() - { - $isOption = false; - foreach ($this->tokens as $i => $token) { - if ($token && '-' === $token[0]) { - if (str_contains($token, '=') || !isset($this->tokens[$i + 1])) { - continue; - } - - // If it's a long option, consider that everything after "--" is the option name. - // Otherwise, use the last char (if it's a short option set, only the last one can take a value with space separator) - $name = '-' === $token[1] ? substr($token, 2) : substr($token, -1); - if (!isset($this->options[$name]) && !$this->definition->hasShortcut($name)) { - // noop - } elseif ((isset($this->options[$name]) || isset($this->options[$name = $this->definition->shortcutToName($name)])) && $this->tokens[$i + 1] === $this->options[$name]) { - $isOption = true; - } - - continue; - } - - if ($isOption) { - $isOption = false; - continue; - } - - return $token; - } - - return null; - } - - /** - * {@inheritdoc} - */ - public function hasParameterOption($values, bool $onlyParams = false) - { - $values = (array) $values; - - foreach ($this->tokens as $token) { - if ($onlyParams && '--' === $token) { - return false; - } - foreach ($values as $value) { - // Options with values: - // For long options, test for '--option=' at beginning - // For short options, test for '-o' at beginning - $leading = str_starts_with($value, '--') ? $value.'=' : $value; - if ($token === $value || '' !== $leading && str_starts_with($token, $leading)) { - return true; - } - } - } - - return false; - } - - /** - * {@inheritdoc} - */ - public function getParameterOption($values, $default = false, bool $onlyParams = false) - { - $values = (array) $values; - $tokens = $this->tokens; - - while (0 < \count($tokens)) { - $token = array_shift($tokens); - if ($onlyParams && '--' === $token) { - return $default; - } - - foreach ($values as $value) { - if ($token === $value) { - return array_shift($tokens); - } - // Options with values: - // For long options, test for '--option=' at beginning - // For short options, test for '-o' at beginning - $leading = str_starts_with($value, '--') ? $value.'=' : $value; - if ('' !== $leading && str_starts_with($token, $leading)) { - return substr($token, \strlen($leading)); - } - } - } - - return $default; - } - - /** - * Returns a stringified representation of the args passed to the command. - * - * @return string - */ - public function __toString() - { - $tokens = array_map(function ($token) { - if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) { - return $match[1].$this->escapeToken($match[2]); - } - - if ($token && '-' !== $token[0]) { - return $this->escapeToken($token); - } - - return $token; - }, $this->tokens); - - return implode(' ', $tokens); - } -} diff --git a/vendor/symfony/console/Input/ArrayInput.php b/vendor/symfony/console/Input/ArrayInput.php deleted file mode 100644 index c65161484..000000000 --- a/vendor/symfony/console/Input/ArrayInput.php +++ /dev/null @@ -1,210 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\InvalidOptionException; - -/** - * ArrayInput represents an input provided as an array. - * - * Usage: - * - * $input = new ArrayInput(['command' => 'foo:bar', 'foo' => 'bar', '--bar' => 'foobar']); - * - * @author Fabien Potencier - */ -class ArrayInput extends Input -{ - private $parameters; - - public function __construct(array $parameters, InputDefinition $definition = null) - { - $this->parameters = $parameters; - - parent::__construct($definition); - } - - /** - * {@inheritdoc} - */ - public function getFirstArgument() - { - foreach ($this->parameters as $param => $value) { - if ($param && \is_string($param) && '-' === $param[0]) { - continue; - } - - return $value; - } - - return null; - } - - /** - * {@inheritdoc} - */ - public function hasParameterOption($values, bool $onlyParams = false) - { - $values = (array) $values; - - foreach ($this->parameters as $k => $v) { - if (!\is_int($k)) { - $v = $k; - } - - if ($onlyParams && '--' === $v) { - return false; - } - - if (\in_array($v, $values)) { - return true; - } - } - - return false; - } - - /** - * {@inheritdoc} - */ - public function getParameterOption($values, $default = false, bool $onlyParams = false) - { - $values = (array) $values; - - foreach ($this->parameters as $k => $v) { - if ($onlyParams && ('--' === $k || (\is_int($k) && '--' === $v))) { - return $default; - } - - if (\is_int($k)) { - if (\in_array($v, $values)) { - return true; - } - } elseif (\in_array($k, $values)) { - return $v; - } - } - - return $default; - } - - /** - * Returns a stringified representation of the args passed to the command. - * - * @return string - */ - public function __toString() - { - $params = []; - foreach ($this->parameters as $param => $val) { - if ($param && \is_string($param) && '-' === $param[0]) { - $glue = ('-' === $param[1]) ? '=' : ' '; - if (\is_array($val)) { - foreach ($val as $v) { - $params[] = $param.('' != $v ? $glue.$this->escapeToken($v) : ''); - } - } else { - $params[] = $param.('' != $val ? $glue.$this->escapeToken($val) : ''); - } - } else { - $params[] = \is_array($val) ? implode(' ', array_map([$this, 'escapeToken'], $val)) : $this->escapeToken($val); - } - } - - return implode(' ', $params); - } - - /** - * {@inheritdoc} - */ - protected function parse() - { - foreach ($this->parameters as $key => $value) { - if ('--' === $key) { - return; - } - if (str_starts_with($key, '--')) { - $this->addLongOption(substr($key, 2), $value); - } elseif (str_starts_with($key, '-')) { - $this->addShortOption(substr($key, 1), $value); - } else { - $this->addArgument($key, $value); - } - } - } - - /** - * Adds a short option value. - * - * @throws InvalidOptionException When option given doesn't exist - */ - private function addShortOption(string $shortcut, $value) - { - if (!$this->definition->hasShortcut($shortcut)) { - throw new InvalidOptionException(sprintf('The "-%s" option does not exist.', $shortcut)); - } - - $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value); - } - - /** - * Adds a long option value. - * - * @throws InvalidOptionException When option given doesn't exist - * @throws InvalidOptionException When a required value is missing - */ - private function addLongOption(string $name, $value) - { - if (!$this->definition->hasOption($name)) { - if (!$this->definition->hasNegation($name)) { - throw new InvalidOptionException(sprintf('The "--%s" option does not exist.', $name)); - } - - $optionName = $this->definition->negationToName($name); - $this->options[$optionName] = false; - - return; - } - - $option = $this->definition->getOption($name); - - if (null === $value) { - if ($option->isValueRequired()) { - throw new InvalidOptionException(sprintf('The "--%s" option requires a value.', $name)); - } - - if (!$option->isValueOptional()) { - $value = true; - } - } - - $this->options[$name] = $value; - } - - /** - * Adds an argument value. - * - * @param string|int $name The argument name - * @param mixed $value The value for the argument - * - * @throws InvalidArgumentException When argument given doesn't exist - */ - private function addArgument($name, $value) - { - if (!$this->definition->hasArgument($name)) { - throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); - } - - $this->arguments[$name] = $value; - } -} diff --git a/vendor/symfony/console/Input/Input.php b/vendor/symfony/console/Input/Input.php deleted file mode 100644 index d37460ed3..000000000 --- a/vendor/symfony/console/Input/Input.php +++ /dev/null @@ -1,213 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\RuntimeException; - -/** - * Input is the base class for all concrete Input classes. - * - * Three concrete classes are provided by default: - * - * * `ArgvInput`: The input comes from the CLI arguments (argv) - * * `StringInput`: The input is provided as a string - * * `ArrayInput`: The input is provided as an array - * - * @author Fabien Potencier - */ -abstract class Input implements InputInterface, StreamableInputInterface -{ - protected $definition; - protected $stream; - protected $options = []; - protected $arguments = []; - protected $interactive = true; - - public function __construct(InputDefinition $definition = null) - { - if (null === $definition) { - $this->definition = new InputDefinition(); - } else { - $this->bind($definition); - $this->validate(); - } - } - - /** - * {@inheritdoc} - */ - public function bind(InputDefinition $definition) - { - $this->arguments = []; - $this->options = []; - $this->definition = $definition; - - $this->parse(); - } - - /** - * Processes command line arguments. - */ - abstract protected function parse(); - - /** - * {@inheritdoc} - */ - public function validate() - { - $definition = $this->definition; - $givenArguments = $this->arguments; - - $missingArguments = array_filter(array_keys($definition->getArguments()), function ($argument) use ($definition, $givenArguments) { - return !\array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired(); - }); - - if (\count($missingArguments) > 0) { - throw new RuntimeException(sprintf('Not enough arguments (missing: "%s").', implode(', ', $missingArguments))); - } - } - - /** - * {@inheritdoc} - */ - public function isInteractive() - { - return $this->interactive; - } - - /** - * {@inheritdoc} - */ - public function setInteractive(bool $interactive) - { - $this->interactive = $interactive; - } - - /** - * {@inheritdoc} - */ - public function getArguments() - { - return array_merge($this->definition->getArgumentDefaults(), $this->arguments); - } - - /** - * {@inheritdoc} - */ - public function getArgument(string $name) - { - if (!$this->definition->hasArgument($name)) { - throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); - } - - return $this->arguments[$name] ?? $this->definition->getArgument($name)->getDefault(); - } - - /** - * {@inheritdoc} - */ - public function setArgument(string $name, $value) - { - if (!$this->definition->hasArgument($name)) { - throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); - } - - $this->arguments[$name] = $value; - } - - /** - * {@inheritdoc} - */ - public function hasArgument(string $name) - { - return $this->definition->hasArgument($name); - } - - /** - * {@inheritdoc} - */ - public function getOptions() - { - return array_merge($this->definition->getOptionDefaults(), $this->options); - } - - /** - * {@inheritdoc} - */ - public function getOption(string $name) - { - if ($this->definition->hasNegation($name)) { - if (null === $value = $this->getOption($this->definition->negationToName($name))) { - return $value; - } - - return !$value; - } - - if (!$this->definition->hasOption($name)) { - throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name)); - } - - return \array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault(); - } - - /** - * {@inheritdoc} - */ - public function setOption(string $name, $value) - { - if ($this->definition->hasNegation($name)) { - $this->options[$this->definition->negationToName($name)] = !$value; - - return; - } elseif (!$this->definition->hasOption($name)) { - throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name)); - } - - $this->options[$name] = $value; - } - - /** - * {@inheritdoc} - */ - public function hasOption(string $name) - { - return $this->definition->hasOption($name) || $this->definition->hasNegation($name); - } - - /** - * Escapes a token through escapeshellarg if it contains unsafe chars. - * - * @return string - */ - public function escapeToken(string $token) - { - return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token); - } - - /** - * {@inheritdoc} - */ - public function setStream($stream) - { - $this->stream = $stream; - } - - /** - * {@inheritdoc} - */ - public function getStream() - { - return $this->stream; - } -} diff --git a/vendor/symfony/console/Input/InputArgument.php b/vendor/symfony/console/Input/InputArgument.php deleted file mode 100644 index ecfcdad58..000000000 --- a/vendor/symfony/console/Input/InputArgument.php +++ /dev/null @@ -1,129 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\LogicException; - -/** - * Represents a command line argument. - * - * @author Fabien Potencier - */ -class InputArgument -{ - public const REQUIRED = 1; - public const OPTIONAL = 2; - public const IS_ARRAY = 4; - - private $name; - private $mode; - private $default; - private $description; - - /** - * @param string $name The argument name - * @param int|null $mode The argument mode: self::REQUIRED or self::OPTIONAL - * @param string $description A description text - * @param string|bool|int|float|array|null $default The default value (for self::OPTIONAL mode only) - * - * @throws InvalidArgumentException When argument mode is not valid - */ - public function __construct(string $name, int $mode = null, string $description = '', $default = null) - { - if (null === $mode) { - $mode = self::OPTIONAL; - } elseif ($mode > 7 || $mode < 1) { - throw new InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode)); - } - - $this->name = $name; - $this->mode = $mode; - $this->description = $description; - - $this->setDefault($default); - } - - /** - * Returns the argument name. - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Returns true if the argument is required. - * - * @return bool true if parameter mode is self::REQUIRED, false otherwise - */ - public function isRequired() - { - return self::REQUIRED === (self::REQUIRED & $this->mode); - } - - /** - * Returns true if the argument can take multiple values. - * - * @return bool true if mode is self::IS_ARRAY, false otherwise - */ - public function isArray() - { - return self::IS_ARRAY === (self::IS_ARRAY & $this->mode); - } - - /** - * Sets the default value. - * - * @param string|bool|int|float|array|null $default - * - * @throws LogicException When incorrect default value is given - */ - public function setDefault($default = null) - { - if ($this->isRequired() && null !== $default) { - throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.'); - } - - if ($this->isArray()) { - if (null === $default) { - $default = []; - } elseif (!\is_array($default)) { - throw new LogicException('A default value for an array argument must be an array.'); - } - } - - $this->default = $default; - } - - /** - * Returns the default value. - * - * @return string|bool|int|float|array|null - */ - public function getDefault() - { - return $this->default; - } - - /** - * Returns the description text. - * - * @return string - */ - public function getDescription() - { - return $this->description; - } -} diff --git a/vendor/symfony/console/Input/InputAwareInterface.php b/vendor/symfony/console/Input/InputAwareInterface.php deleted file mode 100644 index 5a288de5d..000000000 --- a/vendor/symfony/console/Input/InputAwareInterface.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -/** - * InputAwareInterface should be implemented by classes that depends on the - * Console Input. - * - * @author Wouter J - */ -interface InputAwareInterface -{ - /** - * Sets the Console Input. - */ - public function setInput(InputInterface $input); -} diff --git a/vendor/symfony/console/Input/InputDefinition.php b/vendor/symfony/console/Input/InputDefinition.php deleted file mode 100644 index 11f704f0e..000000000 --- a/vendor/symfony/console/Input/InputDefinition.php +++ /dev/null @@ -1,424 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\LogicException; - -/** - * A InputDefinition represents a set of valid command line arguments and options. - * - * Usage: - * - * $definition = new InputDefinition([ - * new InputArgument('name', InputArgument::REQUIRED), - * new InputOption('foo', 'f', InputOption::VALUE_REQUIRED), - * ]); - * - * @author Fabien Potencier - */ -class InputDefinition -{ - private $arguments; - private $requiredCount; - private $lastArrayArgument; - private $lastOptionalArgument; - private $options; - private $negations; - private $shortcuts; - - /** - * @param array $definition An array of InputArgument and InputOption instance - */ - public function __construct(array $definition = []) - { - $this->setDefinition($definition); - } - - /** - * Sets the definition of the input. - */ - public function setDefinition(array $definition) - { - $arguments = []; - $options = []; - foreach ($definition as $item) { - if ($item instanceof InputOption) { - $options[] = $item; - } else { - $arguments[] = $item; - } - } - - $this->setArguments($arguments); - $this->setOptions($options); - } - - /** - * Sets the InputArgument objects. - * - * @param InputArgument[] $arguments An array of InputArgument objects - */ - public function setArguments(array $arguments = []) - { - $this->arguments = []; - $this->requiredCount = 0; - $this->lastOptionalArgument = null; - $this->lastArrayArgument = null; - $this->addArguments($arguments); - } - - /** - * Adds an array of InputArgument objects. - * - * @param InputArgument[] $arguments An array of InputArgument objects - */ - public function addArguments(?array $arguments = []) - { - if (null !== $arguments) { - foreach ($arguments as $argument) { - $this->addArgument($argument); - } - } - } - - /** - * @throws LogicException When incorrect argument is given - */ - public function addArgument(InputArgument $argument) - { - if (isset($this->arguments[$argument->getName()])) { - throw new LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName())); - } - - if (null !== $this->lastArrayArgument) { - throw new LogicException(sprintf('Cannot add a required argument "%s" after an array argument "%s".', $argument->getName(), $this->lastArrayArgument->getName())); - } - - if ($argument->isRequired() && null !== $this->lastOptionalArgument) { - throw new LogicException(sprintf('Cannot add a required argument "%s" after an optional one "%s".', $argument->getName(), $this->lastOptionalArgument->getName())); - } - - if ($argument->isArray()) { - $this->lastArrayArgument = $argument; - } - - if ($argument->isRequired()) { - ++$this->requiredCount; - } else { - $this->lastOptionalArgument = $argument; - } - - $this->arguments[$argument->getName()] = $argument; - } - - /** - * Returns an InputArgument by name or by position. - * - * @param string|int $name The InputArgument name or position - * - * @return InputArgument - * - * @throws InvalidArgumentException When argument given doesn't exist - */ - public function getArgument($name) - { - if (!$this->hasArgument($name)) { - throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); - } - - $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments; - - return $arguments[$name]; - } - - /** - * Returns true if an InputArgument object exists by name or position. - * - * @param string|int $name The InputArgument name or position - * - * @return bool - */ - public function hasArgument($name) - { - $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments; - - return isset($arguments[$name]); - } - - /** - * Gets the array of InputArgument objects. - * - * @return InputArgument[] - */ - public function getArguments() - { - return $this->arguments; - } - - /** - * Returns the number of InputArguments. - * - * @return int - */ - public function getArgumentCount() - { - return null !== $this->lastArrayArgument ? \PHP_INT_MAX : \count($this->arguments); - } - - /** - * Returns the number of required InputArguments. - * - * @return int - */ - public function getArgumentRequiredCount() - { - return $this->requiredCount; - } - - /** - * @return array - */ - public function getArgumentDefaults() - { - $values = []; - foreach ($this->arguments as $argument) { - $values[$argument->getName()] = $argument->getDefault(); - } - - return $values; - } - - /** - * Sets the InputOption objects. - * - * @param InputOption[] $options An array of InputOption objects - */ - public function setOptions(array $options = []) - { - $this->options = []; - $this->shortcuts = []; - $this->negations = []; - $this->addOptions($options); - } - - /** - * Adds an array of InputOption objects. - * - * @param InputOption[] $options An array of InputOption objects - */ - public function addOptions(array $options = []) - { - foreach ($options as $option) { - $this->addOption($option); - } - } - - /** - * @throws LogicException When option given already exist - */ - public function addOption(InputOption $option) - { - if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) { - throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName())); - } - if (isset($this->negations[$option->getName()])) { - throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName())); - } - - if ($option->getShortcut()) { - foreach (explode('|', $option->getShortcut()) as $shortcut) { - if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) { - throw new LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut)); - } - } - } - - $this->options[$option->getName()] = $option; - if ($option->getShortcut()) { - foreach (explode('|', $option->getShortcut()) as $shortcut) { - $this->shortcuts[$shortcut] = $option->getName(); - } - } - - if ($option->isNegatable()) { - $negatedName = 'no-'.$option->getName(); - if (isset($this->options[$negatedName])) { - throw new LogicException(sprintf('An option named "%s" already exists.', $negatedName)); - } - $this->negations[$negatedName] = $option->getName(); - } - } - - /** - * Returns an InputOption by name. - * - * @return InputOption - * - * @throws InvalidArgumentException When option given doesn't exist - */ - public function getOption(string $name) - { - if (!$this->hasOption($name)) { - throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name)); - } - - return $this->options[$name]; - } - - /** - * Returns true if an InputOption object exists by name. - * - * This method can't be used to check if the user included the option when - * executing the command (use getOption() instead). - * - * @return bool - */ - public function hasOption(string $name) - { - return isset($this->options[$name]); - } - - /** - * Gets the array of InputOption objects. - * - * @return InputOption[] - */ - public function getOptions() - { - return $this->options; - } - - /** - * Returns true if an InputOption object exists by shortcut. - * - * @return bool - */ - public function hasShortcut(string $name) - { - return isset($this->shortcuts[$name]); - } - - /** - * Returns true if an InputOption object exists by negated name. - */ - public function hasNegation(string $name): bool - { - return isset($this->negations[$name]); - } - - /** - * Gets an InputOption by shortcut. - * - * @return InputOption - */ - public function getOptionForShortcut(string $shortcut) - { - return $this->getOption($this->shortcutToName($shortcut)); - } - - /** - * @return array - */ - public function getOptionDefaults() - { - $values = []; - foreach ($this->options as $option) { - $values[$option->getName()] = $option->getDefault(); - } - - return $values; - } - - /** - * Returns the InputOption name given a shortcut. - * - * @throws InvalidArgumentException When option given does not exist - * - * @internal - */ - public function shortcutToName(string $shortcut): string - { - if (!isset($this->shortcuts[$shortcut])) { - throw new InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut)); - } - - return $this->shortcuts[$shortcut]; - } - - /** - * Returns the InputOption name given a negation. - * - * @throws InvalidArgumentException When option given does not exist - * - * @internal - */ - public function negationToName(string $negation): string - { - if (!isset($this->negations[$negation])) { - throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $negation)); - } - - return $this->negations[$negation]; - } - - /** - * Gets the synopsis. - * - * @return string - */ - public function getSynopsis(bool $short = false) - { - $elements = []; - - if ($short && $this->getOptions()) { - $elements[] = '[options]'; - } elseif (!$short) { - foreach ($this->getOptions() as $option) { - $value = ''; - if ($option->acceptValue()) { - $value = sprintf( - ' %s%s%s', - $option->isValueOptional() ? '[' : '', - strtoupper($option->getName()), - $option->isValueOptional() ? ']' : '' - ); - } - - $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : ''; - $negation = $option->isNegatable() ? sprintf('|--no-%s', $option->getName()) : ''; - $elements[] = sprintf('[%s--%s%s%s]', $shortcut, $option->getName(), $value, $negation); - } - } - - if (\count($elements) && $this->getArguments()) { - $elements[] = '[--]'; - } - - $tail = ''; - foreach ($this->getArguments() as $argument) { - $element = '<'.$argument->getName().'>'; - if ($argument->isArray()) { - $element .= '...'; - } - - if (!$argument->isRequired()) { - $element = '['.$element; - $tail .= ']'; - } - - $elements[] = $element; - } - - return implode(' ', $elements).$tail; - } -} diff --git a/vendor/symfony/console/Input/InputInterface.php b/vendor/symfony/console/Input/InputInterface.php deleted file mode 100644 index 628b6037a..000000000 --- a/vendor/symfony/console/Input/InputInterface.php +++ /dev/null @@ -1,151 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\RuntimeException; - -/** - * InputInterface is the interface implemented by all input classes. - * - * @author Fabien Potencier - */ -interface InputInterface -{ - /** - * Returns the first argument from the raw parameters (not parsed). - * - * @return string|null - */ - public function getFirstArgument(); - - /** - * Returns true if the raw parameters (not parsed) contain a value. - * - * This method is to be used to introspect the input parameters - * before they have been validated. It must be used carefully. - * Does not necessarily return the correct result for short options - * when multiple flags are combined in the same option. - * - * @param string|array $values The values to look for in the raw parameters (can be an array) - * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal - * - * @return bool - */ - public function hasParameterOption($values, bool $onlyParams = false); - - /** - * Returns the value of a raw option (not parsed). - * - * This method is to be used to introspect the input parameters - * before they have been validated. It must be used carefully. - * Does not necessarily return the correct result for short options - * when multiple flags are combined in the same option. - * - * @param string|array $values The value(s) to look for in the raw parameters (can be an array) - * @param string|bool|int|float|array|null $default The default value to return if no result is found - * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal - * - * @return mixed - */ - public function getParameterOption($values, $default = false, bool $onlyParams = false); - - /** - * Binds the current Input instance with the given arguments and options. - * - * @throws RuntimeException - */ - public function bind(InputDefinition $definition); - - /** - * Validates the input. - * - * @throws RuntimeException When not enough arguments are given - */ - public function validate(); - - /** - * Returns all the given arguments merged with the default values. - * - * @return array - */ - public function getArguments(); - - /** - * Returns the argument value for a given argument name. - * - * @return mixed - * - * @throws InvalidArgumentException When argument given doesn't exist - */ - public function getArgument(string $name); - - /** - * Sets an argument value by name. - * - * @param mixed $value The argument value - * - * @throws InvalidArgumentException When argument given doesn't exist - */ - public function setArgument(string $name, $value); - - /** - * Returns true if an InputArgument object exists by name or position. - * - * @return bool - */ - public function hasArgument(string $name); - - /** - * Returns all the given options merged with the default values. - * - * @return array - */ - public function getOptions(); - - /** - * Returns the option value for a given option name. - * - * @return mixed - * - * @throws InvalidArgumentException When option given doesn't exist - */ - public function getOption(string $name); - - /** - * Sets an option value by name. - * - * @param mixed $value The option value - * - * @throws InvalidArgumentException When option given doesn't exist - */ - public function setOption(string $name, $value); - - /** - * Returns true if an InputOption object exists by name. - * - * @return bool - */ - public function hasOption(string $name); - - /** - * Is this input means interactive? - * - * @return bool - */ - public function isInteractive(); - - /** - * Sets the input interactivity. - */ - public function setInteractive(bool $interactive); -} diff --git a/vendor/symfony/console/Input/InputOption.php b/vendor/symfony/console/Input/InputOption.php deleted file mode 100644 index 2bec34fe1..000000000 --- a/vendor/symfony/console/Input/InputOption.php +++ /dev/null @@ -1,231 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\LogicException; - -/** - * Represents a command line option. - * - * @author Fabien Potencier - */ -class InputOption -{ - /** - * Do not accept input for the option (e.g. --yell). This is the default behavior of options. - */ - public const VALUE_NONE = 1; - - /** - * A value must be passed when the option is used (e.g. --iterations=5 or -i5). - */ - public const VALUE_REQUIRED = 2; - - /** - * The option may or may not have a value (e.g. --yell or --yell=loud). - */ - public const VALUE_OPTIONAL = 4; - - /** - * The option accepts multiple values (e.g. --dir=/foo --dir=/bar). - */ - public const VALUE_IS_ARRAY = 8; - - /** - * The option may have either positive or negative value (e.g. --ansi or --no-ansi). - */ - public const VALUE_NEGATABLE = 16; - - private $name; - private $shortcut; - private $mode; - private $default; - private $description; - - /** - * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts - * @param int|null $mode The option mode: One of the VALUE_* constants - * @param string|bool|int|float|array|null $default The default value (must be null for self::VALUE_NONE) - * - * @throws InvalidArgumentException If option mode is invalid or incompatible - */ - public function __construct(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null) - { - if (str_starts_with($name, '--')) { - $name = substr($name, 2); - } - - if (empty($name)) { - throw new InvalidArgumentException('An option name cannot be empty.'); - } - - if (empty($shortcut)) { - $shortcut = null; - } - - if (null !== $shortcut) { - if (\is_array($shortcut)) { - $shortcut = implode('|', $shortcut); - } - $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-')); - $shortcuts = array_filter($shortcuts); - $shortcut = implode('|', $shortcuts); - - if (empty($shortcut)) { - throw new InvalidArgumentException('An option shortcut cannot be empty.'); - } - } - - if (null === $mode) { - $mode = self::VALUE_NONE; - } elseif ($mode >= (self::VALUE_NEGATABLE << 1) || $mode < 1) { - throw new InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode)); - } - - $this->name = $name; - $this->shortcut = $shortcut; - $this->mode = $mode; - $this->description = $description; - - if ($this->isArray() && !$this->acceptValue()) { - throw new InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.'); - } - if ($this->isNegatable() && $this->acceptValue()) { - throw new InvalidArgumentException('Impossible to have an option mode VALUE_NEGATABLE if the option also accepts a value.'); - } - - $this->setDefault($default); - } - - /** - * Returns the option shortcut. - * - * @return string|null - */ - public function getShortcut() - { - return $this->shortcut; - } - - /** - * Returns the option name. - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Returns true if the option accepts a value. - * - * @return bool true if value mode is not self::VALUE_NONE, false otherwise - */ - public function acceptValue() - { - return $this->isValueRequired() || $this->isValueOptional(); - } - - /** - * Returns true if the option requires a value. - * - * @return bool true if value mode is self::VALUE_REQUIRED, false otherwise - */ - public function isValueRequired() - { - return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode); - } - - /** - * Returns true if the option takes an optional value. - * - * @return bool true if value mode is self::VALUE_OPTIONAL, false otherwise - */ - public function isValueOptional() - { - return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode); - } - - /** - * Returns true if the option can take multiple values. - * - * @return bool true if mode is self::VALUE_IS_ARRAY, false otherwise - */ - public function isArray() - { - return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode); - } - - public function isNegatable(): bool - { - return self::VALUE_NEGATABLE === (self::VALUE_NEGATABLE & $this->mode); - } - - /** - * @param string|bool|int|float|array|null $default - */ - public function setDefault($default = null) - { - if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) { - throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.'); - } - - if ($this->isArray()) { - if (null === $default) { - $default = []; - } elseif (!\is_array($default)) { - throw new LogicException('A default value for an array option must be an array.'); - } - } - - $this->default = $this->acceptValue() || $this->isNegatable() ? $default : false; - } - - /** - * Returns the default value. - * - * @return string|bool|int|float|array|null - */ - public function getDefault() - { - return $this->default; - } - - /** - * Returns the description text. - * - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * Checks whether the given option equals this one. - * - * @return bool - */ - public function equals(self $option) - { - return $option->getName() === $this->getName() - && $option->getShortcut() === $this->getShortcut() - && $option->getDefault() === $this->getDefault() - && $option->isNegatable() === $this->isNegatable() - && $option->isArray() === $this->isArray() - && $option->isValueRequired() === $this->isValueRequired() - && $option->isValueOptional() === $this->isValueOptional() - ; - } -} diff --git a/vendor/symfony/console/Input/StreamableInputInterface.php b/vendor/symfony/console/Input/StreamableInputInterface.php deleted file mode 100644 index d7e462f24..000000000 --- a/vendor/symfony/console/Input/StreamableInputInterface.php +++ /dev/null @@ -1,37 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -/** - * StreamableInputInterface is the interface implemented by all input classes - * that have an input stream. - * - * @author Robin Chalas - */ -interface StreamableInputInterface extends InputInterface -{ - /** - * Sets the input stream to read from when interacting with the user. - * - * This is mainly useful for testing purpose. - * - * @param resource $stream The input stream - */ - public function setStream($stream); - - /** - * Returns the input stream. - * - * @return resource|null - */ - public function getStream(); -} diff --git a/vendor/symfony/console/Input/StringInput.php b/vendor/symfony/console/Input/StringInput.php deleted file mode 100644 index 56bb66cbf..000000000 --- a/vendor/symfony/console/Input/StringInput.php +++ /dev/null @@ -1,84 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Input; - -use Symfony\Component\Console\Exception\InvalidArgumentException; - -/** - * StringInput represents an input provided as a string. - * - * Usage: - * - * $input = new StringInput('foo --bar="foobar"'); - * - * @author Fabien Potencier - */ -class StringInput extends ArgvInput -{ - public const REGEX_STRING = '([^\s]+?)(?:\s|(?setTokens($this->tokenize($input)); - } - - /** - * Tokenizes a string. - * - * @throws InvalidArgumentException When unable to parse input (should never happen) - */ - private function tokenize(string $input): array - { - $tokens = []; - $length = \strlen($input); - $cursor = 0; - $token = null; - while ($cursor < $length) { - if ('\\' === $input[$cursor]) { - $token .= $input[++$cursor] ?? ''; - ++$cursor; - continue; - } - - if (preg_match('/\s+/A', $input, $match, 0, $cursor)) { - if (null !== $token) { - $tokens[] = $token; - $token = null; - } - } elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, 0, $cursor)) { - $token .= $match[1].$match[2].stripcslashes(str_replace(['"\'', '\'"', '\'\'', '""'], '', substr($match[3], 1, -1))); - } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, 0, $cursor)) { - $token .= stripcslashes(substr($match[0], 1, -1)); - } elseif (preg_match('/'.self::REGEX_UNQUOTED_STRING.'/A', $input, $match, 0, $cursor)) { - $token .= $match[1]; - } else { - // should never happen - throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ...".', substr($input, $cursor, 10))); - } - - $cursor += \strlen($match[0]); - } - - if (null !== $token) { - $tokens[] = $token; - } - - return $tokens; - } -} diff --git a/vendor/symfony/console/Logger/ConsoleLogger.php b/vendor/symfony/console/Logger/ConsoleLogger.php deleted file mode 100644 index 4a10fa172..000000000 --- a/vendor/symfony/console/Logger/ConsoleLogger.php +++ /dev/null @@ -1,126 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Logger; - -use Psr\Log\AbstractLogger; -use Psr\Log\InvalidArgumentException; -use Psr\Log\LogLevel; -use Symfony\Component\Console\Output\ConsoleOutputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * PSR-3 compliant console logger. - * - * @author Kévin Dunglas - * - * @see https://www.php-fig.org/psr/psr-3/ - */ -class ConsoleLogger extends AbstractLogger -{ - public const INFO = 'info'; - public const ERROR = 'error'; - - private $output; - private $verbosityLevelMap = [ - LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL, - LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL, - LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL, - LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL, - LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL, - LogLevel::NOTICE => OutputInterface::VERBOSITY_VERBOSE, - LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE, - LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG, - ]; - private $formatLevelMap = [ - LogLevel::EMERGENCY => self::ERROR, - LogLevel::ALERT => self::ERROR, - LogLevel::CRITICAL => self::ERROR, - LogLevel::ERROR => self::ERROR, - LogLevel::WARNING => self::INFO, - LogLevel::NOTICE => self::INFO, - LogLevel::INFO => self::INFO, - LogLevel::DEBUG => self::INFO, - ]; - private $errored = false; - - public function __construct(OutputInterface $output, array $verbosityLevelMap = [], array $formatLevelMap = []) - { - $this->output = $output; - $this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap; - $this->formatLevelMap = $formatLevelMap + $this->formatLevelMap; - } - - /** - * {@inheritdoc} - * - * @return void - */ - public function log($level, $message, array $context = []) - { - if (!isset($this->verbosityLevelMap[$level])) { - throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level)); - } - - $output = $this->output; - - // Write to the error output if necessary and available - if (self::ERROR === $this->formatLevelMap[$level]) { - if ($this->output instanceof ConsoleOutputInterface) { - $output = $output->getErrorOutput(); - } - $this->errored = true; - } - - // the if condition check isn't necessary -- it's the same one that $output will do internally anyway. - // We only do it for efficiency here as the message formatting is relatively expensive. - if ($output->getVerbosity() >= $this->verbosityLevelMap[$level]) { - $output->writeln(sprintf('<%1$s>[%2$s] %3$s', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context)), $this->verbosityLevelMap[$level]); - } - } - - /** - * Returns true when any messages have been logged at error levels. - * - * @return bool - */ - public function hasErrored() - { - return $this->errored; - } - - /** - * Interpolates context values into the message placeholders. - * - * @author PHP Framework Interoperability Group - */ - private function interpolate(string $message, array $context): string - { - if (!str_contains($message, '{')) { - return $message; - } - - $replacements = []; - foreach ($context as $key => $val) { - if (null === $val || \is_scalar($val) || (\is_object($val) && method_exists($val, '__toString'))) { - $replacements["{{$key}}"] = $val; - } elseif ($val instanceof \DateTimeInterface) { - $replacements["{{$key}}"] = $val->format(\DateTime::RFC3339); - } elseif (\is_object($val)) { - $replacements["{{$key}}"] = '[object '.\get_class($val).']'; - } else { - $replacements["{{$key}}"] = '['.\gettype($val).']'; - } - } - - return strtr($message, $replacements); - } -} diff --git a/vendor/symfony/console/Output/BufferedOutput.php b/vendor/symfony/console/Output/BufferedOutput.php deleted file mode 100644 index d37c6e323..000000000 --- a/vendor/symfony/console/Output/BufferedOutput.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -/** - * @author Jean-François Simon - */ -class BufferedOutput extends Output -{ - private $buffer = ''; - - /** - * Empties buffer and returns its content. - * - * @return string - */ - public function fetch() - { - $content = $this->buffer; - $this->buffer = ''; - - return $content; - } - - /** - * {@inheritdoc} - */ - protected function doWrite(string $message, bool $newline) - { - $this->buffer .= $message; - - if ($newline) { - $this->buffer .= \PHP_EOL; - } - } -} diff --git a/vendor/symfony/console/Output/ConsoleOutput.php b/vendor/symfony/console/Output/ConsoleOutput.php deleted file mode 100644 index f19f9ebf4..000000000 --- a/vendor/symfony/console/Output/ConsoleOutput.php +++ /dev/null @@ -1,172 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -use Symfony\Component\Console\Formatter\OutputFormatterInterface; - -/** - * ConsoleOutput is the default class for all CLI output. It uses STDOUT and STDERR. - * - * This class is a convenient wrapper around `StreamOutput` for both STDOUT and STDERR. - * - * $output = new ConsoleOutput(); - * - * This is equivalent to: - * - * $output = new StreamOutput(fopen('php://stdout', 'w')); - * $stdErr = new StreamOutput(fopen('php://stderr', 'w')); - * - * @author Fabien Potencier - */ -class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface -{ - private $stderr; - private $consoleSectionOutputs = []; - - /** - * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) - * @param bool|null $decorated Whether to decorate messages (null for auto-guessing) - * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) - */ - public function __construct(int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null) - { - parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter); - - if (null === $formatter) { - // for BC reasons, stdErr has it own Formatter only when user don't inject a specific formatter. - $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated); - - return; - } - - $actualDecorated = $this->isDecorated(); - $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter()); - - if (null === $decorated) { - $this->setDecorated($actualDecorated && $this->stderr->isDecorated()); - } - } - - /** - * Creates a new output section. - */ - public function section(): ConsoleSectionOutput - { - return new ConsoleSectionOutput($this->getStream(), $this->consoleSectionOutputs, $this->getVerbosity(), $this->isDecorated(), $this->getFormatter()); - } - - /** - * {@inheritdoc} - */ - public function setDecorated(bool $decorated) - { - parent::setDecorated($decorated); - $this->stderr->setDecorated($decorated); - } - - /** - * {@inheritdoc} - */ - public function setFormatter(OutputFormatterInterface $formatter) - { - parent::setFormatter($formatter); - $this->stderr->setFormatter($formatter); - } - - /** - * {@inheritdoc} - */ - public function setVerbosity(int $level) - { - parent::setVerbosity($level); - $this->stderr->setVerbosity($level); - } - - /** - * {@inheritdoc} - */ - public function getErrorOutput() - { - return $this->stderr; - } - - /** - * {@inheritdoc} - */ - public function setErrorOutput(OutputInterface $error) - { - $this->stderr = $error; - } - - /** - * Returns true if current environment supports writing console output to - * STDOUT. - * - * @return bool - */ - protected function hasStdoutSupport() - { - return false === $this->isRunningOS400(); - } - - /** - * Returns true if current environment supports writing console output to - * STDERR. - * - * @return bool - */ - protected function hasStderrSupport() - { - return false === $this->isRunningOS400(); - } - - /** - * Checks if current executing environment is IBM iSeries (OS400), which - * doesn't properly convert character-encodings between ASCII to EBCDIC. - */ - private function isRunningOS400(): bool - { - $checks = [ - \function_exists('php_uname') ? php_uname('s') : '', - getenv('OSTYPE'), - \PHP_OS, - ]; - - return false !== stripos(implode(';', $checks), 'OS400'); - } - - /** - * @return resource - */ - private function openOutputStream() - { - if (!$this->hasStdoutSupport()) { - return fopen('php://output', 'w'); - } - - // Use STDOUT when possible to prevent from opening too many file descriptors - return \defined('STDOUT') ? \STDOUT : (@fopen('php://stdout', 'w') ?: fopen('php://output', 'w')); - } - - /** - * @return resource - */ - private function openErrorStream() - { - if (!$this->hasStderrSupport()) { - return fopen('php://output', 'w'); - } - - // Use STDERR when possible to prevent from opening too many file descriptors - return \defined('STDERR') ? \STDERR : (@fopen('php://stderr', 'w') ?: fopen('php://output', 'w')); - } -} diff --git a/vendor/symfony/console/Output/ConsoleOutputInterface.php b/vendor/symfony/console/Output/ConsoleOutputInterface.php deleted file mode 100644 index 6b6635f58..000000000 --- a/vendor/symfony/console/Output/ConsoleOutputInterface.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -/** - * ConsoleOutputInterface is the interface implemented by ConsoleOutput class. - * This adds information about stderr and section output stream. - * - * @author Dariusz Górecki - */ -interface ConsoleOutputInterface extends OutputInterface -{ - /** - * Gets the OutputInterface for errors. - * - * @return OutputInterface - */ - public function getErrorOutput(); - - public function setErrorOutput(OutputInterface $error); - - public function section(): ConsoleSectionOutput; -} diff --git a/vendor/symfony/console/Output/ConsoleSectionOutput.php b/vendor/symfony/console/Output/ConsoleSectionOutput.php deleted file mode 100644 index 8f1649758..000000000 --- a/vendor/symfony/console/Output/ConsoleSectionOutput.php +++ /dev/null @@ -1,143 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -use Symfony\Component\Console\Formatter\OutputFormatterInterface; -use Symfony\Component\Console\Helper\Helper; -use Symfony\Component\Console\Terminal; - -/** - * @author Pierre du Plessis - * @author Gabriel Ostrolucký - */ -class ConsoleSectionOutput extends StreamOutput -{ - private $content = []; - private $lines = 0; - private $sections; - private $terminal; - - /** - * @param resource $stream - * @param ConsoleSectionOutput[] $sections - */ - public function __construct($stream, array &$sections, int $verbosity, bool $decorated, OutputFormatterInterface $formatter) - { - parent::__construct($stream, $verbosity, $decorated, $formatter); - array_unshift($sections, $this); - $this->sections = &$sections; - $this->terminal = new Terminal(); - } - - /** - * Clears previous output for this section. - * - * @param int $lines Number of lines to clear. If null, then the entire output of this section is cleared - */ - public function clear(int $lines = null) - { - if (empty($this->content) || !$this->isDecorated()) { - return; - } - - if ($lines) { - array_splice($this->content, -($lines * 2)); // Multiply lines by 2 to cater for each new line added between content - } else { - $lines = $this->lines; - $this->content = []; - } - - $this->lines -= $lines; - - parent::doWrite($this->popStreamContentUntilCurrentSection($lines), false); - } - - /** - * Overwrites the previous output with a new message. - * - * @param array|string $message - */ - public function overwrite($message) - { - $this->clear(); - $this->writeln($message); - } - - public function getContent(): string - { - return implode('', $this->content); - } - - /** - * @internal - */ - public function addContent(string $input) - { - foreach (explode(\PHP_EOL, $input) as $lineContent) { - $this->lines += ceil($this->getDisplayLength($lineContent) / $this->terminal->getWidth()) ?: 1; - $this->content[] = $lineContent; - $this->content[] = \PHP_EOL; - } - } - - /** - * {@inheritdoc} - */ - protected function doWrite(string $message, bool $newline) - { - if (!$this->isDecorated()) { - parent::doWrite($message, $newline); - - return; - } - - $erasedContent = $this->popStreamContentUntilCurrentSection(); - - $this->addContent($message); - - parent::doWrite($message, true); - parent::doWrite($erasedContent, false); - } - - /** - * At initial stage, cursor is at the end of stream output. This method makes cursor crawl upwards until it hits - * current section. Then it erases content it crawled through. Optionally, it erases part of current section too. - */ - private function popStreamContentUntilCurrentSection(int $numberOfLinesToClearFromCurrentSection = 0): string - { - $numberOfLinesToClear = $numberOfLinesToClearFromCurrentSection; - $erasedContent = []; - - foreach ($this->sections as $section) { - if ($section === $this) { - break; - } - - $numberOfLinesToClear += $section->lines; - $erasedContent[] = $section->getContent(); - } - - if ($numberOfLinesToClear > 0) { - // move cursor up n lines - parent::doWrite(sprintf("\x1b[%dA", $numberOfLinesToClear), false); - // erase to end of screen - parent::doWrite("\x1b[0J", false); - } - - return implode('', array_reverse($erasedContent)); - } - - private function getDisplayLength(string $text): int - { - return Helper::width(Helper::removeDecoration($this->getFormatter(), str_replace("\t", ' ', $text))); - } -} diff --git a/vendor/symfony/console/Output/NullOutput.php b/vendor/symfony/console/Output/NullOutput.php deleted file mode 100644 index 3bbe63ea0..000000000 --- a/vendor/symfony/console/Output/NullOutput.php +++ /dev/null @@ -1,128 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -use Symfony\Component\Console\Formatter\NullOutputFormatter; -use Symfony\Component\Console\Formatter\OutputFormatterInterface; - -/** - * NullOutput suppresses all output. - * - * $output = new NullOutput(); - * - * @author Fabien Potencier - * @author Tobias Schultze - */ -class NullOutput implements OutputInterface -{ - private $formatter; - - /** - * {@inheritdoc} - */ - public function setFormatter(OutputFormatterInterface $formatter) - { - // do nothing - } - - /** - * {@inheritdoc} - */ - public function getFormatter() - { - if ($this->formatter) { - return $this->formatter; - } - // to comply with the interface we must return a OutputFormatterInterface - return $this->formatter = new NullOutputFormatter(); - } - - /** - * {@inheritdoc} - */ - public function setDecorated(bool $decorated) - { - // do nothing - } - - /** - * {@inheritdoc} - */ - public function isDecorated() - { - return false; - } - - /** - * {@inheritdoc} - */ - public function setVerbosity(int $level) - { - // do nothing - } - - /** - * {@inheritdoc} - */ - public function getVerbosity() - { - return self::VERBOSITY_QUIET; - } - - /** - * {@inheritdoc} - */ - public function isQuiet() - { - return true; - } - - /** - * {@inheritdoc} - */ - public function isVerbose() - { - return false; - } - - /** - * {@inheritdoc} - */ - public function isVeryVerbose() - { - return false; - } - - /** - * {@inheritdoc} - */ - public function isDebug() - { - return false; - } - - /** - * {@inheritdoc} - */ - public function writeln($messages, int $options = self::OUTPUT_NORMAL) - { - // do nothing - } - - /** - * {@inheritdoc} - */ - public function write($messages, bool $newline = false, int $options = self::OUTPUT_NORMAL) - { - // do nothing - } -} diff --git a/vendor/symfony/console/Output/Output.php b/vendor/symfony/console/Output/Output.php deleted file mode 100644 index d7c5fb2d1..000000000 --- a/vendor/symfony/console/Output/Output.php +++ /dev/null @@ -1,174 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -use Symfony\Component\Console\Formatter\OutputFormatter; -use Symfony\Component\Console\Formatter\OutputFormatterInterface; - -/** - * Base class for output classes. - * - * There are five levels of verbosity: - * - * * normal: no option passed (normal output) - * * verbose: -v (more output) - * * very verbose: -vv (highly extended output) - * * debug: -vvv (all debug output) - * * quiet: -q (no output) - * - * @author Fabien Potencier - */ -abstract class Output implements OutputInterface -{ - private $verbosity; - private $formatter; - - /** - * @param int|null $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) - * @param bool $decorated Whether to decorate messages - * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) - */ - public function __construct(?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, OutputFormatterInterface $formatter = null) - { - $this->verbosity = $verbosity ?? self::VERBOSITY_NORMAL; - $this->formatter = $formatter ?? new OutputFormatter(); - $this->formatter->setDecorated($decorated); - } - - /** - * {@inheritdoc} - */ - public function setFormatter(OutputFormatterInterface $formatter) - { - $this->formatter = $formatter; - } - - /** - * {@inheritdoc} - */ - public function getFormatter() - { - return $this->formatter; - } - - /** - * {@inheritdoc} - */ - public function setDecorated(bool $decorated) - { - $this->formatter->setDecorated($decorated); - } - - /** - * {@inheritdoc} - */ - public function isDecorated() - { - return $this->formatter->isDecorated(); - } - - /** - * {@inheritdoc} - */ - public function setVerbosity(int $level) - { - $this->verbosity = $level; - } - - /** - * {@inheritdoc} - */ - public function getVerbosity() - { - return $this->verbosity; - } - - /** - * {@inheritdoc} - */ - public function isQuiet() - { - return self::VERBOSITY_QUIET === $this->verbosity; - } - - /** - * {@inheritdoc} - */ - public function isVerbose() - { - return self::VERBOSITY_VERBOSE <= $this->verbosity; - } - - /** - * {@inheritdoc} - */ - public function isVeryVerbose() - { - return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity; - } - - /** - * {@inheritdoc} - */ - public function isDebug() - { - return self::VERBOSITY_DEBUG <= $this->verbosity; - } - - /** - * {@inheritdoc} - */ - public function writeln($messages, int $options = self::OUTPUT_NORMAL) - { - $this->write($messages, true, $options); - } - - /** - * {@inheritdoc} - */ - public function write($messages, bool $newline = false, int $options = self::OUTPUT_NORMAL) - { - if (!is_iterable($messages)) { - $messages = [$messages]; - } - - $types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN; - $type = $types & $options ?: self::OUTPUT_NORMAL; - - $verbosities = self::VERBOSITY_QUIET | self::VERBOSITY_NORMAL | self::VERBOSITY_VERBOSE | self::VERBOSITY_VERY_VERBOSE | self::VERBOSITY_DEBUG; - $verbosity = $verbosities & $options ?: self::VERBOSITY_NORMAL; - - if ($verbosity > $this->getVerbosity()) { - return; - } - - foreach ($messages as $message) { - switch ($type) { - case OutputInterface::OUTPUT_NORMAL: - $message = $this->formatter->format($message); - break; - case OutputInterface::OUTPUT_RAW: - break; - case OutputInterface::OUTPUT_PLAIN: - $message = strip_tags($this->formatter->format($message)); - break; - } - - $this->doWrite($message ?? '', $newline); - } - } - - /** - * Writes a message to the output. - */ - abstract protected function doWrite(string $message, bool $newline); -} diff --git a/vendor/symfony/console/Output/OutputInterface.php b/vendor/symfony/console/Output/OutputInterface.php deleted file mode 100644 index 55caab80b..000000000 --- a/vendor/symfony/console/Output/OutputInterface.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. - */ - -namespace Symfony\Component\Console\Output; - -use Symfony\Component\Console\Formatter\OutputFormatterInterface; - -/** - * OutputInterface is the interface implemented by all Output classes. - * - * @author Fabien Potencier - */ -interface OutputInterface -{ - public const VERBOSITY_QUIET = 16; - public const VERBOSITY_NORMAL = 32; - public const VERBOSITY_VERBOSE = 64; - public const VERBOSITY_VERY_VERBOSE = 128; - public const VERBOSITY_DEBUG = 256; - - public const OUTPUT_NORMAL = 1; - public const OUTPUT_RAW = 2; - public const OUTPUT_PLAIN = 4; - - /** - * Writes a message to the output. - * - * @param string|iterable $messages The message as an iterable of strings or a single string - * @param bool $newline Whether to add a newline - * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL - */ - public function write($messages, bool $newline = false, int $options = 0); - - /** - * Writes a message to the output and adds a newline at the end. - * - * @param string|iterable $messages The message as an iterable of strings or a single string - * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL - */ - public function writeln($messages, int $options = 0); - - /** - * Sets the verbosity of the output. - */ - public function setVerbosity(int $level); - - /** - * Gets the current verbosity of the output. - * - * @return int - */ - public function getVerbosity(); - - /** - * Returns whether verbosity is quiet (-q). - * - * @return bool - */ - public function isQuiet(); - - /** - * Returns whether verbosity is verbose (-v). - * - * @return bool - */ - public function isVerbose(); - - /** - * Returns whether verbosity is very verbose (-vv). - * - * @return bool - */ - public function isVeryVerbose(); - - /** - * Returns whether verbosity is debug (-vvv). - * - * @return bool - */ - public function isDebug(); - - /** - * Sets the decorated flag. - */ - public function setDecorated(bool $decorated); - - /** - * Gets the decorated flag. - * - * @return bool - */ - public function isDecorated(); - - public function setFormatter(OutputFormatterInterface $formatter); - - /** - * Returns current output formatter instance. - * - * @return OutputFormatterInterface - */ - public function getFormatter(); -} diff --git a/vendor/symfony/console/Output/StreamOutput.php b/vendor/symfony/console/Output/StreamOutput.php deleted file mode 100644 index 7f5551827..000000000 --- a/vendor/symfony/console/Output/StreamOutput.php +++ /dev/null @@ -1,115 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Output; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Formatter\OutputFormatterInterface; - -/** - * StreamOutput writes the output to a given stream. - * - * Usage: - * - * $output = new StreamOutput(fopen('php://stdout', 'w')); - * - * As `StreamOutput` can use any stream, you can also use a file: - * - * $output = new StreamOutput(fopen('/path/to/output.log', 'a', false)); - * - * @author Fabien Potencier - */ -class StreamOutput extends Output -{ - private $stream; - - /** - * @param resource $stream A stream resource - * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) - * @param bool|null $decorated Whether to decorate messages (null for auto-guessing) - * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) - * - * @throws InvalidArgumentException When first argument is not a real stream - */ - public function __construct($stream, int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null) - { - if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) { - throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.'); - } - - $this->stream = $stream; - - if (null === $decorated) { - $decorated = $this->hasColorSupport(); - } - - parent::__construct($verbosity, $decorated, $formatter); - } - - /** - * Gets the stream attached to this StreamOutput instance. - * - * @return resource - */ - public function getStream() - { - return $this->stream; - } - - /** - * {@inheritdoc} - */ - protected function doWrite(string $message, bool $newline) - { - if ($newline) { - $message .= \PHP_EOL; - } - - @fwrite($this->stream, $message); - - fflush($this->stream); - } - - /** - * Returns true if the stream supports colorization. - * - * Colorization is disabled if not supported by the stream: - * - * This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo - * terminals via named pipes, so we can only check the environment. - * - * Reference: Composer\XdebugHandler\Process::supportsColor - * https://github.com/composer/xdebug-handler - * - * @return bool true if the stream supports colorization, false otherwise - */ - protected function hasColorSupport() - { - // Follow https://no-color.org/ - if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) { - return false; - } - - if ('Hyper' === getenv('TERM_PROGRAM')) { - return true; - } - - if (\DIRECTORY_SEPARATOR === '\\') { - return (\function_exists('sapi_windows_vt100_support') - && @sapi_windows_vt100_support($this->stream)) - || false !== getenv('ANSICON') - || 'ON' === getenv('ConEmuANSI') - || 'xterm' === getenv('TERM'); - } - - return stream_isatty($this->stream); - } -} diff --git a/vendor/symfony/console/Output/TrimmedBufferOutput.php b/vendor/symfony/console/Output/TrimmedBufferOutput.php deleted file mode 100644 index 3f4d375f4..000000000 --- a/vendor/symfony/console/Output/TrimmedBufferOutput.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. - */ - -namespace Symfony\Component\Console\Output; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Formatter\OutputFormatterInterface; - -/** - * A BufferedOutput that keeps only the last N chars. - * - * @author Jérémy Derussé - */ -class TrimmedBufferOutput extends Output -{ - private $maxLength; - private $buffer = ''; - - public function __construct(int $maxLength, ?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, OutputFormatterInterface $formatter = null) - { - if ($maxLength <= 0) { - throw new InvalidArgumentException(sprintf('"%s()" expects a strictly positive maxLength. Got %d.', __METHOD__, $maxLength)); - } - - parent::__construct($verbosity, $decorated, $formatter); - $this->maxLength = $maxLength; - } - - /** - * Empties buffer and returns its content. - * - * @return string - */ - public function fetch() - { - $content = $this->buffer; - $this->buffer = ''; - - return $content; - } - - /** - * {@inheritdoc} - */ - protected function doWrite(string $message, bool $newline) - { - $this->buffer .= $message; - - if ($newline) { - $this->buffer .= \PHP_EOL; - } - - $this->buffer = substr($this->buffer, 0 - $this->maxLength); - } -} diff --git a/vendor/symfony/console/Question/ChoiceQuestion.php b/vendor/symfony/console/Question/ChoiceQuestion.php deleted file mode 100644 index bf1f90487..000000000 --- a/vendor/symfony/console/Question/ChoiceQuestion.php +++ /dev/null @@ -1,183 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Question; - -use Symfony\Component\Console\Exception\InvalidArgumentException; - -/** - * Represents a choice question. - * - * @author Fabien Potencier - */ -class ChoiceQuestion extends Question -{ - private $choices; - private $multiselect = false; - private $prompt = ' > '; - private $errorMessage = 'Value "%s" is invalid'; - - /** - * @param string $question The question to ask to the user - * @param array $choices The list of available choices - * @param mixed $default The default answer to return - */ - public function __construct(string $question, array $choices, $default = null) - { - if (!$choices) { - throw new \LogicException('Choice question must have at least 1 choice available.'); - } - - parent::__construct($question, $default); - - $this->choices = $choices; - $this->setValidator($this->getDefaultValidator()); - $this->setAutocompleterValues($choices); - } - - /** - * Returns available choices. - * - * @return array - */ - public function getChoices() - { - return $this->choices; - } - - /** - * Sets multiselect option. - * - * When multiselect is set to true, multiple choices can be answered. - * - * @return $this - */ - public function setMultiselect(bool $multiselect) - { - $this->multiselect = $multiselect; - $this->setValidator($this->getDefaultValidator()); - - return $this; - } - - /** - * Returns whether the choices are multiselect. - * - * @return bool - */ - public function isMultiselect() - { - return $this->multiselect; - } - - /** - * Gets the prompt for choices. - * - * @return string - */ - public function getPrompt() - { - return $this->prompt; - } - - /** - * Sets the prompt for choices. - * - * @return $this - */ - public function setPrompt(string $prompt) - { - $this->prompt = $prompt; - - return $this; - } - - /** - * Sets the error message for invalid values. - * - * The error message has a string placeholder (%s) for the invalid value. - * - * @return $this - */ - public function setErrorMessage(string $errorMessage) - { - $this->errorMessage = $errorMessage; - $this->setValidator($this->getDefaultValidator()); - - return $this; - } - - private function getDefaultValidator(): callable - { - $choices = $this->choices; - $errorMessage = $this->errorMessage; - $multiselect = $this->multiselect; - $isAssoc = $this->isAssoc($choices); - - return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) { - if ($multiselect) { - // Check for a separated comma values - if (!preg_match('/^[^,]+(?:,[^,]+)*$/', (string) $selected, $matches)) { - throw new InvalidArgumentException(sprintf($errorMessage, $selected)); - } - - $selectedChoices = explode(',', (string) $selected); - } else { - $selectedChoices = [$selected]; - } - - if ($this->isTrimmable()) { - foreach ($selectedChoices as $k => $v) { - $selectedChoices[$k] = trim((string) $v); - } - } - - $multiselectChoices = []; - foreach ($selectedChoices as $value) { - $results = []; - foreach ($choices as $key => $choice) { - if ($choice === $value) { - $results[] = $key; - } - } - - if (\count($results) > 1) { - throw new InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of "%s".', implode('" or "', $results))); - } - - $result = array_search($value, $choices); - - if (!$isAssoc) { - if (false !== $result) { - $result = $choices[$result]; - } elseif (isset($choices[$value])) { - $result = $choices[$value]; - } - } elseif (false === $result && isset($choices[$value])) { - $result = $value; - } - - if (false === $result) { - throw new InvalidArgumentException(sprintf($errorMessage, $value)); - } - - // For associative choices, consistently return the key as string: - $multiselectChoices[] = $isAssoc ? (string) $result : $result; - } - - if ($multiselect) { - return $multiselectChoices; - } - - return current($multiselectChoices); - }; - } -} diff --git a/vendor/symfony/console/Question/ConfirmationQuestion.php b/vendor/symfony/console/Question/ConfirmationQuestion.php deleted file mode 100644 index 4228521b9..000000000 --- a/vendor/symfony/console/Question/ConfirmationQuestion.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Question; - -/** - * Represents a yes/no question. - * - * @author Fabien Potencier - */ -class ConfirmationQuestion extends Question -{ - private $trueAnswerRegex; - - /** - * @param string $question The question to ask to the user - * @param bool $default The default answer to return, true or false - * @param string $trueAnswerRegex A regex to match the "yes" answer - */ - public function __construct(string $question, bool $default = true, string $trueAnswerRegex = '/^y/i') - { - parent::__construct($question, $default); - - $this->trueAnswerRegex = $trueAnswerRegex; - $this->setNormalizer($this->getDefaultNormalizer()); - } - - /** - * Returns the default answer normalizer. - */ - private function getDefaultNormalizer(): callable - { - $default = $this->getDefault(); - $regex = $this->trueAnswerRegex; - - return function ($answer) use ($default, $regex) { - if (\is_bool($answer)) { - return $answer; - } - - $answerIsTrue = (bool) preg_match($regex, $answer); - if (false === $default) { - return $answer && $answerIsTrue; - } - - return '' === $answer || $answerIsTrue; - }; - } -} diff --git a/vendor/symfony/console/Question/Question.php b/vendor/symfony/console/Question/Question.php deleted file mode 100644 index 3a73f04b2..000000000 --- a/vendor/symfony/console/Question/Question.php +++ /dev/null @@ -1,299 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Question; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\LogicException; - -/** - * Represents a Question. - * - * @author Fabien Potencier - */ -class Question -{ - private $question; - private $attempts; - private $hidden = false; - private $hiddenFallback = true; - private $autocompleterCallback; - private $validator; - private $default; - private $normalizer; - private $trimmable = true; - private $multiline = false; - - /** - * @param string $question The question to ask to the user - * @param string|bool|int|float|null $default The default answer to return if the user enters nothing - */ - public function __construct(string $question, $default = null) - { - $this->question = $question; - $this->default = $default; - } - - /** - * Returns the question. - * - * @return string - */ - public function getQuestion() - { - return $this->question; - } - - /** - * Returns the default answer. - * - * @return string|bool|int|float|null - */ - public function getDefault() - { - return $this->default; - } - - /** - * Returns whether the user response accepts newline characters. - */ - public function isMultiline(): bool - { - return $this->multiline; - } - - /** - * Sets whether the user response should accept newline characters. - * - * @return $this - */ - public function setMultiline(bool $multiline): self - { - $this->multiline = $multiline; - - return $this; - } - - /** - * Returns whether the user response must be hidden. - * - * @return bool - */ - public function isHidden() - { - return $this->hidden; - } - - /** - * Sets whether the user response must be hidden or not. - * - * @return $this - * - * @throws LogicException In case the autocompleter is also used - */ - public function setHidden(bool $hidden) - { - if ($this->autocompleterCallback) { - throw new LogicException('A hidden question cannot use the autocompleter.'); - } - - $this->hidden = $hidden; - - return $this; - } - - /** - * In case the response cannot be hidden, whether to fallback on non-hidden question or not. - * - * @return bool - */ - public function isHiddenFallback() - { - return $this->hiddenFallback; - } - - /** - * Sets whether to fallback on non-hidden question if the response cannot be hidden. - * - * @return $this - */ - public function setHiddenFallback(bool $fallback) - { - $this->hiddenFallback = $fallback; - - return $this; - } - - /** - * Gets values for the autocompleter. - * - * @return iterable|null - */ - public function getAutocompleterValues() - { - $callback = $this->getAutocompleterCallback(); - - return $callback ? $callback('') : null; - } - - /** - * Sets values for the autocompleter. - * - * @return $this - * - * @throws LogicException - */ - public function setAutocompleterValues(?iterable $values) - { - if (\is_array($values)) { - $values = $this->isAssoc($values) ? array_merge(array_keys($values), array_values($values)) : array_values($values); - - $callback = static function () use ($values) { - return $values; - }; - } elseif ($values instanceof \Traversable) { - $valueCache = null; - $callback = static function () use ($values, &$valueCache) { - return $valueCache ?? $valueCache = iterator_to_array($values, false); - }; - } else { - $callback = null; - } - - return $this->setAutocompleterCallback($callback); - } - - /** - * Gets the callback function used for the autocompleter. - */ - public function getAutocompleterCallback(): ?callable - { - return $this->autocompleterCallback; - } - - /** - * Sets the callback function used for the autocompleter. - * - * The callback is passed the user input as argument and should return an iterable of corresponding suggestions. - * - * @return $this - */ - public function setAutocompleterCallback(callable $callback = null): self - { - if ($this->hidden && null !== $callback) { - throw new LogicException('A hidden question cannot use the autocompleter.'); - } - - $this->autocompleterCallback = $callback; - - return $this; - } - - /** - * Sets a validator for the question. - * - * @return $this - */ - public function setValidator(callable $validator = null) - { - $this->validator = $validator; - - return $this; - } - - /** - * Gets the validator for the question. - * - * @return callable|null - */ - public function getValidator() - { - return $this->validator; - } - - /** - * Sets the maximum number of attempts. - * - * Null means an unlimited number of attempts. - * - * @return $this - * - * @throws InvalidArgumentException in case the number of attempts is invalid - */ - public function setMaxAttempts(?int $attempts) - { - if (null !== $attempts && $attempts < 1) { - throw new InvalidArgumentException('Maximum number of attempts must be a positive value.'); - } - - $this->attempts = $attempts; - - return $this; - } - - /** - * Gets the maximum number of attempts. - * - * Null means an unlimited number of attempts. - * - * @return int|null - */ - public function getMaxAttempts() - { - return $this->attempts; - } - - /** - * Sets a normalizer for the response. - * - * The normalizer can be a callable (a string), a closure or a class implementing __invoke. - * - * @return $this - */ - public function setNormalizer(callable $normalizer) - { - $this->normalizer = $normalizer; - - return $this; - } - - /** - * Gets the normalizer for the response. - * - * The normalizer can ba a callable (a string), a closure or a class implementing __invoke. - * - * @return callable|null - */ - public function getNormalizer() - { - return $this->normalizer; - } - - protected function isAssoc(array $array) - { - return (bool) \count(array_filter(array_keys($array), 'is_string')); - } - - public function isTrimmable(): bool - { - return $this->trimmable; - } - - /** - * @return $this - */ - public function setTrimmable(bool $trimmable): self - { - $this->trimmable = $trimmable; - - return $this; - } -} diff --git a/vendor/symfony/console/Resources/bin/hiddeninput.exe b/vendor/symfony/console/Resources/bin/hiddeninput.exe deleted file mode 100644 index c8cf65e8d819e6e525121cf6b21f1c2429746038..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9216 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 J0sQ~1{4brj`U(I5 diff --git a/vendor/symfony/console/SignalRegistry/SignalRegistry.php b/vendor/symfony/console/SignalRegistry/SignalRegistry.php deleted file mode 100644 index 6bee24a42..000000000 --- a/vendor/symfony/console/SignalRegistry/SignalRegistry.php +++ /dev/null @@ -1,65 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\SignalRegistry; - -final class SignalRegistry -{ - private $signalHandlers = []; - - public function __construct() - { - if (\function_exists('pcntl_async_signals')) { - pcntl_async_signals(true); - } - } - - public function register(int $signal, callable $signalHandler): void - { - if (!isset($this->signalHandlers[$signal])) { - $previousCallback = pcntl_signal_get_handler($signal); - - if (\is_callable($previousCallback)) { - $this->signalHandlers[$signal][] = $previousCallback; - } - } - - $this->signalHandlers[$signal][] = $signalHandler; - - pcntl_signal($signal, [$this, 'handle']); - } - - public static function isSupported(): bool - { - if (!\function_exists('pcntl_signal')) { - return false; - } - - if (\in_array('pcntl_signal', explode(',', \ini_get('disable_functions')))) { - return false; - } - - return true; - } - - /** - * @internal - */ - public function handle(int $signal): void - { - $count = \count($this->signalHandlers[$signal]); - - foreach ($this->signalHandlers[$signal] as $i => $signalHandler) { - $hasNext = $i !== $count - 1; - $signalHandler($signal, $hasNext); - } - } -} diff --git a/vendor/symfony/console/SingleCommandApplication.php b/vendor/symfony/console/SingleCommandApplication.php deleted file mode 100644 index e93c1821b..000000000 --- a/vendor/symfony/console/SingleCommandApplication.php +++ /dev/null @@ -1,72 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * @author Grégoire Pineau - */ -class SingleCommandApplication extends Command -{ - private $version = 'UNKNOWN'; - private $autoExit = true; - private $running = false; - - /** - * @return $this - */ - public function setVersion(string $version): self - { - $this->version = $version; - - return $this; - } - - /** - * @final - * - * @return $this - */ - public function setAutoExit(bool $autoExit): self - { - $this->autoExit = $autoExit; - - return $this; - } - - public function run(InputInterface $input = null, OutputInterface $output = null): int - { - if ($this->running) { - return parent::run($input, $output); - } - - // We use the command name as the application name - $application = new Application($this->getName() ?: 'UNKNOWN', $this->version); - $application->setAutoExit($this->autoExit); - // Fix the usage of the command displayed with "--help" - $this->setName($_SERVER['argv'][0]); - $application->add($this); - $application->setDefaultCommand($this->getName(), true); - - $this->running = true; - try { - $ret = $application->run($input, $output); - } finally { - $this->running = false; - } - - return $ret ?? 1; - } -} diff --git a/vendor/symfony/console/Style/OutputStyle.php b/vendor/symfony/console/Style/OutputStyle.php deleted file mode 100644 index 67a98ff07..000000000 --- a/vendor/symfony/console/Style/OutputStyle.php +++ /dev/null @@ -1,153 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Style; - -use Symfony\Component\Console\Formatter\OutputFormatterInterface; -use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Output\ConsoleOutputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Decorates output to add console style guide helpers. - * - * @author Kevin Bond - */ -abstract class OutputStyle implements OutputInterface, StyleInterface -{ - private $output; - - public function __construct(OutputInterface $output) - { - $this->output = $output; - } - - /** - * {@inheritdoc} - */ - public function newLine(int $count = 1) - { - $this->output->write(str_repeat(\PHP_EOL, $count)); - } - - /** - * @return ProgressBar - */ - public function createProgressBar(int $max = 0) - { - return new ProgressBar($this->output, $max); - } - - /** - * {@inheritdoc} - */ - public function write($messages, bool $newline = false, int $type = self::OUTPUT_NORMAL) - { - $this->output->write($messages, $newline, $type); - } - - /** - * {@inheritdoc} - */ - public function writeln($messages, int $type = self::OUTPUT_NORMAL) - { - $this->output->writeln($messages, $type); - } - - /** - * {@inheritdoc} - */ - public function setVerbosity(int $level) - { - $this->output->setVerbosity($level); - } - - /** - * {@inheritdoc} - */ - public function getVerbosity() - { - return $this->output->getVerbosity(); - } - - /** - * {@inheritdoc} - */ - public function setDecorated(bool $decorated) - { - $this->output->setDecorated($decorated); - } - - /** - * {@inheritdoc} - */ - public function isDecorated() - { - return $this->output->isDecorated(); - } - - /** - * {@inheritdoc} - */ - public function setFormatter(OutputFormatterInterface $formatter) - { - $this->output->setFormatter($formatter); - } - - /** - * {@inheritdoc} - */ - public function getFormatter() - { - return $this->output->getFormatter(); - } - - /** - * {@inheritdoc} - */ - public function isQuiet() - { - return $this->output->isQuiet(); - } - - /** - * {@inheritdoc} - */ - public function isVerbose() - { - return $this->output->isVerbose(); - } - - /** - * {@inheritdoc} - */ - public function isVeryVerbose() - { - return $this->output->isVeryVerbose(); - } - - /** - * {@inheritdoc} - */ - public function isDebug() - { - return $this->output->isDebug(); - } - - protected function getErrorOutput() - { - if (!$this->output instanceof ConsoleOutputInterface) { - return $this->output; - } - - return $this->output->getErrorOutput(); - } -} diff --git a/vendor/symfony/console/Style/StyleInterface.php b/vendor/symfony/console/Style/StyleInterface.php deleted file mode 100644 index 38d23b77e..000000000 --- a/vendor/symfony/console/Style/StyleInterface.php +++ /dev/null @@ -1,132 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Style; - -/** - * Output style helpers. - * - * @author Kevin Bond - */ -interface StyleInterface -{ - /** - * Formats a command title. - */ - public function title(string $message); - - /** - * Formats a section title. - */ - public function section(string $message); - - /** - * Formats a list. - */ - public function listing(array $elements); - - /** - * Formats informational text. - * - * @param string|array $message - */ - public function text($message); - - /** - * Formats a success result bar. - * - * @param string|array $message - */ - public function success($message); - - /** - * Formats an error result bar. - * - * @param string|array $message - */ - public function error($message); - - /** - * Formats an warning result bar. - * - * @param string|array $message - */ - public function warning($message); - - /** - * Formats a note admonition. - * - * @param string|array $message - */ - public function note($message); - - /** - * Formats a caution admonition. - * - * @param string|array $message - */ - public function caution($message); - - /** - * Formats a table. - */ - public function table(array $headers, array $rows); - - /** - * Asks a question. - * - * @return mixed - */ - public function ask(string $question, string $default = null, callable $validator = null); - - /** - * Asks a question with the user input hidden. - * - * @return mixed - */ - public function askHidden(string $question, callable $validator = null); - - /** - * Asks for confirmation. - * - * @return bool - */ - public function confirm(string $question, bool $default = true); - - /** - * Asks a choice question. - * - * @param string|int|null $default - * - * @return mixed - */ - public function choice(string $question, array $choices, $default = null); - - /** - * Add newline(s). - */ - public function newLine(int $count = 1); - - /** - * Starts the progress output. - */ - public function progressStart(int $max = 0); - - /** - * Advances the progress output X steps. - */ - public function progressAdvance(int $step = 1); - - /** - * Finishes the progress output. - */ - public function progressFinish(); -} diff --git a/vendor/symfony/console/Style/SymfonyStyle.php b/vendor/symfony/console/Style/SymfonyStyle.php deleted file mode 100644 index e3c5ac8e7..000000000 --- a/vendor/symfony/console/Style/SymfonyStyle.php +++ /dev/null @@ -1,518 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Style; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\RuntimeException; -use Symfony\Component\Console\Formatter\OutputFormatter; -use Symfony\Component\Console\Helper\Helper; -use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Helper\SymfonyQuestionHelper; -use Symfony\Component\Console\Helper\Table; -use Symfony\Component\Console\Helper\TableCell; -use Symfony\Component\Console\Helper\TableSeparator; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\ConsoleOutputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Output\TrimmedBufferOutput; -use Symfony\Component\Console\Question\ChoiceQuestion; -use Symfony\Component\Console\Question\ConfirmationQuestion; -use Symfony\Component\Console\Question\Question; -use Symfony\Component\Console\Terminal; - -/** - * Output decorator helpers for the Symfony Style Guide. - * - * @author Kevin Bond - */ -class SymfonyStyle extends OutputStyle -{ - public const MAX_LINE_LENGTH = 120; - - private $input; - private $output; - private $questionHelper; - private $progressBar; - private $lineLength; - private $bufferedOutput; - - public function __construct(InputInterface $input, OutputInterface $output) - { - $this->input = $input; - $this->bufferedOutput = new TrimmedBufferOutput(\DIRECTORY_SEPARATOR === '\\' ? 4 : 2, $output->getVerbosity(), false, clone $output->getFormatter()); - // Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not. - $width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH; - $this->lineLength = min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH); - - parent::__construct($this->output = $output); - } - - /** - * Formats a message as a block of text. - * - * @param string|array $messages The message to write in the block - */ - public function block($messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = true) - { - $messages = \is_array($messages) ? array_values($messages) : [$messages]; - - $this->autoPrependBlock(); - $this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, $escape)); - $this->newLine(); - } - - /** - * {@inheritdoc} - */ - public function title(string $message) - { - $this->autoPrependBlock(); - $this->writeln([ - sprintf('%s', OutputFormatter::escapeTrailingBackslash($message)), - sprintf('%s', str_repeat('=', Helper::width(Helper::removeDecoration($this->getFormatter(), $message)))), - ]); - $this->newLine(); - } - - /** - * {@inheritdoc} - */ - public function section(string $message) - { - $this->autoPrependBlock(); - $this->writeln([ - sprintf('%s', OutputFormatter::escapeTrailingBackslash($message)), - sprintf('%s', str_repeat('-', Helper::width(Helper::removeDecoration($this->getFormatter(), $message)))), - ]); - $this->newLine(); - } - - /** - * {@inheritdoc} - */ - public function listing(array $elements) - { - $this->autoPrependText(); - $elements = array_map(function ($element) { - return sprintf(' * %s', $element); - }, $elements); - - $this->writeln($elements); - $this->newLine(); - } - - /** - * {@inheritdoc} - */ - public function text($message) - { - $this->autoPrependText(); - - $messages = \is_array($message) ? array_values($message) : [$message]; - foreach ($messages as $message) { - $this->writeln(sprintf(' %s', $message)); - } - } - - /** - * Formats a command comment. - * - * @param string|array $message - */ - public function comment($message) - { - $this->block($message, null, null, ' // ', false, false); - } - - /** - * {@inheritdoc} - */ - public function success($message) - { - $this->block($message, 'OK', 'fg=black;bg=green', ' ', true); - } - - /** - * {@inheritdoc} - */ - public function error($message) - { - $this->block($message, 'ERROR', 'fg=white;bg=red', ' ', true); - } - - /** - * {@inheritdoc} - */ - public function warning($message) - { - $this->block($message, 'WARNING', 'fg=black;bg=yellow', ' ', true); - } - - /** - * {@inheritdoc} - */ - public function note($message) - { - $this->block($message, 'NOTE', 'fg=yellow', ' ! '); - } - - /** - * Formats an info message. - * - * @param string|array $message - */ - public function info($message) - { - $this->block($message, 'INFO', 'fg=green', ' ', true); - } - - /** - * {@inheritdoc} - */ - public function caution($message) - { - $this->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', true); - } - - /** - * {@inheritdoc} - */ - public function table(array $headers, array $rows) - { - $this->createTable() - ->setHeaders($headers) - ->setRows($rows) - ->render() - ; - - $this->newLine(); - } - - /** - * Formats a horizontal table. - */ - public function horizontalTable(array $headers, array $rows) - { - $this->createTable() - ->setHorizontal(true) - ->setHeaders($headers) - ->setRows($rows) - ->render() - ; - - $this->newLine(); - } - - /** - * Formats a list of key/value horizontally. - * - * Each row can be one of: - * * 'A title' - * * ['key' => 'value'] - * * new TableSeparator() - * - * @param string|array|TableSeparator ...$list - */ - public function definitionList(...$list) - { - $headers = []; - $row = []; - foreach ($list as $value) { - if ($value instanceof TableSeparator) { - $headers[] = $value; - $row[] = $value; - continue; - } - if (\is_string($value)) { - $headers[] = new TableCell($value, ['colspan' => 2]); - $row[] = null; - continue; - } - if (!\is_array($value)) { - throw new InvalidArgumentException('Value should be an array, string, or an instance of TableSeparator.'); - } - $headers[] = key($value); - $row[] = current($value); - } - - $this->horizontalTable($headers, [$row]); - } - - /** - * {@inheritdoc} - */ - public function ask(string $question, string $default = null, callable $validator = null) - { - $question = new Question($question, $default); - $question->setValidator($validator); - - return $this->askQuestion($question); - } - - /** - * {@inheritdoc} - */ - public function askHidden(string $question, callable $validator = null) - { - $question = new Question($question); - - $question->setHidden(true); - $question->setValidator($validator); - - return $this->askQuestion($question); - } - - /** - * {@inheritdoc} - */ - public function confirm(string $question, bool $default = true) - { - return $this->askQuestion(new ConfirmationQuestion($question, $default)); - } - - /** - * {@inheritdoc} - */ - public function choice(string $question, array $choices, $default = null) - { - if (null !== $default) { - $values = array_flip($choices); - $default = $values[$default] ?? $default; - } - - return $this->askQuestion(new ChoiceQuestion($question, $choices, $default)); - } - - /** - * {@inheritdoc} - */ - public function progressStart(int $max = 0) - { - $this->progressBar = $this->createProgressBar($max); - $this->progressBar->start(); - } - - /** - * {@inheritdoc} - */ - public function progressAdvance(int $step = 1) - { - $this->getProgressBar()->advance($step); - } - - /** - * {@inheritdoc} - */ - public function progressFinish() - { - $this->getProgressBar()->finish(); - $this->newLine(2); - $this->progressBar = null; - } - - /** - * {@inheritdoc} - */ - public function createProgressBar(int $max = 0) - { - $progressBar = parent::createProgressBar($max); - - if ('\\' !== \DIRECTORY_SEPARATOR || 'Hyper' === getenv('TERM_PROGRAM')) { - $progressBar->setEmptyBarCharacter('░'); // light shade character \u2591 - $progressBar->setProgressCharacter(''); - $progressBar->setBarCharacter('▓'); // dark shade character \u2593 - } - - return $progressBar; - } - - /** - * @see ProgressBar::iterate() - */ - public function progressIterate(iterable $iterable, int $max = null): iterable - { - yield from $this->createProgressBar()->iterate($iterable, $max); - - $this->newLine(2); - } - - /** - * @return mixed - */ - public function askQuestion(Question $question) - { - if ($this->input->isInteractive()) { - $this->autoPrependBlock(); - } - - if (!$this->questionHelper) { - $this->questionHelper = new SymfonyQuestionHelper(); - } - - $answer = $this->questionHelper->ask($this->input, $this, $question); - - if ($this->input->isInteractive()) { - $this->newLine(); - $this->bufferedOutput->write("\n"); - } - - return $answer; - } - - /** - * {@inheritdoc} - */ - public function writeln($messages, int $type = self::OUTPUT_NORMAL) - { - if (!is_iterable($messages)) { - $messages = [$messages]; - } - - foreach ($messages as $message) { - parent::writeln($message, $type); - $this->writeBuffer($message, true, $type); - } - } - - /** - * {@inheritdoc} - */ - public function write($messages, bool $newline = false, int $type = self::OUTPUT_NORMAL) - { - if (!is_iterable($messages)) { - $messages = [$messages]; - } - - foreach ($messages as $message) { - parent::write($message, $newline, $type); - $this->writeBuffer($message, $newline, $type); - } - } - - /** - * {@inheritdoc} - */ - public function newLine(int $count = 1) - { - parent::newLine($count); - $this->bufferedOutput->write(str_repeat("\n", $count)); - } - - /** - * Returns a new instance which makes use of stderr if available. - * - * @return self - */ - public function getErrorStyle() - { - return new self($this->input, $this->getErrorOutput()); - } - - public function createTable(): Table - { - $output = $this->output instanceof ConsoleOutputInterface ? $this->output->section() : $this->output; - $style = clone Table::getStyleDefinition('symfony-style-guide'); - $style->setCellHeaderFormat('%s'); - - return (new Table($output))->setStyle($style); - } - - private function getProgressBar(): ProgressBar - { - if (!$this->progressBar) { - throw new RuntimeException('The ProgressBar is not started.'); - } - - return $this->progressBar; - } - - private function autoPrependBlock(): void - { - $chars = substr(str_replace(\PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2); - - if (!isset($chars[0])) { - $this->newLine(); // empty history, so we should start with a new line. - - return; - } - // Prepend new line for each non LF chars (This means no blank line was output before) - $this->newLine(2 - substr_count($chars, "\n")); - } - - private function autoPrependText(): void - { - $fetched = $this->bufferedOutput->fetch(); - // Prepend new line if last char isn't EOL: - if (!str_ends_with($fetched, "\n")) { - $this->newLine(); - } - } - - private function writeBuffer(string $message, bool $newLine, int $type): void - { - // We need to know if the last chars are PHP_EOL - $this->bufferedOutput->write($message, $newLine, $type); - } - - private function createBlock(iterable $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = false): array - { - $indentLength = 0; - $prefixLength = Helper::width(Helper::removeDecoration($this->getFormatter(), $prefix)); - $lines = []; - - if (null !== $type) { - $type = sprintf('[%s] ', $type); - $indentLength = \strlen($type); - $lineIndentation = str_repeat(' ', $indentLength); - } - - // wrap and add newlines for each element - foreach ($messages as $key => $message) { - if ($escape) { - $message = OutputFormatter::escape($message); - } - - $decorationLength = Helper::width($message) - Helper::width(Helper::removeDecoration($this->getFormatter(), $message)); - $messageLineLength = min($this->lineLength - $prefixLength - $indentLength + $decorationLength, $this->lineLength); - $messageLines = explode(\PHP_EOL, wordwrap($message, $messageLineLength, \PHP_EOL, true)); - foreach ($messageLines as $messageLine) { - $lines[] = $messageLine; - } - - if (\count($messages) > 1 && $key < \count($messages) - 1) { - $lines[] = ''; - } - } - - $firstLineIndex = 0; - if ($padding && $this->isDecorated()) { - $firstLineIndex = 1; - array_unshift($lines, ''); - $lines[] = ''; - } - - foreach ($lines as $i => &$line) { - if (null !== $type) { - $line = $firstLineIndex === $i ? $type.$line : $lineIndentation.$line; - } - - $line = $prefix.$line; - $line .= str_repeat(' ', max($this->lineLength - Helper::width(Helper::removeDecoration($this->getFormatter(), $line)), 0)); - - if ($style) { - $line = sprintf('<%s>%s', $style, $line); - } - } - - return $lines; - } -} diff --git a/vendor/symfony/console/Terminal.php b/vendor/symfony/console/Terminal.php deleted file mode 100644 index 08c53535b..000000000 --- a/vendor/symfony/console/Terminal.php +++ /dev/null @@ -1,172 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console; - -class Terminal -{ - private static $width; - private static $height; - private static $stty; - - /** - * Gets the terminal width. - * - * @return int - */ - public function getWidth() - { - $width = getenv('COLUMNS'); - if (false !== $width) { - return (int) trim($width); - } - - if (null === self::$width) { - self::initDimensions(); - } - - return self::$width ?: 80; - } - - /** - * Gets the terminal height. - * - * @return int - */ - public function getHeight() - { - $height = getenv('LINES'); - if (false !== $height) { - return (int) trim($height); - } - - if (null === self::$height) { - self::initDimensions(); - } - - return self::$height ?: 50; - } - - /** - * @internal - */ - public static function hasSttyAvailable(): bool - { - if (null !== self::$stty) { - return self::$stty; - } - - // skip check if exec function is disabled - if (!\function_exists('exec')) { - return false; - } - - exec('stty 2>&1', $output, $exitcode); - - return self::$stty = 0 === $exitcode; - } - - private static function initDimensions() - { - if ('\\' === \DIRECTORY_SEPARATOR) { - if (preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim(getenv('ANSICON')), $matches)) { - // extract [w, H] from "wxh (WxH)" - // or [w, h] from "wxh" - self::$width = (int) $matches[1]; - self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2]; - } elseif (!self::hasVt100Support() && self::hasSttyAvailable()) { - // only use stty on Windows if the terminal does not support vt100 (e.g. Windows 7 + git-bash) - // testing for stty in a Windows 10 vt100-enabled console will implicitly disable vt100 support on STDOUT - self::initDimensionsUsingStty(); - } elseif (null !== $dimensions = self::getConsoleMode()) { - // extract [w, h] from "wxh" - self::$width = (int) $dimensions[0]; - self::$height = (int) $dimensions[1]; - } - } else { - self::initDimensionsUsingStty(); - } - } - - /** - * Returns whether STDOUT has vt100 support (some Windows 10+ configurations). - */ - private static function hasVt100Support(): bool - { - return \function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support(fopen('php://stdout', 'w')); - } - - /** - * Initializes dimensions using the output of an stty columns line. - */ - private static function initDimensionsUsingStty() - { - if ($sttyString = self::getSttyColumns()) { - if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) { - // extract [w, h] from "rows h; columns w;" - self::$width = (int) $matches[2]; - self::$height = (int) $matches[1]; - } elseif (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) { - // extract [w, h] from "; h rows; w columns" - self::$width = (int) $matches[2]; - self::$height = (int) $matches[1]; - } - } - } - - /** - * Runs and parses mode CON if it's available, suppressing any error output. - * - * @return int[]|null An array composed of the width and the height or null if it could not be parsed - */ - private static function getConsoleMode(): ?array - { - $info = self::readFromProcess('mode CON'); - - if (null === $info || !preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) { - return null; - } - - return [(int) $matches[2], (int) $matches[1]]; - } - - /** - * Runs and parses stty -a if it's available, suppressing any error output. - */ - private static function getSttyColumns(): ?string - { - return self::readFromProcess('stty -a | grep columns'); - } - - private static function readFromProcess(string $command): ?string - { - if (!\function_exists('proc_open')) { - return null; - } - - $descriptorspec = [ - 1 => ['pipe', 'w'], - 2 => ['pipe', 'w'], - ]; - - $process = proc_open($command, $descriptorspec, $pipes, null, null, ['suppress_errors' => true]); - if (!\is_resource($process)) { - return null; - } - - $info = stream_get_contents($pipes[1]); - fclose($pipes[1]); - fclose($pipes[2]); - proc_close($process); - - return $info; - } -} diff --git a/vendor/symfony/console/Tester/ApplicationTester.php b/vendor/symfony/console/Tester/ApplicationTester.php deleted file mode 100644 index 3a262e81c..000000000 --- a/vendor/symfony/console/Tester/ApplicationTester.php +++ /dev/null @@ -1,85 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Tester; - -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Input\ArrayInput; - -/** - * Eases the testing of console applications. - * - * When testing an application, don't forget to disable the auto exit flag: - * - * $application = new Application(); - * $application->setAutoExit(false); - * - * @author Fabien Potencier - */ -class ApplicationTester -{ - use TesterTrait; - - private $application; - - public function __construct(Application $application) - { - $this->application = $application; - } - - /** - * Executes the application. - * - * Available options: - * - * * interactive: Sets the input interactive flag - * * decorated: Sets the output decorated flag - * * verbosity: Sets the output verbosity flag - * * capture_stderr_separately: Make output of stdOut and stdErr separately available - * - * @return int The command exit code - */ - public function run(array $input, array $options = []) - { - $prevShellVerbosity = getenv('SHELL_VERBOSITY'); - - try { - $this->input = new ArrayInput($input); - if (isset($options['interactive'])) { - $this->input->setInteractive($options['interactive']); - } - - if ($this->inputs) { - $this->input->setStream(self::createStream($this->inputs)); - } - - $this->initOutput($options); - - return $this->statusCode = $this->application->run($this->input, $this->output); - } finally { - // SHELL_VERBOSITY is set by Application::configureIO so we need to unset/reset it - // to its previous value to avoid one test's verbosity to spread to the following tests - if (false === $prevShellVerbosity) { - if (\function_exists('putenv')) { - @putenv('SHELL_VERBOSITY'); - } - unset($_ENV['SHELL_VERBOSITY']); - unset($_SERVER['SHELL_VERBOSITY']); - } else { - if (\function_exists('putenv')) { - @putenv('SHELL_VERBOSITY='.$prevShellVerbosity); - } - $_ENV['SHELL_VERBOSITY'] = $prevShellVerbosity; - $_SERVER['SHELL_VERBOSITY'] = $prevShellVerbosity; - } - } - } -} diff --git a/vendor/symfony/console/Tester/CommandCompletionTester.php b/vendor/symfony/console/Tester/CommandCompletionTester.php deleted file mode 100644 index ade732752..000000000 --- a/vendor/symfony/console/Tester/CommandCompletionTester.php +++ /dev/null @@ -1,56 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Tester; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; - -/** - * Eases the testing of command completion. - * - * @author Jérôme Tamarelle - */ -class CommandCompletionTester -{ - private $command; - - public function __construct(Command $command) - { - $this->command = $command; - } - - /** - * Create completion suggestions from input tokens. - */ - public function complete(array $input): array - { - $currentIndex = \count($input); - if ('' === end($input)) { - array_pop($input); - } - array_unshift($input, $this->command->getName()); - - $completionInput = CompletionInput::fromTokens($input, $currentIndex); - $completionInput->bind($this->command->getDefinition()); - $suggestions = new CompletionSuggestions(); - - $this->command->complete($completionInput, $suggestions); - - $options = []; - foreach ($suggestions->getOptionSuggestions() as $option) { - $options[] = '--'.$option->getName(); - } - - return array_map('strval', array_merge($options, $suggestions->getValueSuggestions())); - } -} diff --git a/vendor/symfony/console/Tester/CommandTester.php b/vendor/symfony/console/Tester/CommandTester.php deleted file mode 100644 index 6c15c25fb..000000000 --- a/vendor/symfony/console/Tester/CommandTester.php +++ /dev/null @@ -1,76 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Tester; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\ArrayInput; - -/** - * Eases the testing of console commands. - * - * @author Fabien Potencier - * @author Robin Chalas - */ -class CommandTester -{ - use TesterTrait; - - private $command; - - public function __construct(Command $command) - { - $this->command = $command; - } - - /** - * Executes the command. - * - * Available execution options: - * - * * interactive: Sets the input interactive flag - * * decorated: Sets the output decorated flag - * * verbosity: Sets the output verbosity flag - * * capture_stderr_separately: Make output of stdOut and stdErr separately available - * - * @param array $input An array of command arguments and options - * @param array $options An array of execution options - * - * @return int The command exit code - */ - public function execute(array $input, array $options = []) - { - // set the command name automatically if the application requires - // this argument and no command name was passed - if (!isset($input['command']) - && (null !== $application = $this->command->getApplication()) - && $application->getDefinition()->hasArgument('command') - ) { - $input = array_merge(['command' => $this->command->getName()], $input); - } - - $this->input = new ArrayInput($input); - // Use an in-memory input stream even if no inputs are set so that QuestionHelper::ask() does not rely on the blocking STDIN. - $this->input->setStream(self::createStream($this->inputs)); - - if (isset($options['interactive'])) { - $this->input->setInteractive($options['interactive']); - } - - if (!isset($options['decorated'])) { - $options['decorated'] = false; - } - - $this->initOutput($options); - - return $this->statusCode = $this->command->run($this->input, $this->output); - } -} diff --git a/vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php b/vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php deleted file mode 100644 index a47324237..000000000 --- a/vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php +++ /dev/null @@ -1,55 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Tester\Constraint; - -use PHPUnit\Framework\Constraint\Constraint; -use Symfony\Component\Console\Command\Command; - -final class CommandIsSuccessful extends Constraint -{ - /** - * {@inheritdoc} - */ - public function toString(): string - { - return 'is successful'; - } - - /** - * {@inheritdoc} - */ - protected function matches($other): bool - { - return Command::SUCCESS === $other; - } - - /** - * {@inheritdoc} - */ - protected function failureDescription($other): string - { - return 'the command '.$this->toString(); - } - - /** - * {@inheritdoc} - */ - protected function additionalFailureDescription($other): string - { - $mapping = [ - Command::FAILURE => 'Command failed.', - Command::INVALID => 'Command was invalid.', - ]; - - return $mapping[$other] ?? sprintf('Command returned exit status %d.', $other); - } -} diff --git a/vendor/symfony/console/Tester/TesterTrait.php b/vendor/symfony/console/Tester/TesterTrait.php deleted file mode 100644 index 40bc58177..000000000 --- a/vendor/symfony/console/Tester/TesterTrait.php +++ /dev/null @@ -1,197 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Tester; - -use PHPUnit\Framework\Assert; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\ConsoleOutput; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Output\StreamOutput; -use Symfony\Component\Console\Tester\Constraint\CommandIsSuccessful; - -/** - * @author Amrouche Hamza - */ -trait TesterTrait -{ - /** @var StreamOutput */ - private $output; - private $inputs = []; - private $captureStreamsIndependently = false; - /** @var InputInterface */ - private $input; - /** @var int */ - private $statusCode; - - /** - * Gets the display returned by the last execution of the command or application. - * - * @throws \RuntimeException If it's called before the execute method - * - * @return string - */ - public function getDisplay(bool $normalize = false) - { - if (null === $this->output) { - throw new \RuntimeException('Output not initialized, did you execute the command before requesting the display?'); - } - - rewind($this->output->getStream()); - - $display = stream_get_contents($this->output->getStream()); - - if ($normalize) { - $display = str_replace(\PHP_EOL, "\n", $display); - } - - return $display; - } - - /** - * Gets the output written to STDERR by the application. - * - * @param bool $normalize Whether to normalize end of lines to \n or not - * - * @return string - */ - public function getErrorOutput(bool $normalize = false) - { - if (!$this->captureStreamsIndependently) { - throw new \LogicException('The error output is not available when the tester is run without "capture_stderr_separately" option set.'); - } - - rewind($this->output->getErrorOutput()->getStream()); - - $display = stream_get_contents($this->output->getErrorOutput()->getStream()); - - if ($normalize) { - $display = str_replace(\PHP_EOL, "\n", $display); - } - - return $display; - } - - /** - * Gets the input instance used by the last execution of the command or application. - * - * @return InputInterface - */ - public function getInput() - { - return $this->input; - } - - /** - * Gets the output instance used by the last execution of the command or application. - * - * @return OutputInterface - */ - public function getOutput() - { - return $this->output; - } - - /** - * Gets the status code returned by the last execution of the command or application. - * - * @throws \RuntimeException If it's called before the execute method - * - * @return int - */ - public function getStatusCode() - { - if (null === $this->statusCode) { - throw new \RuntimeException('Status code not initialized, did you execute the command before requesting the status code?'); - } - - return $this->statusCode; - } - - public function assertCommandIsSuccessful(string $message = ''): void - { - Assert::assertThat($this->statusCode, new CommandIsSuccessful(), $message); - } - - /** - * Sets the user inputs. - * - * @param array $inputs An array of strings representing each input - * passed to the command input stream - * - * @return $this - */ - public function setInputs(array $inputs) - { - $this->inputs = $inputs; - - return $this; - } - - /** - * Initializes the output property. - * - * Available options: - * - * * decorated: Sets the output decorated flag - * * verbosity: Sets the output verbosity flag - * * capture_stderr_separately: Make output of stdOut and stdErr separately available - */ - private function initOutput(array $options) - { - $this->captureStreamsIndependently = \array_key_exists('capture_stderr_separately', $options) && $options['capture_stderr_separately']; - if (!$this->captureStreamsIndependently) { - $this->output = new StreamOutput(fopen('php://memory', 'w', false)); - if (isset($options['decorated'])) { - $this->output->setDecorated($options['decorated']); - } - if (isset($options['verbosity'])) { - $this->output->setVerbosity($options['verbosity']); - } - } else { - $this->output = new ConsoleOutput( - $options['verbosity'] ?? ConsoleOutput::VERBOSITY_NORMAL, - $options['decorated'] ?? null - ); - - $errorOutput = new StreamOutput(fopen('php://memory', 'w', false)); - $errorOutput->setFormatter($this->output->getFormatter()); - $errorOutput->setVerbosity($this->output->getVerbosity()); - $errorOutput->setDecorated($this->output->isDecorated()); - - $reflectedOutput = new \ReflectionObject($this->output); - $strErrProperty = $reflectedOutput->getProperty('stderr'); - $strErrProperty->setAccessible(true); - $strErrProperty->setValue($this->output, $errorOutput); - - $reflectedParent = $reflectedOutput->getParentClass(); - $streamProperty = $reflectedParent->getProperty('stream'); - $streamProperty->setAccessible(true); - $streamProperty->setValue($this->output, fopen('php://memory', 'w', false)); - } - } - - /** - * @return resource - */ - private static function createStream(array $inputs) - { - $stream = fopen('php://memory', 'r+', false); - - foreach ($inputs as $input) { - fwrite($stream, $input.\PHP_EOL); - } - - rewind($stream); - - return $stream; - } -} diff --git a/vendor/symfony/deprecation-contracts/function.php b/vendor/symfony/deprecation-contracts/function.php deleted file mode 100644 index d4371504a..000000000 --- a/vendor/symfony/deprecation-contracts/function.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * 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, ...$args): void - { - @trigger_error(($package || $version ? "Since $package $version: " : '').($args ? vsprintf($message, $args) : $message), \E_USER_DEPRECATED); - } -} diff --git a/vendor/symfony/polyfill-ctype/Ctype.php b/vendor/symfony/polyfill-ctype/Ctype.php deleted file mode 100644 index ba75a2c95..000000000 --- a/vendor/symfony/polyfill-ctype/Ctype.php +++ /dev/null @@ -1,232 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Ctype; - -/** - * Ctype implementation through regex. - * - * @internal - * - * @author Gert de Pagter - */ -final class Ctype -{ - /** - * Returns TRUE if every character in text is either a letter or a digit, FALSE otherwise. - * - * @see https://php.net/ctype-alnum - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_alnum($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text); - } - - /** - * Returns TRUE if every character in text is a letter, FALSE otherwise. - * - * @see https://php.net/ctype-alpha - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_alpha($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text); - } - - /** - * Returns TRUE if every character in text is a control character from the current locale, FALSE otherwise. - * - * @see https://php.net/ctype-cntrl - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_cntrl($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text); - } - - /** - * Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise. - * - * @see https://php.net/ctype-digit - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_digit($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text); - } - - /** - * Returns TRUE if every character in text is printable and actually creates visible output (no white space), FALSE otherwise. - * - * @see https://php.net/ctype-graph - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_graph($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text); - } - - /** - * Returns TRUE if every character in text is a lowercase letter. - * - * @see https://php.net/ctype-lower - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_lower($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text); - } - - /** - * Returns TRUE if every character in text will actually create output (including blanks). Returns FALSE if text contains control characters or characters that do not have any output or control function at all. - * - * @see https://php.net/ctype-print - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_print($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text); - } - - /** - * Returns TRUE if every character in text is printable, but neither letter, digit or blank, FALSE otherwise. - * - * @see https://php.net/ctype-punct - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_punct($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text); - } - - /** - * Returns TRUE if every character in text creates some sort of white space, FALSE otherwise. Besides the blank character this also includes tab, vertical tab, line feed, carriage return and form feed characters. - * - * @see https://php.net/ctype-space - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_space($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text); - } - - /** - * Returns TRUE if every character in text is an uppercase letter. - * - * @see https://php.net/ctype-upper - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_upper($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text); - } - - /** - * Returns TRUE if every character in text is a hexadecimal 'digit', that is a decimal digit or a character from [A-Fa-f] , FALSE otherwise. - * - * @see https://php.net/ctype-xdigit - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_xdigit($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text); - } - - /** - * Converts integers to their char versions according to normal ctype behaviour, if needed. - * - * If an integer between -128 and 255 inclusive is provided, - * it is interpreted as the ASCII value of a single character - * (negative values have 256 added in order to allow characters in the Extended ASCII range). - * Any other integer is interpreted as a string containing the decimal digits of the integer. - * - * @param mixed $int - * @param string $function - * - * @return mixed - */ - private static function convert_int_to_char_for_ctype($int, $function) - { - if (!\is_int($int)) { - return $int; - } - - if ($int < -128 || $int > 255) { - return (string) $int; - } - - if (\PHP_VERSION_ID >= 80100) { - @trigger_error($function.'(): Argument of type int will be interpreted as string in the future', \E_USER_DEPRECATED); - } - - if ($int < 0) { - $int += 256; - } - - return \chr($int); - } -} diff --git a/vendor/symfony/polyfill-ctype/bootstrap.php b/vendor/symfony/polyfill-ctype/bootstrap.php deleted file mode 100644 index d54524b31..000000000 --- a/vendor/symfony/polyfill-ctype/bootstrap.php +++ /dev/null @@ -1,50 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Ctype as p; - -if (\PHP_VERSION_ID >= 80000) { - return require __DIR__.'/bootstrap80.php'; -} - -if (!function_exists('ctype_alnum')) { - function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); } -} -if (!function_exists('ctype_alpha')) { - function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); } -} -if (!function_exists('ctype_cntrl')) { - function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); } -} -if (!function_exists('ctype_digit')) { - function ctype_digit($text) { return p\Ctype::ctype_digit($text); } -} -if (!function_exists('ctype_graph')) { - function ctype_graph($text) { return p\Ctype::ctype_graph($text); } -} -if (!function_exists('ctype_lower')) { - function ctype_lower($text) { return p\Ctype::ctype_lower($text); } -} -if (!function_exists('ctype_print')) { - function ctype_print($text) { return p\Ctype::ctype_print($text); } -} -if (!function_exists('ctype_punct')) { - function ctype_punct($text) { return p\Ctype::ctype_punct($text); } -} -if (!function_exists('ctype_space')) { - function ctype_space($text) { return p\Ctype::ctype_space($text); } -} -if (!function_exists('ctype_upper')) { - function ctype_upper($text) { return p\Ctype::ctype_upper($text); } -} -if (!function_exists('ctype_xdigit')) { - function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); } -} diff --git a/vendor/symfony/polyfill-ctype/bootstrap80.php b/vendor/symfony/polyfill-ctype/bootstrap80.php deleted file mode 100644 index ab2f8611d..000000000 --- a/vendor/symfony/polyfill-ctype/bootstrap80.php +++ /dev/null @@ -1,46 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Ctype as p; - -if (!function_exists('ctype_alnum')) { - function ctype_alnum(mixed $text): bool { return p\Ctype::ctype_alnum($text); } -} -if (!function_exists('ctype_alpha')) { - function ctype_alpha(mixed $text): bool { return p\Ctype::ctype_alpha($text); } -} -if (!function_exists('ctype_cntrl')) { - function ctype_cntrl(mixed $text): bool { return p\Ctype::ctype_cntrl($text); } -} -if (!function_exists('ctype_digit')) { - function ctype_digit(mixed $text): bool { return p\Ctype::ctype_digit($text); } -} -if (!function_exists('ctype_graph')) { - function ctype_graph(mixed $text): bool { return p\Ctype::ctype_graph($text); } -} -if (!function_exists('ctype_lower')) { - function ctype_lower(mixed $text): bool { return p\Ctype::ctype_lower($text); } -} -if (!function_exists('ctype_print')) { - function ctype_print(mixed $text): bool { return p\Ctype::ctype_print($text); } -} -if (!function_exists('ctype_punct')) { - function ctype_punct(mixed $text): bool { return p\Ctype::ctype_punct($text); } -} -if (!function_exists('ctype_space')) { - function ctype_space(mixed $text): bool { return p\Ctype::ctype_space($text); } -} -if (!function_exists('ctype_upper')) { - function ctype_upper(mixed $text): bool { return p\Ctype::ctype_upper($text); } -} -if (!function_exists('ctype_xdigit')) { - function ctype_xdigit(mixed $text): bool { return p\Ctype::ctype_xdigit($text); } -} diff --git a/vendor/symfony/polyfill-intl-grapheme/Grapheme.php b/vendor/symfony/polyfill-intl-grapheme/Grapheme.php deleted file mode 100644 index 6f7c0c78d..000000000 --- a/vendor/symfony/polyfill-intl-grapheme/Grapheme.php +++ /dev/null @@ -1,247 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Intl\Grapheme; - -\define('SYMFONY_GRAPHEME_CLUSTER_RX', ((float) \PCRE_VERSION < 10 ? (float) \PCRE_VERSION >= 8.32 : (float) \PCRE_VERSION >= 10.39) ? '\X' : Grapheme::GRAPHEME_CLUSTER_RX); - -/** - * Partial intl implementation in pure PHP. - * - * Implemented: - * - grapheme_extract - Extract a sequence of grapheme clusters from a text buffer, which must be encoded in UTF-8 - * - grapheme_stripos - Find position (in grapheme units) of first occurrence of a case-insensitive string - * - grapheme_stristr - Returns part of haystack string from the first occurrence of case-insensitive needle to the end of haystack - * - grapheme_strlen - Get string length in grapheme units - * - grapheme_strpos - Find position (in grapheme units) of first occurrence of a string - * - grapheme_strripos - Find position (in grapheme units) of last occurrence of a case-insensitive string - * - grapheme_strrpos - Find position (in grapheme units) of last occurrence of a string - * - grapheme_strstr - Returns part of haystack string from the first occurrence of needle to the end of haystack - * - grapheme_substr - Return part of a string - * - * @author Nicolas Grekas - * - * @internal - */ -final class Grapheme -{ - // (CRLF|([ZWNJ-ZWJ]|T+|L*(LV?V+|LV|LVT)T*|L+|[^Control])[Extend]*|[Control]) - // This regular expression is a work around for http://bugs.exim.org/1279 - public const GRAPHEME_CLUSTER_RX = '(?:\r\n|(?:[ -~\x{200C}\x{200D}]|[ᆨ-ᇹ]+|[ᄀ-ᅟ]*(?:[가개갸걔거게겨계고과괘괴교구궈궤귀규그긔기까깨꺄꺠꺼께껴꼐꼬꽈꽤꾀꾜꾸꿔꿰뀌뀨끄끠끼나내냐냬너네녀녜노놔놰뇌뇨누눠눼뉘뉴느늬니다대댜댸더데뎌뎨도돠돼되됴두둬뒈뒤듀드듸디따때땨떄떠떼뗘뗴또똬뙈뙤뚀뚜뚸뛔뛰뜌뜨띄띠라래랴럐러레려례로롸뢔뢰료루뤄뤠뤼류르릐리마매먀먜머메며몌모뫄뫠뫼묘무뭐뭬뮈뮤므믜미바배뱌뱨버베벼볘보봐봬뵈뵤부붜붸뷔뷰브븨비빠빼뺘뺴뻐뻬뼈뼤뽀뽜뽸뾔뾰뿌뿨쀄쀠쀼쁘쁴삐사새샤섀서세셔셰소솨쇄쇠쇼수숴쉐쉬슈스싀시싸쌔쌰썌써쎄쎠쎼쏘쏴쐐쐬쑈쑤쒀쒜쒸쓔쓰씌씨아애야얘어에여예오와왜외요우워웨위유으의이자재쟈쟤저제져졔조좌좨죄죠주줘줴쥐쥬즈즤지짜째쨔쨰쩌쩨쪄쪠쪼쫘쫴쬐쬬쭈쭤쮀쮜쮸쯔쯰찌차채챠챼처체쳐쳬초촤쵀최쵸추춰췌취츄츠츼치카캐캬컈커케켜켸코콰쾌쾨쿄쿠쿼퀘퀴큐크킈키타태탸턔터테텨톄토톼퇘퇴툐투퉈퉤튀튜트틔티파패퍄퍠퍼페펴폐포퐈퐤푀표푸풔풰퓌퓨프픠피하해햐햬허헤혀혜호화홰회효후훠훼휘휴흐희히]?[ᅠ-ᆢ]+|[가-힣])[ᆨ-ᇹ]*|[ᄀ-ᅟ]+|[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}])[\p{Mn}\p{Me}\x{09BE}\x{09D7}\x{0B3E}\x{0B57}\x{0BBE}\x{0BD7}\x{0CC2}\x{0CD5}\x{0CD6}\x{0D3E}\x{0D57}\x{0DCF}\x{0DDF}\x{200C}\x{200D}\x{1D165}\x{1D16E}-\x{1D172}]*|[\p{Cc}\p{Cf}\p{Zl}\p{Zp}])'; - - private const CASE_FOLD = [ - ['µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"], - ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'], - ]; - - public static function grapheme_extract($s, $size, $type = \GRAPHEME_EXTR_COUNT, $start = 0, &$next = 0) - { - if (0 > $start) { - $start = \strlen($s) + $start; - } - - if (!is_scalar($s)) { - $hasError = false; - set_error_handler(function () use (&$hasError) { $hasError = true; }); - $next = substr($s, $start); - restore_error_handler(); - if ($hasError) { - substr($s, $start); - $s = ''; - } else { - $s = $next; - } - } else { - $s = substr($s, $start); - } - $size = (int) $size; - $type = (int) $type; - $start = (int) $start; - - if (\GRAPHEME_EXTR_COUNT !== $type && \GRAPHEME_EXTR_MAXBYTES !== $type && \GRAPHEME_EXTR_MAXCHARS !== $type) { - if (80000 > \PHP_VERSION_ID) { - return false; - } - - throw new \ValueError('grapheme_extract(): Argument #3 ($type) must be one of GRAPHEME_EXTR_COUNT, GRAPHEME_EXTR_MAXBYTES, or GRAPHEME_EXTR_MAXCHARS'); - } - - if (!isset($s[0]) || 0 > $size || 0 > $start) { - return false; - } - if (0 === $size) { - return ''; - } - - $next = $start; - - $s = preg_split('/('.SYMFONY_GRAPHEME_CLUSTER_RX.')/u', "\r\n".$s, $size + 1, \PREG_SPLIT_NO_EMPTY | \PREG_SPLIT_DELIM_CAPTURE); - - if (!isset($s[1])) { - return false; - } - - $i = 1; - $ret = ''; - - do { - if (\GRAPHEME_EXTR_COUNT === $type) { - --$size; - } elseif (\GRAPHEME_EXTR_MAXBYTES === $type) { - $size -= \strlen($s[$i]); - } else { - $size -= iconv_strlen($s[$i], 'UTF-8//IGNORE'); - } - - if ($size >= 0) { - $ret .= $s[$i]; - } - } while (isset($s[++$i]) && $size > 0); - - $next += \strlen($ret); - - return $ret; - } - - public static function grapheme_strlen($s) - { - preg_replace('/'.SYMFONY_GRAPHEME_CLUSTER_RX.'/u', '', $s, -1, $len); - - return 0 === $len && '' !== $s ? null : $len; - } - - public static function grapheme_substr($s, $start, $len = null) - { - if (null === $len) { - $len = 2147483647; - } - - preg_match_all('/'.SYMFONY_GRAPHEME_CLUSTER_RX.'/u', $s, $s); - - $slen = \count($s[0]); - $start = (int) $start; - - if (0 > $start) { - $start += $slen; - } - if (0 > $start) { - if (\PHP_VERSION_ID < 80000) { - return false; - } - - $start = 0; - } - if ($start >= $slen) { - return \PHP_VERSION_ID >= 80000 ? '' : false; - } - - $rem = $slen - $start; - - if (0 > $len) { - $len += $rem; - } - if (0 === $len) { - return ''; - } - if (0 > $len) { - return \PHP_VERSION_ID >= 80000 ? '' : false; - } - if ($len > $rem) { - $len = $rem; - } - - return implode('', \array_slice($s[0], $start, $len)); - } - - public static function grapheme_strpos($s, $needle, $offset = 0) - { - return self::grapheme_position($s, $needle, $offset, 0); - } - - public static function grapheme_stripos($s, $needle, $offset = 0) - { - return self::grapheme_position($s, $needle, $offset, 1); - } - - public static function grapheme_strrpos($s, $needle, $offset = 0) - { - return self::grapheme_position($s, $needle, $offset, 2); - } - - public static function grapheme_strripos($s, $needle, $offset = 0) - { - return self::grapheme_position($s, $needle, $offset, 3); - } - - public static function grapheme_stristr($s, $needle, $beforeNeedle = false) - { - return mb_stristr($s, $needle, $beforeNeedle, 'UTF-8'); - } - - public static function grapheme_strstr($s, $needle, $beforeNeedle = false) - { - return mb_strstr($s, $needle, $beforeNeedle, 'UTF-8'); - } - - private static function grapheme_position($s, $needle, $offset, $mode) - { - $needle = (string) $needle; - if (80000 > \PHP_VERSION_ID && !preg_match('/./us', $needle)) { - return false; - } - $s = (string) $s; - if (!preg_match('/./us', $s)) { - return false; - } - if ($offset > 0) { - $s = self::grapheme_substr($s, $offset); - } elseif ($offset < 0) { - if (2 > $mode) { - $offset += self::grapheme_strlen($s); - $s = self::grapheme_substr($s, $offset); - if (0 > $offset) { - $offset = 0; - } - } elseif (0 > $offset += self::grapheme_strlen($needle)) { - $s = self::grapheme_substr($s, 0, $offset); - $offset = 0; - } else { - $offset = 0; - } - } - - // As UTF-8 is self-synchronizing, and we have ensured the strings are valid UTF-8, - // we can use normal binary string functions here. For case-insensitive searches, - // case fold the strings first. - $caseInsensitive = $mode & 1; - $reverse = $mode & 2; - if ($caseInsensitive) { - // Use the same case folding mode as mbstring does for mb_stripos(). - // Stick to SIMPLE case folding to avoid changing the length of the string, which - // might result in offsets being shifted. - $mode = \defined('MB_CASE_FOLD_SIMPLE') ? \MB_CASE_FOLD_SIMPLE : \MB_CASE_LOWER; - $s = mb_convert_case($s, $mode, 'UTF-8'); - $needle = mb_convert_case($needle, $mode, 'UTF-8'); - - if (!\defined('MB_CASE_FOLD_SIMPLE')) { - $s = str_replace(self::CASE_FOLD[0], self::CASE_FOLD[1], $s); - $needle = str_replace(self::CASE_FOLD[0], self::CASE_FOLD[1], $needle); - } - } - if ($reverse) { - $needlePos = strrpos($s, $needle); - } else { - $needlePos = strpos($s, $needle); - } - - return false !== $needlePos ? self::grapheme_strlen(substr($s, 0, $needlePos)) + $offset : false; - } -} diff --git a/vendor/symfony/polyfill-intl-grapheme/bootstrap.php b/vendor/symfony/polyfill-intl-grapheme/bootstrap.php deleted file mode 100644 index a9ea03c7e..000000000 --- a/vendor/symfony/polyfill-intl-grapheme/bootstrap.php +++ /dev/null @@ -1,58 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Intl\Grapheme as p; - -if (extension_loaded('intl')) { - return; -} - -if (\PHP_VERSION_ID >= 80000) { - return require __DIR__.'/bootstrap80.php'; -} - -if (!defined('GRAPHEME_EXTR_COUNT')) { - define('GRAPHEME_EXTR_COUNT', 0); -} -if (!defined('GRAPHEME_EXTR_MAXBYTES')) { - define('GRAPHEME_EXTR_MAXBYTES', 1); -} -if (!defined('GRAPHEME_EXTR_MAXCHARS')) { - define('GRAPHEME_EXTR_MAXCHARS', 2); -} - -if (!function_exists('grapheme_extract')) { - function grapheme_extract($haystack, $size, $type = 0, $start = 0, &$next = 0) { return p\Grapheme::grapheme_extract($haystack, $size, $type, $start, $next); } -} -if (!function_exists('grapheme_stripos')) { - function grapheme_stripos($haystack, $needle, $offset = 0) { return p\Grapheme::grapheme_stripos($haystack, $needle, $offset); } -} -if (!function_exists('grapheme_stristr')) { - function grapheme_stristr($haystack, $needle, $beforeNeedle = false) { return p\Grapheme::grapheme_stristr($haystack, $needle, $beforeNeedle); } -} -if (!function_exists('grapheme_strlen')) { - function grapheme_strlen($input) { return p\Grapheme::grapheme_strlen($input); } -} -if (!function_exists('grapheme_strpos')) { - function grapheme_strpos($haystack, $needle, $offset = 0) { return p\Grapheme::grapheme_strpos($haystack, $needle, $offset); } -} -if (!function_exists('grapheme_strripos')) { - function grapheme_strripos($haystack, $needle, $offset = 0) { return p\Grapheme::grapheme_strripos($haystack, $needle, $offset); } -} -if (!function_exists('grapheme_strrpos')) { - function grapheme_strrpos($haystack, $needle, $offset = 0) { return p\Grapheme::grapheme_strrpos($haystack, $needle, $offset); } -} -if (!function_exists('grapheme_strstr')) { - function grapheme_strstr($haystack, $needle, $beforeNeedle = false) { return p\Grapheme::grapheme_strstr($haystack, $needle, $beforeNeedle); } -} -if (!function_exists('grapheme_substr')) { - function grapheme_substr($string, $offset, $length = null) { return p\Grapheme::grapheme_substr($string, $offset, $length); } -} diff --git a/vendor/symfony/polyfill-intl-grapheme/bootstrap80.php b/vendor/symfony/polyfill-intl-grapheme/bootstrap80.php deleted file mode 100644 index b8c078677..000000000 --- a/vendor/symfony/polyfill-intl-grapheme/bootstrap80.php +++ /dev/null @@ -1,50 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Intl\Grapheme as p; - -if (!defined('GRAPHEME_EXTR_COUNT')) { - define('GRAPHEME_EXTR_COUNT', 0); -} -if (!defined('GRAPHEME_EXTR_MAXBYTES')) { - define('GRAPHEME_EXTR_MAXBYTES', 1); -} -if (!defined('GRAPHEME_EXTR_MAXCHARS')) { - define('GRAPHEME_EXTR_MAXCHARS', 2); -} - -if (!function_exists('grapheme_extract')) { - function grapheme_extract(?string $haystack, ?int $size, ?int $type = GRAPHEME_EXTR_COUNT, ?int $offset = 0, &$next = null): string|false { return p\Grapheme::grapheme_extract((string) $haystack, (int) $size, (int) $type, (int) $offset, $next); } -} -if (!function_exists('grapheme_stripos')) { - function grapheme_stripos(?string $haystack, ?string $needle, ?int $offset = 0): int|false { return p\Grapheme::grapheme_stripos((string) $haystack, (string) $needle, (int) $offset); } -} -if (!function_exists('grapheme_stristr')) { - function grapheme_stristr(?string $haystack, ?string $needle, ?bool $beforeNeedle = false): string|false { return p\Grapheme::grapheme_stristr((string) $haystack, (string) $needle, (bool) $beforeNeedle); } -} -if (!function_exists('grapheme_strlen')) { - function grapheme_strlen(?string $string): int|false|null { return p\Grapheme::grapheme_strlen((string) $string); } -} -if (!function_exists('grapheme_strpos')) { - function grapheme_strpos(?string $haystack, ?string $needle, ?int $offset = 0): int|false { return p\Grapheme::grapheme_strpos((string) $haystack, (string) $needle, (int) $offset); } -} -if (!function_exists('grapheme_strripos')) { - function grapheme_strripos(?string $haystack, ?string $needle, ?int $offset = 0): int|false { return p\Grapheme::grapheme_strripos((string) $haystack, (string) $needle, (int) $offset); } -} -if (!function_exists('grapheme_strrpos')) { - function grapheme_strrpos(?string $haystack, ?string $needle, ?int $offset = 0): int|false { return p\Grapheme::grapheme_strrpos((string) $haystack, (string) $needle, (int) $offset); } -} -if (!function_exists('grapheme_strstr')) { - function grapheme_strstr(?string $haystack, ?string $needle, ?bool $beforeNeedle = false): string|false { return p\Grapheme::grapheme_strstr((string) $haystack, (string) $needle, (bool) $beforeNeedle); } -} -if (!function_exists('grapheme_substr')) { - function grapheme_substr(?string $string, ?int $offset, ?int $length = null): string|false { return p\Grapheme::grapheme_substr((string) $string, (int) $offset, $length); } -} diff --git a/vendor/symfony/polyfill-intl-normalizer/Normalizer.php b/vendor/symfony/polyfill-intl-normalizer/Normalizer.php deleted file mode 100644 index 4443c2322..000000000 --- a/vendor/symfony/polyfill-intl-normalizer/Normalizer.php +++ /dev/null @@ -1,310 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Intl\Normalizer; - -/** - * Normalizer is a PHP fallback implementation of the Normalizer class provided by the intl extension. - * - * It has been validated with Unicode 6.3 Normalization Conformance Test. - * See http://www.unicode.org/reports/tr15/ for detailed info about Unicode normalizations. - * - * @author Nicolas Grekas - * - * @internal - */ -class Normalizer -{ - public const FORM_D = \Normalizer::FORM_D; - public const FORM_KD = \Normalizer::FORM_KD; - public const FORM_C = \Normalizer::FORM_C; - public const FORM_KC = \Normalizer::FORM_KC; - public const NFD = \Normalizer::NFD; - public const NFKD = \Normalizer::NFKD; - public const NFC = \Normalizer::NFC; - public const NFKC = \Normalizer::NFKC; - - private static $C; - private static $D; - private static $KD; - private static $cC; - private static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; - private static $ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"; - - public static function isNormalized(string $s, int $form = self::FORM_C) - { - if (!\in_array($form, [self::NFD, self::NFKD, self::NFC, self::NFKC])) { - return false; - } - if (!isset($s[strspn($s, self::$ASCII)])) { - return true; - } - if (self::NFC == $form && preg_match('//u', $s) && !preg_match('/[^\x00-\x{2FF}]/u', $s)) { - return true; - } - - return self::normalize($s, $form) === $s; - } - - public static function normalize(string $s, int $form = self::FORM_C) - { - if (!preg_match('//u', $s)) { - return false; - } - - switch ($form) { - case self::NFC: $C = true; $K = false; break; - case self::NFD: $C = false; $K = false; break; - case self::NFKC: $C = true; $K = true; break; - case self::NFKD: $C = false; $K = true; break; - default: - if (\defined('Normalizer::NONE') && \Normalizer::NONE == $form) { - return $s; - } - - if (80000 > \PHP_VERSION_ID) { - return false; - } - - throw new \ValueError('normalizer_normalize(): Argument #2 ($form) must be a a valid normalization form'); - } - - if ('' === $s) { - return ''; - } - - if ($K && null === self::$KD) { - self::$KD = self::getData('compatibilityDecomposition'); - } - - if (null === self::$D) { - self::$D = self::getData('canonicalDecomposition'); - self::$cC = self::getData('combiningClass'); - } - - if (null !== $mbEncoding = (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) ? mb_internal_encoding() : null) { - mb_internal_encoding('8bit'); - } - - $r = self::decompose($s, $K); - - if ($C) { - if (null === self::$C) { - self::$C = self::getData('canonicalComposition'); - } - - $r = self::recompose($r); - } - if (null !== $mbEncoding) { - mb_internal_encoding($mbEncoding); - } - - return $r; - } - - private static function recompose($s) - { - $ASCII = self::$ASCII; - $compMap = self::$C; - $combClass = self::$cC; - $ulenMask = self::$ulenMask; - - $result = $tail = ''; - - $i = $s[0] < "\x80" ? 1 : $ulenMask[$s[0] & "\xF0"]; - $len = \strlen($s); - - $lastUchr = substr($s, 0, $i); - $lastUcls = isset($combClass[$lastUchr]) ? 256 : 0; - - while ($i < $len) { - if ($s[$i] < "\x80") { - // ASCII chars - - if ($tail) { - $lastUchr .= $tail; - $tail = ''; - } - - if ($j = strspn($s, $ASCII, $i + 1)) { - $lastUchr .= substr($s, $i, $j); - $i += $j; - } - - $result .= $lastUchr; - $lastUchr = $s[$i]; - $lastUcls = 0; - ++$i; - continue; - } - - $ulen = $ulenMask[$s[$i] & "\xF0"]; - $uchr = substr($s, $i, $ulen); - - if ($lastUchr < "\xE1\x84\x80" || "\xE1\x84\x92" < $lastUchr - || $uchr < "\xE1\x85\xA1" || "\xE1\x85\xB5" < $uchr - || $lastUcls) { - // Table lookup and combining chars composition - - $ucls = $combClass[$uchr] ?? 0; - - if (isset($compMap[$lastUchr.$uchr]) && (!$lastUcls || $lastUcls < $ucls)) { - $lastUchr = $compMap[$lastUchr.$uchr]; - } elseif ($lastUcls = $ucls) { - $tail .= $uchr; - } else { - if ($tail) { - $lastUchr .= $tail; - $tail = ''; - } - - $result .= $lastUchr; - $lastUchr = $uchr; - } - } else { - // Hangul chars - - $L = \ord($lastUchr[2]) - 0x80; - $V = \ord($uchr[2]) - 0xA1; - $T = 0; - - $uchr = substr($s, $i + $ulen, 3); - - if ("\xE1\x86\xA7" <= $uchr && $uchr <= "\xE1\x87\x82") { - $T = \ord($uchr[2]) - 0xA7; - 0 > $T && $T += 0x40; - $ulen += 3; - } - - $L = 0xAC00 + ($L * 21 + $V) * 28 + $T; - $lastUchr = \chr(0xE0 | $L >> 12).\chr(0x80 | $L >> 6 & 0x3F).\chr(0x80 | $L & 0x3F); - } - - $i += $ulen; - } - - return $result.$lastUchr.$tail; - } - - private static function decompose($s, $c) - { - $result = ''; - - $ASCII = self::$ASCII; - $decompMap = self::$D; - $combClass = self::$cC; - $ulenMask = self::$ulenMask; - if ($c) { - $compatMap = self::$KD; - } - - $c = []; - $i = 0; - $len = \strlen($s); - - while ($i < $len) { - if ($s[$i] < "\x80") { - // ASCII chars - - if ($c) { - ksort($c); - $result .= implode('', $c); - $c = []; - } - - $j = 1 + strspn($s, $ASCII, $i + 1); - $result .= substr($s, $i, $j); - $i += $j; - continue; - } - - $ulen = $ulenMask[$s[$i] & "\xF0"]; - $uchr = substr($s, $i, $ulen); - $i += $ulen; - - if ($uchr < "\xEA\xB0\x80" || "\xED\x9E\xA3" < $uchr) { - // Table lookup - - if ($uchr !== $j = $compatMap[$uchr] ?? ($decompMap[$uchr] ?? $uchr)) { - $uchr = $j; - - $j = \strlen($uchr); - $ulen = $uchr[0] < "\x80" ? 1 : $ulenMask[$uchr[0] & "\xF0"]; - - if ($ulen != $j) { - // Put trailing chars in $s - - $j -= $ulen; - $i -= $j; - - if (0 > $i) { - $s = str_repeat(' ', -$i).$s; - $len -= $i; - $i = 0; - } - - while ($j--) { - $s[$i + $j] = $uchr[$ulen + $j]; - } - - $uchr = substr($uchr, 0, $ulen); - } - } - if (isset($combClass[$uchr])) { - // Combining chars, for sorting - - if (!isset($c[$combClass[$uchr]])) { - $c[$combClass[$uchr]] = ''; - } - $c[$combClass[$uchr]] .= $uchr; - continue; - } - } else { - // Hangul chars - - $uchr = unpack('C*', $uchr); - $j = (($uchr[1] - 224) << 12) + (($uchr[2] - 128) << 6) + $uchr[3] - 0xAC80; - - $uchr = "\xE1\x84".\chr(0x80 + (int) ($j / 588)) - ."\xE1\x85".\chr(0xA1 + (int) (($j % 588) / 28)); - - if ($j %= 28) { - $uchr .= $j < 25 - ? ("\xE1\x86".\chr(0xA7 + $j)) - : ("\xE1\x87".\chr(0x67 + $j)); - } - } - if ($c) { - ksort($c); - $result .= implode('', $c); - $c = []; - } - - $result .= $uchr; - } - - if ($c) { - ksort($c); - $result .= implode('', $c); - } - - return $result; - } - - private static function getData($file) - { - if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) { - return require $file; - } - - return false; - } -} diff --git a/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php b/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php deleted file mode 100644 index 0fdfc890a..000000000 --- a/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php +++ /dev/null @@ -1,17 +0,0 @@ - 'À', - 'Á' => 'Á', - 'Â' => 'Â', - 'Ã' => 'Ã', - 'Ä' => 'Ä', - 'Å' => 'Å', - 'Ç' => 'Ç', - 'È' => 'È', - 'É' => 'É', - 'Ê' => 'Ê', - 'Ë' => 'Ë', - 'Ì' => 'Ì', - 'Í' => 'Í', - 'Î' => 'Î', - 'Ï' => 'Ï', - 'Ñ' => 'Ñ', - 'Ò' => 'Ò', - 'Ó' => 'Ó', - 'Ô' => 'Ô', - 'Õ' => 'Õ', - 'Ö' => 'Ö', - 'Ù' => 'Ù', - 'Ú' => 'Ú', - 'Û' => 'Û', - 'Ü' => 'Ü', - 'Ý' => 'Ý', - 'à' => 'à', - 'á' => 'á', - 'â' => 'â', - 'ã' => 'ã', - 'ä' => 'ä', - 'å' => 'å', - 'ç' => 'ç', - 'è' => 'è', - 'é' => 'é', - 'ê' => 'ê', - 'ë' => 'ë', - 'ì' => 'ì', - 'í' => 'í', - 'î' => 'î', - 'ï' => 'ï', - 'ñ' => 'ñ', - 'ò' => 'ò', - 'ó' => 'ó', - 'ô' => 'ô', - 'õ' => 'õ', - 'ö' => 'ö', - 'ù' => 'ù', - 'ú' => 'ú', - 'û' => 'û', - 'ü' => 'ü', - 'ý' => 'ý', - 'ÿ' => 'ÿ', - 'Ā' => 'Ā', - 'ā' => 'ā', - 'Ă' => 'Ă', - 'ă' => 'ă', - 'Ą' => 'Ą', - 'ą' => 'ą', - 'Ć' => 'Ć', - 'ć' => 'ć', - 'Ĉ' => 'Ĉ', - 'ĉ' => 'ĉ', - 'Ċ' => 'Ċ', - 'ċ' => 'ċ', - 'Č' => 'Č', - 'č' => 'č', - 'Ď' => 'Ď', - 'ď' => 'ď', - 'Ē' => 'Ē', - 'ē' => 'ē', - 'Ĕ' => 'Ĕ', - 'ĕ' => 'ĕ', - 'Ė' => 'Ė', - 'ė' => 'ė', - 'Ę' => 'Ę', - 'ę' => 'ę', - 'Ě' => 'Ě', - 'ě' => 'ě', - 'Ĝ' => 'Ĝ', - 'ĝ' => 'ĝ', - 'Ğ' => 'Ğ', - 'ğ' => 'ğ', - 'Ġ' => 'Ġ', - 'ġ' => 'ġ', - 'Ģ' => 'Ģ', - 'ģ' => 'ģ', - 'Ĥ' => 'Ĥ', - 'ĥ' => 'ĥ', - 'Ĩ' => 'Ĩ', - 'ĩ' => 'ĩ', - 'Ī' => 'Ī', - 'ī' => 'ī', - 'Ĭ' => 'Ĭ', - 'ĭ' => 'ĭ', - 'Į' => 'Į', - 'į' => 'į', - 'İ' => 'İ', - 'Ĵ' => 'Ĵ', - 'ĵ' => 'ĵ', - 'Ķ' => 'Ķ', - 'ķ' => 'ķ', - 'Ĺ' => 'Ĺ', - 'ĺ' => 'ĺ', - 'Ļ' => 'Ļ', - 'ļ' => 'ļ', - 'Ľ' => 'Ľ', - 'ľ' => 'ľ', - 'Ń' => 'Ń', - 'ń' => 'ń', - 'Ņ' => 'Ņ', - 'ņ' => 'ņ', - 'Ň' => 'Ň', - 'ň' => 'ň', - 'Ō' => 'Ō', - 'ō' => 'ō', - 'Ŏ' => 'Ŏ', - 'ŏ' => 'ŏ', - 'Ő' => 'Ő', - 'ő' => 'ő', - 'Ŕ' => 'Ŕ', - 'ŕ' => 'ŕ', - 'Ŗ' => 'Ŗ', - 'ŗ' => 'ŗ', - 'Ř' => 'Ř', - 'ř' => 'ř', - 'Ś' => 'Ś', - 'ś' => 'ś', - 'Ŝ' => 'Ŝ', - 'ŝ' => 'ŝ', - 'Ş' => 'Ş', - 'ş' => 'ş', - 'Š' => 'Š', - 'š' => 'š', - 'Ţ' => 'Ţ', - 'ţ' => 'ţ', - 'Ť' => 'Ť', - 'ť' => 'ť', - 'Ũ' => 'Ũ', - 'ũ' => 'ũ', - 'Ū' => 'Ū', - 'ū' => 'ū', - 'Ŭ' => 'Ŭ', - 'ŭ' => 'ŭ', - 'Ů' => 'Ů', - 'ů' => 'ů', - 'Ű' => 'Ű', - 'ű' => 'ű', - 'Ų' => 'Ų', - 'ų' => 'ų', - 'Ŵ' => 'Ŵ', - 'ŵ' => 'ŵ', - 'Ŷ' => 'Ŷ', - 'ŷ' => 'ŷ', - 'Ÿ' => 'Ÿ', - 'Ź' => 'Ź', - 'ź' => 'ź', - 'Ż' => 'Ż', - 'ż' => 'ż', - 'Ž' => 'Ž', - 'ž' => 'ž', - 'Ơ' => 'Ơ', - 'ơ' => 'ơ', - 'Ư' => 'Ư', - 'ư' => 'ư', - 'Ǎ' => 'Ǎ', - 'ǎ' => 'ǎ', - 'Ǐ' => 'Ǐ', - 'ǐ' => 'ǐ', - 'Ǒ' => 'Ǒ', - 'ǒ' => 'ǒ', - 'Ǔ' => 'Ǔ', - 'ǔ' => 'ǔ', - 'Ǖ' => 'Ǖ', - 'ǖ' => 'ǖ', - 'Ǘ' => 'Ǘ', - 'ǘ' => 'ǘ', - 'Ǚ' => 'Ǚ', - 'ǚ' => 'ǚ', - 'Ǜ' => 'Ǜ', - 'ǜ' => 'ǜ', - 'Ǟ' => 'Ǟ', - 'ǟ' => 'ǟ', - 'Ǡ' => 'Ǡ', - 'ǡ' => 'ǡ', - 'Ǣ' => 'Ǣ', - 'ǣ' => 'ǣ', - 'Ǧ' => 'Ǧ', - 'ǧ' => 'ǧ', - 'Ǩ' => 'Ǩ', - 'ǩ' => 'ǩ', - 'Ǫ' => 'Ǫ', - 'ǫ' => 'ǫ', - 'Ǭ' => 'Ǭ', - 'ǭ' => 'ǭ', - 'Ǯ' => 'Ǯ', - 'ǯ' => 'ǯ', - 'ǰ' => 'ǰ', - 'Ǵ' => 'Ǵ', - 'ǵ' => 'ǵ', - 'Ǹ' => 'Ǹ', - 'ǹ' => 'ǹ', - 'Ǻ' => 'Ǻ', - 'ǻ' => 'ǻ', - 'Ǽ' => 'Ǽ', - 'ǽ' => 'ǽ', - 'Ǿ' => 'Ǿ', - 'ǿ' => 'ǿ', - 'Ȁ' => 'Ȁ', - 'ȁ' => 'ȁ', - 'Ȃ' => 'Ȃ', - 'ȃ' => 'ȃ', - 'Ȅ' => 'Ȅ', - 'ȅ' => 'ȅ', - 'Ȇ' => 'Ȇ', - 'ȇ' => 'ȇ', - 'Ȉ' => 'Ȉ', - 'ȉ' => 'ȉ', - 'Ȋ' => 'Ȋ', - 'ȋ' => 'ȋ', - 'Ȍ' => 'Ȍ', - 'ȍ' => 'ȍ', - 'Ȏ' => 'Ȏ', - 'ȏ' => 'ȏ', - 'Ȑ' => 'Ȑ', - 'ȑ' => 'ȑ', - 'Ȓ' => 'Ȓ', - 'ȓ' => 'ȓ', - 'Ȕ' => 'Ȕ', - 'ȕ' => 'ȕ', - 'Ȗ' => 'Ȗ', - 'ȗ' => 'ȗ', - 'Ș' => 'Ș', - 'ș' => 'ș', - 'Ț' => 'Ț', - 'ț' => 'ț', - 'Ȟ' => 'Ȟ', - 'ȟ' => 'ȟ', - 'Ȧ' => 'Ȧ', - 'ȧ' => 'ȧ', - 'Ȩ' => 'Ȩ', - 'ȩ' => 'ȩ', - 'Ȫ' => 'Ȫ', - 'ȫ' => 'ȫ', - 'Ȭ' => 'Ȭ', - 'ȭ' => 'ȭ', - 'Ȯ' => 'Ȯ', - 'ȯ' => 'ȯ', - 'Ȱ' => 'Ȱ', - 'ȱ' => 'ȱ', - 'Ȳ' => 'Ȳ', - 'ȳ' => 'ȳ', - '΅' => '΅', - 'Ά' => 'Ά', - 'Έ' => 'Έ', - 'Ή' => 'Ή', - 'Ί' => 'Ί', - 'Ό' => 'Ό', - 'Ύ' => 'Ύ', - 'Ώ' => 'Ώ', - 'ΐ' => 'ΐ', - 'Ϊ' => 'Ϊ', - 'Ϋ' => 'Ϋ', - 'ά' => 'ά', - 'έ' => 'έ', - 'ή' => 'ή', - 'ί' => 'ί', - 'ΰ' => 'ΰ', - 'ϊ' => 'ϊ', - 'ϋ' => 'ϋ', - 'ό' => 'ό', - 'ύ' => 'ύ', - 'ώ' => 'ώ', - 'ϓ' => 'ϓ', - 'ϔ' => 'ϔ', - 'Ѐ' => 'Ѐ', - 'Ё' => 'Ё', - 'Ѓ' => 'Ѓ', - 'Ї' => 'Ї', - 'Ќ' => 'Ќ', - 'Ѝ' => 'Ѝ', - 'Ў' => 'Ў', - 'Й' => 'Й', - 'й' => 'й', - 'ѐ' => 'ѐ', - 'ё' => 'ё', - 'ѓ' => 'ѓ', - 'ї' => 'ї', - 'ќ' => 'ќ', - 'ѝ' => 'ѝ', - 'ў' => 'ў', - 'Ѷ' => 'Ѷ', - 'ѷ' => 'ѷ', - 'Ӂ' => 'Ӂ', - 'ӂ' => 'ӂ', - 'Ӑ' => 'Ӑ', - 'ӑ' => 'ӑ', - 'Ӓ' => 'Ӓ', - 'ӓ' => 'ӓ', - 'Ӗ' => 'Ӗ', - 'ӗ' => 'ӗ', - 'Ӛ' => 'Ӛ', - 'ӛ' => 'ӛ', - 'Ӝ' => 'Ӝ', - 'ӝ' => 'ӝ', - 'Ӟ' => 'Ӟ', - 'ӟ' => 'ӟ', - 'Ӣ' => 'Ӣ', - 'ӣ' => 'ӣ', - 'Ӥ' => 'Ӥ', - 'ӥ' => 'ӥ', - 'Ӧ' => 'Ӧ', - 'ӧ' => 'ӧ', - 'Ӫ' => 'Ӫ', - 'ӫ' => 'ӫ', - 'Ӭ' => 'Ӭ', - 'ӭ' => 'ӭ', - 'Ӯ' => 'Ӯ', - 'ӯ' => 'ӯ', - 'Ӱ' => 'Ӱ', - 'ӱ' => 'ӱ', - 'Ӳ' => 'Ӳ', - 'ӳ' => 'ӳ', - 'Ӵ' => 'Ӵ', - 'ӵ' => 'ӵ', - 'Ӹ' => 'Ӹ', - 'ӹ' => 'ӹ', - 'آ' => 'آ', - 'أ' => 'أ', - 'ؤ' => 'ؤ', - 'إ' => 'إ', - 'ئ' => 'ئ', - 'ۀ' => 'ۀ', - 'ۂ' => 'ۂ', - 'ۓ' => 'ۓ', - 'ऩ' => 'ऩ', - 'ऱ' => 'ऱ', - 'ऴ' => 'ऴ', - 'ো' => 'ো', - 'ৌ' => 'ৌ', - 'ୈ' => 'ୈ', - 'ୋ' => 'ୋ', - 'ୌ' => 'ୌ', - 'ஔ' => 'ஔ', - 'ொ' => 'ொ', - 'ோ' => 'ோ', - 'ௌ' => 'ௌ', - 'ై' => 'ై', - 'ೀ' => 'ೀ', - 'ೇ' => 'ೇ', - 'ೈ' => 'ೈ', - 'ೊ' => 'ೊ', - 'ೋ' => 'ೋ', - 'ൊ' => 'ൊ', - 'ോ' => 'ോ', - 'ൌ' => 'ൌ', - 'ේ' => 'ේ', - 'ො' => 'ො', - 'ෝ' => 'ෝ', - 'ෞ' => 'ෞ', - 'ဦ' => 'ဦ', - 'ᬆ' => 'ᬆ', - 'ᬈ' => 'ᬈ', - 'ᬊ' => 'ᬊ', - 'ᬌ' => 'ᬌ', - 'ᬎ' => 'ᬎ', - 'ᬒ' => 'ᬒ', - 'ᬻ' => 'ᬻ', - 'ᬽ' => 'ᬽ', - 'ᭀ' => 'ᭀ', - 'ᭁ' => 'ᭁ', - 'ᭃ' => 'ᭃ', - 'Ḁ' => 'Ḁ', - 'ḁ' => 'ḁ', - 'Ḃ' => 'Ḃ', - 'ḃ' => 'ḃ', - 'Ḅ' => 'Ḅ', - 'ḅ' => 'ḅ', - 'Ḇ' => 'Ḇ', - 'ḇ' => 'ḇ', - 'Ḉ' => 'Ḉ', - 'ḉ' => 'ḉ', - 'Ḋ' => 'Ḋ', - 'ḋ' => 'ḋ', - 'Ḍ' => 'Ḍ', - 'ḍ' => 'ḍ', - 'Ḏ' => 'Ḏ', - 'ḏ' => 'ḏ', - 'Ḑ' => 'Ḑ', - 'ḑ' => 'ḑ', - 'Ḓ' => 'Ḓ', - 'ḓ' => 'ḓ', - 'Ḕ' => 'Ḕ', - 'ḕ' => 'ḕ', - 'Ḗ' => 'Ḗ', - 'ḗ' => 'ḗ', - 'Ḙ' => 'Ḙ', - 'ḙ' => 'ḙ', - 'Ḛ' => 'Ḛ', - 'ḛ' => 'ḛ', - 'Ḝ' => 'Ḝ', - 'ḝ' => 'ḝ', - 'Ḟ' => 'Ḟ', - 'ḟ' => 'ḟ', - 'Ḡ' => 'Ḡ', - 'ḡ' => 'ḡ', - 'Ḣ' => 'Ḣ', - 'ḣ' => 'ḣ', - 'Ḥ' => 'Ḥ', - 'ḥ' => 'ḥ', - 'Ḧ' => 'Ḧ', - 'ḧ' => 'ḧ', - 'Ḩ' => 'Ḩ', - 'ḩ' => 'ḩ', - 'Ḫ' => 'Ḫ', - 'ḫ' => 'ḫ', - 'Ḭ' => 'Ḭ', - 'ḭ' => 'ḭ', - 'Ḯ' => 'Ḯ', - 'ḯ' => 'ḯ', - 'Ḱ' => 'Ḱ', - 'ḱ' => 'ḱ', - 'Ḳ' => 'Ḳ', - 'ḳ' => 'ḳ', - 'Ḵ' => 'Ḵ', - 'ḵ' => 'ḵ', - 'Ḷ' => 'Ḷ', - 'ḷ' => 'ḷ', - 'Ḹ' => 'Ḹ', - 'ḹ' => 'ḹ', - 'Ḻ' => 'Ḻ', - 'ḻ' => 'ḻ', - 'Ḽ' => 'Ḽ', - 'ḽ' => 'ḽ', - 'Ḿ' => 'Ḿ', - 'ḿ' => 'ḿ', - 'Ṁ' => 'Ṁ', - 'ṁ' => 'ṁ', - 'Ṃ' => 'Ṃ', - 'ṃ' => 'ṃ', - 'Ṅ' => 'Ṅ', - 'ṅ' => 'ṅ', - 'Ṇ' => 'Ṇ', - 'ṇ' => 'ṇ', - 'Ṉ' => 'Ṉ', - 'ṉ' => 'ṉ', - 'Ṋ' => 'Ṋ', - 'ṋ' => 'ṋ', - 'Ṍ' => 'Ṍ', - 'ṍ' => 'ṍ', - 'Ṏ' => 'Ṏ', - 'ṏ' => 'ṏ', - 'Ṑ' => 'Ṑ', - 'ṑ' => 'ṑ', - 'Ṓ' => 'Ṓ', - 'ṓ' => 'ṓ', - 'Ṕ' => 'Ṕ', - 'ṕ' => 'ṕ', - 'Ṗ' => 'Ṗ', - 'ṗ' => 'ṗ', - 'Ṙ' => 'Ṙ', - 'ṙ' => 'ṙ', - 'Ṛ' => 'Ṛ', - 'ṛ' => 'ṛ', - 'Ṝ' => 'Ṝ', - 'ṝ' => 'ṝ', - 'Ṟ' => 'Ṟ', - 'ṟ' => 'ṟ', - 'Ṡ' => 'Ṡ', - 'ṡ' => 'ṡ', - 'Ṣ' => 'Ṣ', - 'ṣ' => 'ṣ', - 'Ṥ' => 'Ṥ', - 'ṥ' => 'ṥ', - 'Ṧ' => 'Ṧ', - 'ṧ' => 'ṧ', - 'Ṩ' => 'Ṩ', - 'ṩ' => 'ṩ', - 'Ṫ' => 'Ṫ', - 'ṫ' => 'ṫ', - 'Ṭ' => 'Ṭ', - 'ṭ' => 'ṭ', - 'Ṯ' => 'Ṯ', - 'ṯ' => 'ṯ', - 'Ṱ' => 'Ṱ', - 'ṱ' => 'ṱ', - 'Ṳ' => 'Ṳ', - 'ṳ' => 'ṳ', - 'Ṵ' => 'Ṵ', - 'ṵ' => 'ṵ', - 'Ṷ' => 'Ṷ', - 'ṷ' => 'ṷ', - 'Ṹ' => 'Ṹ', - 'ṹ' => 'ṹ', - 'Ṻ' => 'Ṻ', - 'ṻ' => 'ṻ', - 'Ṽ' => 'Ṽ', - 'ṽ' => 'ṽ', - 'Ṿ' => 'Ṿ', - 'ṿ' => 'ṿ', - 'Ẁ' => 'Ẁ', - 'ẁ' => 'ẁ', - 'Ẃ' => 'Ẃ', - 'ẃ' => 'ẃ', - 'Ẅ' => 'Ẅ', - 'ẅ' => 'ẅ', - 'Ẇ' => 'Ẇ', - 'ẇ' => 'ẇ', - 'Ẉ' => 'Ẉ', - 'ẉ' => 'ẉ', - 'Ẋ' => 'Ẋ', - 'ẋ' => 'ẋ', - 'Ẍ' => 'Ẍ', - 'ẍ' => 'ẍ', - 'Ẏ' => 'Ẏ', - 'ẏ' => 'ẏ', - 'Ẑ' => 'Ẑ', - 'ẑ' => 'ẑ', - 'Ẓ' => 'Ẓ', - 'ẓ' => 'ẓ', - 'Ẕ' => 'Ẕ', - 'ẕ' => 'ẕ', - 'ẖ' => 'ẖ', - 'ẗ' => 'ẗ', - 'ẘ' => 'ẘ', - 'ẙ' => 'ẙ', - 'ẛ' => 'ẛ', - 'Ạ' => 'Ạ', - 'ạ' => 'ạ', - 'Ả' => 'Ả', - 'ả' => 'ả', - 'Ấ' => 'Ấ', - 'ấ' => 'ấ', - 'Ầ' => 'Ầ', - 'ầ' => 'ầ', - 'Ẩ' => 'Ẩ', - 'ẩ' => 'ẩ', - 'Ẫ' => 'Ẫ', - 'ẫ' => 'ẫ', - 'Ậ' => 'Ậ', - 'ậ' => 'ậ', - 'Ắ' => 'Ắ', - 'ắ' => 'ắ', - 'Ằ' => 'Ằ', - 'ằ' => 'ằ', - 'Ẳ' => 'Ẳ', - 'ẳ' => 'ẳ', - 'Ẵ' => 'Ẵ', - 'ẵ' => 'ẵ', - 'Ặ' => 'Ặ', - 'ặ' => 'ặ', - 'Ẹ' => 'Ẹ', - 'ẹ' => 'ẹ', - 'Ẻ' => 'Ẻ', - 'ẻ' => 'ẻ', - 'Ẽ' => 'Ẽ', - 'ẽ' => 'ẽ', - 'Ế' => 'Ế', - 'ế' => 'ế', - 'Ề' => 'Ề', - 'ề' => 'ề', - 'Ể' => 'Ể', - 'ể' => 'ể', - 'Ễ' => 'Ễ', - 'ễ' => 'ễ', - 'Ệ' => 'Ệ', - 'ệ' => 'ệ', - 'Ỉ' => 'Ỉ', - 'ỉ' => 'ỉ', - 'Ị' => 'Ị', - 'ị' => 'ị', - 'Ọ' => 'Ọ', - 'ọ' => 'ọ', - 'Ỏ' => 'Ỏ', - 'ỏ' => 'ỏ', - 'Ố' => 'Ố', - 'ố' => 'ố', - 'Ồ' => 'Ồ', - 'ồ' => 'ồ', - 'Ổ' => 'Ổ', - 'ổ' => 'ổ', - 'Ỗ' => 'Ỗ', - 'ỗ' => 'ỗ', - 'Ộ' => 'Ộ', - 'ộ' => 'ộ', - 'Ớ' => 'Ớ', - 'ớ' => 'ớ', - 'Ờ' => 'Ờ', - 'ờ' => 'ờ', - 'Ở' => 'Ở', - 'ở' => 'ở', - 'Ỡ' => 'Ỡ', - 'ỡ' => 'ỡ', - 'Ợ' => 'Ợ', - 'ợ' => 'ợ', - 'Ụ' => 'Ụ', - 'ụ' => 'ụ', - 'Ủ' => 'Ủ', - 'ủ' => 'ủ', - 'Ứ' => 'Ứ', - 'ứ' => 'ứ', - 'Ừ' => 'Ừ', - 'ừ' => 'ừ', - 'Ử' => 'Ử', - 'ử' => 'ử', - 'Ữ' => 'Ữ', - 'ữ' => 'ữ', - 'Ự' => 'Ự', - 'ự' => 'ự', - 'Ỳ' => 'Ỳ', - 'ỳ' => 'ỳ', - 'Ỵ' => 'Ỵ', - 'ỵ' => 'ỵ', - 'Ỷ' => 'Ỷ', - 'ỷ' => 'ỷ', - 'Ỹ' => 'Ỹ', - 'ỹ' => 'ỹ', - 'ἀ' => 'ἀ', - 'ἁ' => 'ἁ', - 'ἂ' => 'ἂ', - 'ἃ' => 'ἃ', - 'ἄ' => 'ἄ', - 'ἅ' => 'ἅ', - 'ἆ' => 'ἆ', - 'ἇ' => 'ἇ', - 'Ἀ' => 'Ἀ', - 'Ἁ' => 'Ἁ', - 'Ἂ' => 'Ἂ', - 'Ἃ' => 'Ἃ', - 'Ἄ' => 'Ἄ', - 'Ἅ' => 'Ἅ', - 'Ἆ' => 'Ἆ', - 'Ἇ' => 'Ἇ', - 'ἐ' => 'ἐ', - 'ἑ' => 'ἑ', - 'ἒ' => 'ἒ', - 'ἓ' => 'ἓ', - 'ἔ' => 'ἔ', - 'ἕ' => 'ἕ', - 'Ἐ' => 'Ἐ', - 'Ἑ' => 'Ἑ', - 'Ἒ' => 'Ἒ', - 'Ἓ' => 'Ἓ', - 'Ἔ' => 'Ἔ', - 'Ἕ' => 'Ἕ', - 'ἠ' => 'ἠ', - 'ἡ' => 'ἡ', - 'ἢ' => 'ἢ', - 'ἣ' => 'ἣ', - 'ἤ' => 'ἤ', - 'ἥ' => 'ἥ', - 'ἦ' => 'ἦ', - 'ἧ' => 'ἧ', - 'Ἠ' => 'Ἠ', - 'Ἡ' => 'Ἡ', - 'Ἢ' => 'Ἢ', - 'Ἣ' => 'Ἣ', - 'Ἤ' => 'Ἤ', - 'Ἥ' => 'Ἥ', - 'Ἦ' => 'Ἦ', - 'Ἧ' => 'Ἧ', - 'ἰ' => 'ἰ', - 'ἱ' => 'ἱ', - 'ἲ' => 'ἲ', - 'ἳ' => 'ἳ', - 'ἴ' => 'ἴ', - 'ἵ' => 'ἵ', - 'ἶ' => 'ἶ', - 'ἷ' => 'ἷ', - 'Ἰ' => 'Ἰ', - 'Ἱ' => 'Ἱ', - 'Ἲ' => 'Ἲ', - 'Ἳ' => 'Ἳ', - 'Ἴ' => 'Ἴ', - 'Ἵ' => 'Ἵ', - 'Ἶ' => 'Ἶ', - 'Ἷ' => 'Ἷ', - 'ὀ' => 'ὀ', - 'ὁ' => 'ὁ', - 'ὂ' => 'ὂ', - 'ὃ' => 'ὃ', - 'ὄ' => 'ὄ', - 'ὅ' => 'ὅ', - 'Ὀ' => 'Ὀ', - 'Ὁ' => 'Ὁ', - 'Ὂ' => 'Ὂ', - 'Ὃ' => 'Ὃ', - 'Ὄ' => 'Ὄ', - 'Ὅ' => 'Ὅ', - 'ὐ' => 'ὐ', - 'ὑ' => 'ὑ', - 'ὒ' => 'ὒ', - 'ὓ' => 'ὓ', - 'ὔ' => 'ὔ', - 'ὕ' => 'ὕ', - 'ὖ' => 'ὖ', - 'ὗ' => 'ὗ', - 'Ὑ' => 'Ὑ', - 'Ὓ' => 'Ὓ', - 'Ὕ' => 'Ὕ', - 'Ὗ' => 'Ὗ', - 'ὠ' => 'ὠ', - 'ὡ' => 'ὡ', - 'ὢ' => 'ὢ', - 'ὣ' => 'ὣ', - 'ὤ' => 'ὤ', - 'ὥ' => 'ὥ', - 'ὦ' => 'ὦ', - 'ὧ' => 'ὧ', - 'Ὠ' => 'Ὠ', - 'Ὡ' => 'Ὡ', - 'Ὢ' => 'Ὢ', - 'Ὣ' => 'Ὣ', - 'Ὤ' => 'Ὤ', - 'Ὥ' => 'Ὥ', - 'Ὦ' => 'Ὦ', - 'Ὧ' => 'Ὧ', - 'ὰ' => 'ὰ', - 'ὲ' => 'ὲ', - 'ὴ' => 'ὴ', - 'ὶ' => 'ὶ', - 'ὸ' => 'ὸ', - 'ὺ' => 'ὺ', - 'ὼ' => 'ὼ', - 'ᾀ' => 'ᾀ', - 'ᾁ' => 'ᾁ', - 'ᾂ' => 'ᾂ', - 'ᾃ' => 'ᾃ', - 'ᾄ' => 'ᾄ', - 'ᾅ' => 'ᾅ', - 'ᾆ' => 'ᾆ', - 'ᾇ' => 'ᾇ', - 'ᾈ' => 'ᾈ', - 'ᾉ' => 'ᾉ', - 'ᾊ' => 'ᾊ', - 'ᾋ' => 'ᾋ', - 'ᾌ' => 'ᾌ', - 'ᾍ' => 'ᾍ', - 'ᾎ' => 'ᾎ', - 'ᾏ' => 'ᾏ', - 'ᾐ' => 'ᾐ', - 'ᾑ' => 'ᾑ', - 'ᾒ' => 'ᾒ', - 'ᾓ' => 'ᾓ', - 'ᾔ' => 'ᾔ', - 'ᾕ' => 'ᾕ', - 'ᾖ' => 'ᾖ', - 'ᾗ' => 'ᾗ', - 'ᾘ' => 'ᾘ', - 'ᾙ' => 'ᾙ', - 'ᾚ' => 'ᾚ', - 'ᾛ' => 'ᾛ', - 'ᾜ' => 'ᾜ', - 'ᾝ' => 'ᾝ', - 'ᾞ' => 'ᾞ', - 'ᾟ' => 'ᾟ', - 'ᾠ' => 'ᾠ', - 'ᾡ' => 'ᾡ', - 'ᾢ' => 'ᾢ', - 'ᾣ' => 'ᾣ', - 'ᾤ' => 'ᾤ', - 'ᾥ' => 'ᾥ', - 'ᾦ' => 'ᾦ', - 'ᾧ' => 'ᾧ', - 'ᾨ' => 'ᾨ', - 'ᾩ' => 'ᾩ', - 'ᾪ' => 'ᾪ', - 'ᾫ' => 'ᾫ', - 'ᾬ' => 'ᾬ', - 'ᾭ' => 'ᾭ', - 'ᾮ' => 'ᾮ', - 'ᾯ' => 'ᾯ', - 'ᾰ' => 'ᾰ', - 'ᾱ' => 'ᾱ', - 'ᾲ' => 'ᾲ', - 'ᾳ' => 'ᾳ', - 'ᾴ' => 'ᾴ', - 'ᾶ' => 'ᾶ', - 'ᾷ' => 'ᾷ', - 'Ᾰ' => 'Ᾰ', - 'Ᾱ' => 'Ᾱ', - 'Ὰ' => 'Ὰ', - 'ᾼ' => 'ᾼ', - '῁' => '῁', - 'ῂ' => 'ῂ', - 'ῃ' => 'ῃ', - 'ῄ' => 'ῄ', - 'ῆ' => 'ῆ', - 'ῇ' => 'ῇ', - 'Ὲ' => 'Ὲ', - 'Ὴ' => 'Ὴ', - 'ῌ' => 'ῌ', - '῍' => '῍', - '῎' => '῎', - '῏' => '῏', - 'ῐ' => 'ῐ', - 'ῑ' => 'ῑ', - 'ῒ' => 'ῒ', - 'ῖ' => 'ῖ', - 'ῗ' => 'ῗ', - 'Ῐ' => 'Ῐ', - 'Ῑ' => 'Ῑ', - 'Ὶ' => 'Ὶ', - '῝' => '῝', - '῞' => '῞', - '῟' => '῟', - 'ῠ' => 'ῠ', - 'ῡ' => 'ῡ', - 'ῢ' => 'ῢ', - 'ῤ' => 'ῤ', - 'ῥ' => 'ῥ', - 'ῦ' => 'ῦ', - 'ῧ' => 'ῧ', - 'Ῠ' => 'Ῠ', - 'Ῡ' => 'Ῡ', - 'Ὺ' => 'Ὺ', - 'Ῥ' => 'Ῥ', - '῭' => '῭', - 'ῲ' => 'ῲ', - 'ῳ' => 'ῳ', - 'ῴ' => 'ῴ', - 'ῶ' => 'ῶ', - 'ῷ' => 'ῷ', - 'Ὸ' => 'Ὸ', - 'Ὼ' => 'Ὼ', - 'ῼ' => 'ῼ', - '↚' => '↚', - '↛' => '↛', - '↮' => '↮', - '⇍' => '⇍', - '⇎' => '⇎', - '⇏' => '⇏', - '∄' => '∄', - '∉' => '∉', - '∌' => '∌', - '∤' => '∤', - '∦' => '∦', - '≁' => '≁', - '≄' => '≄', - '≇' => '≇', - '≉' => '≉', - '≠' => '≠', - '≢' => '≢', - '≭' => '≭', - '≮' => '≮', - '≯' => '≯', - '≰' => '≰', - '≱' => '≱', - '≴' => '≴', - '≵' => '≵', - '≸' => '≸', - '≹' => '≹', - '⊀' => '⊀', - '⊁' => '⊁', - '⊄' => '⊄', - '⊅' => '⊅', - '⊈' => '⊈', - '⊉' => '⊉', - '⊬' => '⊬', - '⊭' => '⊭', - '⊮' => '⊮', - '⊯' => '⊯', - '⋠' => '⋠', - '⋡' => '⋡', - '⋢' => '⋢', - '⋣' => '⋣', - '⋪' => '⋪', - '⋫' => '⋫', - '⋬' => '⋬', - '⋭' => '⋭', - 'が' => 'が', - 'ぎ' => 'ぎ', - 'ぐ' => 'ぐ', - 'げ' => 'げ', - 'ご' => 'ご', - 'ざ' => 'ざ', - 'じ' => 'じ', - 'ず' => 'ず', - 'ぜ' => 'ぜ', - 'ぞ' => 'ぞ', - 'だ' => 'だ', - 'ぢ' => 'ぢ', - 'づ' => 'づ', - 'で' => 'で', - 'ど' => 'ど', - 'ば' => 'ば', - 'ぱ' => 'ぱ', - 'び' => 'び', - 'ぴ' => 'ぴ', - 'ぶ' => 'ぶ', - 'ぷ' => 'ぷ', - 'べ' => 'べ', - 'ぺ' => 'ぺ', - 'ぼ' => 'ぼ', - 'ぽ' => 'ぽ', - 'ゔ' => 'ゔ', - 'ゞ' => 'ゞ', - 'ガ' => 'ガ', - 'ギ' => 'ギ', - 'グ' => 'グ', - 'ゲ' => 'ゲ', - 'ゴ' => 'ゴ', - 'ザ' => 'ザ', - 'ジ' => 'ジ', - 'ズ' => 'ズ', - 'ゼ' => 'ゼ', - 'ゾ' => 'ゾ', - 'ダ' => 'ダ', - 'ヂ' => 'ヂ', - 'ヅ' => 'ヅ', - 'デ' => 'デ', - 'ド' => 'ド', - 'バ' => 'バ', - 'パ' => 'パ', - 'ビ' => 'ビ', - 'ピ' => 'ピ', - 'ブ' => 'ブ', - 'プ' => 'プ', - 'ベ' => 'ベ', - 'ペ' => 'ペ', - 'ボ' => 'ボ', - 'ポ' => 'ポ', - 'ヴ' => 'ヴ', - 'ヷ' => 'ヷ', - 'ヸ' => 'ヸ', - 'ヹ' => 'ヹ', - 'ヺ' => 'ヺ', - 'ヾ' => 'ヾ', - '𑂚' => '𑂚', - '𑂜' => '𑂜', - '𑂫' => '𑂫', - '𑄮' => '𑄮', - '𑄯' => '𑄯', - '𑍋' => '𑍋', - '𑍌' => '𑍌', - '𑒻' => '𑒻', - '𑒼' => '𑒼', - '𑒾' => '𑒾', - '𑖺' => '𑖺', - '𑖻' => '𑖻', - '𑤸' => '𑤸', -); diff --git a/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php deleted file mode 100644 index 5a3e8e096..000000000 --- a/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php +++ /dev/null @@ -1,2065 +0,0 @@ - 'À', - 'Á' => 'Á', - 'Â' => 'Â', - 'Ã' => 'Ã', - 'Ä' => 'Ä', - 'Å' => 'Å', - 'Ç' => 'Ç', - 'È' => 'È', - 'É' => 'É', - 'Ê' => 'Ê', - 'Ë' => 'Ë', - 'Ì' => 'Ì', - 'Í' => 'Í', - 'Î' => 'Î', - 'Ï' => 'Ï', - 'Ñ' => 'Ñ', - 'Ò' => 'Ò', - 'Ó' => 'Ó', - 'Ô' => 'Ô', - 'Õ' => 'Õ', - 'Ö' => 'Ö', - 'Ù' => 'Ù', - 'Ú' => 'Ú', - 'Û' => 'Û', - 'Ü' => 'Ü', - 'Ý' => 'Ý', - 'à' => 'à', - 'á' => 'á', - 'â' => 'â', - 'ã' => 'ã', - 'ä' => 'ä', - 'å' => 'å', - 'ç' => 'ç', - 'è' => 'è', - 'é' => 'é', - 'ê' => 'ê', - 'ë' => 'ë', - 'ì' => 'ì', - 'í' => 'í', - 'î' => 'î', - 'ï' => 'ï', - 'ñ' => 'ñ', - 'ò' => 'ò', - 'ó' => 'ó', - 'ô' => 'ô', - 'õ' => 'õ', - 'ö' => 'ö', - 'ù' => 'ù', - 'ú' => 'ú', - 'û' => 'û', - 'ü' => 'ü', - 'ý' => 'ý', - 'ÿ' => 'ÿ', - 'Ā' => 'Ā', - 'ā' => 'ā', - 'Ă' => 'Ă', - 'ă' => 'ă', - 'Ą' => 'Ą', - 'ą' => 'ą', - 'Ć' => 'Ć', - 'ć' => 'ć', - 'Ĉ' => 'Ĉ', - 'ĉ' => 'ĉ', - 'Ċ' => 'Ċ', - 'ċ' => 'ċ', - 'Č' => 'Č', - 'č' => 'č', - 'Ď' => 'Ď', - 'ď' => 'ď', - 'Ē' => 'Ē', - 'ē' => 'ē', - 'Ĕ' => 'Ĕ', - 'ĕ' => 'ĕ', - 'Ė' => 'Ė', - 'ė' => 'ė', - 'Ę' => 'Ę', - 'ę' => 'ę', - 'Ě' => 'Ě', - 'ě' => 'ě', - 'Ĝ' => 'Ĝ', - 'ĝ' => 'ĝ', - 'Ğ' => 'Ğ', - 'ğ' => 'ğ', - 'Ġ' => 'Ġ', - 'ġ' => 'ġ', - 'Ģ' => 'Ģ', - 'ģ' => 'ģ', - 'Ĥ' => 'Ĥ', - 'ĥ' => 'ĥ', - 'Ĩ' => 'Ĩ', - 'ĩ' => 'ĩ', - 'Ī' => 'Ī', - 'ī' => 'ī', - 'Ĭ' => 'Ĭ', - 'ĭ' => 'ĭ', - 'Į' => 'Į', - 'į' => 'į', - 'İ' => 'İ', - 'Ĵ' => 'Ĵ', - 'ĵ' => 'ĵ', - 'Ķ' => 'Ķ', - 'ķ' => 'ķ', - 'Ĺ' => 'Ĺ', - 'ĺ' => 'ĺ', - 'Ļ' => 'Ļ', - 'ļ' => 'ļ', - 'Ľ' => 'Ľ', - 'ľ' => 'ľ', - 'Ń' => 'Ń', - 'ń' => 'ń', - 'Ņ' => 'Ņ', - 'ņ' => 'ņ', - 'Ň' => 'Ň', - 'ň' => 'ň', - 'Ō' => 'Ō', - 'ō' => 'ō', - 'Ŏ' => 'Ŏ', - 'ŏ' => 'ŏ', - 'Ő' => 'Ő', - 'ő' => 'ő', - 'Ŕ' => 'Ŕ', - 'ŕ' => 'ŕ', - 'Ŗ' => 'Ŗ', - 'ŗ' => 'ŗ', - 'Ř' => 'Ř', - 'ř' => 'ř', - 'Ś' => 'Ś', - 'ś' => 'ś', - 'Ŝ' => 'Ŝ', - 'ŝ' => 'ŝ', - 'Ş' => 'Ş', - 'ş' => 'ş', - 'Š' => 'Š', - 'š' => 'š', - 'Ţ' => 'Ţ', - 'ţ' => 'ţ', - 'Ť' => 'Ť', - 'ť' => 'ť', - 'Ũ' => 'Ũ', - 'ũ' => 'ũ', - 'Ū' => 'Ū', - 'ū' => 'ū', - 'Ŭ' => 'Ŭ', - 'ŭ' => 'ŭ', - 'Ů' => 'Ů', - 'ů' => 'ů', - 'Ű' => 'Ű', - 'ű' => 'ű', - 'Ų' => 'Ų', - 'ų' => 'ų', - 'Ŵ' => 'Ŵ', - 'ŵ' => 'ŵ', - 'Ŷ' => 'Ŷ', - 'ŷ' => 'ŷ', - 'Ÿ' => 'Ÿ', - 'Ź' => 'Ź', - 'ź' => 'ź', - 'Ż' => 'Ż', - 'ż' => 'ż', - 'Ž' => 'Ž', - 'ž' => 'ž', - 'Ơ' => 'Ơ', - 'ơ' => 'ơ', - 'Ư' => 'Ư', - 'ư' => 'ư', - 'Ǎ' => 'Ǎ', - 'ǎ' => 'ǎ', - 'Ǐ' => 'Ǐ', - 'ǐ' => 'ǐ', - 'Ǒ' => 'Ǒ', - 'ǒ' => 'ǒ', - 'Ǔ' => 'Ǔ', - 'ǔ' => 'ǔ', - 'Ǖ' => 'Ǖ', - 'ǖ' => 'ǖ', - 'Ǘ' => 'Ǘ', - 'ǘ' => 'ǘ', - 'Ǚ' => 'Ǚ', - 'ǚ' => 'ǚ', - 'Ǜ' => 'Ǜ', - 'ǜ' => 'ǜ', - 'Ǟ' => 'Ǟ', - 'ǟ' => 'ǟ', - 'Ǡ' => 'Ǡ', - 'ǡ' => 'ǡ', - 'Ǣ' => 'Ǣ', - 'ǣ' => 'ǣ', - 'Ǧ' => 'Ǧ', - 'ǧ' => 'ǧ', - 'Ǩ' => 'Ǩ', - 'ǩ' => 'ǩ', - 'Ǫ' => 'Ǫ', - 'ǫ' => 'ǫ', - 'Ǭ' => 'Ǭ', - 'ǭ' => 'ǭ', - 'Ǯ' => 'Ǯ', - 'ǯ' => 'ǯ', - 'ǰ' => 'ǰ', - 'Ǵ' => 'Ǵ', - 'ǵ' => 'ǵ', - 'Ǹ' => 'Ǹ', - 'ǹ' => 'ǹ', - 'Ǻ' => 'Ǻ', - 'ǻ' => 'ǻ', - 'Ǽ' => 'Ǽ', - 'ǽ' => 'ǽ', - 'Ǿ' => 'Ǿ', - 'ǿ' => 'ǿ', - 'Ȁ' => 'Ȁ', - 'ȁ' => 'ȁ', - 'Ȃ' => 'Ȃ', - 'ȃ' => 'ȃ', - 'Ȅ' => 'Ȅ', - 'ȅ' => 'ȅ', - 'Ȇ' => 'Ȇ', - 'ȇ' => 'ȇ', - 'Ȉ' => 'Ȉ', - 'ȉ' => 'ȉ', - 'Ȋ' => 'Ȋ', - 'ȋ' => 'ȋ', - 'Ȍ' => 'Ȍ', - 'ȍ' => 'ȍ', - 'Ȏ' => 'Ȏ', - 'ȏ' => 'ȏ', - 'Ȑ' => 'Ȑ', - 'ȑ' => 'ȑ', - 'Ȓ' => 'Ȓ', - 'ȓ' => 'ȓ', - 'Ȕ' => 'Ȕ', - 'ȕ' => 'ȕ', - 'Ȗ' => 'Ȗ', - 'ȗ' => 'ȗ', - 'Ș' => 'Ș', - 'ș' => 'ș', - 'Ț' => 'Ț', - 'ț' => 'ț', - 'Ȟ' => 'Ȟ', - 'ȟ' => 'ȟ', - 'Ȧ' => 'Ȧ', - 'ȧ' => 'ȧ', - 'Ȩ' => 'Ȩ', - 'ȩ' => 'ȩ', - 'Ȫ' => 'Ȫ', - 'ȫ' => 'ȫ', - 'Ȭ' => 'Ȭ', - 'ȭ' => 'ȭ', - 'Ȯ' => 'Ȯ', - 'ȯ' => 'ȯ', - 'Ȱ' => 'Ȱ', - 'ȱ' => 'ȱ', - 'Ȳ' => 'Ȳ', - 'ȳ' => 'ȳ', - '̀' => '̀', - '́' => '́', - '̓' => '̓', - '̈́' => '̈́', - 'ʹ' => 'ʹ', - ';' => ';', - '΅' => '΅', - 'Ά' => 'Ά', - '·' => '·', - 'Έ' => 'Έ', - 'Ή' => 'Ή', - 'Ί' => 'Ί', - 'Ό' => 'Ό', - 'Ύ' => 'Ύ', - 'Ώ' => 'Ώ', - 'ΐ' => 'ΐ', - 'Ϊ' => 'Ϊ', - 'Ϋ' => 'Ϋ', - 'ά' => 'ά', - 'έ' => 'έ', - 'ή' => 'ή', - 'ί' => 'ί', - 'ΰ' => 'ΰ', - 'ϊ' => 'ϊ', - 'ϋ' => 'ϋ', - 'ό' => 'ό', - 'ύ' => 'ύ', - 'ώ' => 'ώ', - 'ϓ' => 'ϓ', - 'ϔ' => 'ϔ', - 'Ѐ' => 'Ѐ', - 'Ё' => 'Ё', - 'Ѓ' => 'Ѓ', - 'Ї' => 'Ї', - 'Ќ' => 'Ќ', - 'Ѝ' => 'Ѝ', - 'Ў' => 'Ў', - 'Й' => 'Й', - 'й' => 'й', - 'ѐ' => 'ѐ', - 'ё' => 'ё', - 'ѓ' => 'ѓ', - 'ї' => 'ї', - 'ќ' => 'ќ', - 'ѝ' => 'ѝ', - 'ў' => 'ў', - 'Ѷ' => 'Ѷ', - 'ѷ' => 'ѷ', - 'Ӂ' => 'Ӂ', - 'ӂ' => 'ӂ', - 'Ӑ' => 'Ӑ', - 'ӑ' => 'ӑ', - 'Ӓ' => 'Ӓ', - 'ӓ' => 'ӓ', - 'Ӗ' => 'Ӗ', - 'ӗ' => 'ӗ', - 'Ӛ' => 'Ӛ', - 'ӛ' => 'ӛ', - 'Ӝ' => 'Ӝ', - 'ӝ' => 'ӝ', - 'Ӟ' => 'Ӟ', - 'ӟ' => 'ӟ', - 'Ӣ' => 'Ӣ', - 'ӣ' => 'ӣ', - 'Ӥ' => 'Ӥ', - 'ӥ' => 'ӥ', - 'Ӧ' => 'Ӧ', - 'ӧ' => 'ӧ', - 'Ӫ' => 'Ӫ', - 'ӫ' => 'ӫ', - 'Ӭ' => 'Ӭ', - 'ӭ' => 'ӭ', - 'Ӯ' => 'Ӯ', - 'ӯ' => 'ӯ', - 'Ӱ' => 'Ӱ', - 'ӱ' => 'ӱ', - 'Ӳ' => 'Ӳ', - 'ӳ' => 'ӳ', - 'Ӵ' => 'Ӵ', - 'ӵ' => 'ӵ', - 'Ӹ' => 'Ӹ', - 'ӹ' => 'ӹ', - 'آ' => 'آ', - 'أ' => 'أ', - 'ؤ' => 'ؤ', - 'إ' => 'إ', - 'ئ' => 'ئ', - 'ۀ' => 'ۀ', - 'ۂ' => 'ۂ', - 'ۓ' => 'ۓ', - 'ऩ' => 'ऩ', - 'ऱ' => 'ऱ', - 'ऴ' => 'ऴ', - 'क़' => 'क़', - 'ख़' => 'ख़', - 'ग़' => 'ग़', - 'ज़' => 'ज़', - 'ड़' => 'ड़', - 'ढ़' => 'ढ़', - 'फ़' => 'फ़', - 'य़' => 'य़', - 'ো' => 'ো', - 'ৌ' => 'ৌ', - 'ড়' => 'ড়', - 'ঢ়' => 'ঢ়', - 'য়' => 'য়', - 'ਲ਼' => 'ਲ਼', - 'ਸ਼' => 'ਸ਼', - 'ਖ਼' => 'ਖ਼', - 'ਗ਼' => 'ਗ਼', - 'ਜ਼' => 'ਜ਼', - 'ਫ਼' => 'ਫ਼', - 'ୈ' => 'ୈ', - 'ୋ' => 'ୋ', - 'ୌ' => 'ୌ', - 'ଡ଼' => 'ଡ଼', - 'ଢ଼' => 'ଢ଼', - 'ஔ' => 'ஔ', - 'ொ' => 'ொ', - 'ோ' => 'ோ', - 'ௌ' => 'ௌ', - 'ై' => 'ై', - 'ೀ' => 'ೀ', - 'ೇ' => 'ೇ', - 'ೈ' => 'ೈ', - 'ೊ' => 'ೊ', - 'ೋ' => 'ೋ', - 'ൊ' => 'ൊ', - 'ോ' => 'ോ', - 'ൌ' => 'ൌ', - 'ේ' => 'ේ', - 'ො' => 'ො', - 'ෝ' => 'ෝ', - 'ෞ' => 'ෞ', - 'གྷ' => 'གྷ', - 'ཌྷ' => 'ཌྷ', - 'དྷ' => 'དྷ', - 'བྷ' => 'བྷ', - 'ཛྷ' => 'ཛྷ', - 'ཀྵ' => 'ཀྵ', - 'ཱི' => 'ཱི', - 'ཱུ' => 'ཱུ', - 'ྲྀ' => 'ྲྀ', - 'ླྀ' => 'ླྀ', - 'ཱྀ' => 'ཱྀ', - 'ྒྷ' => 'ྒྷ', - 'ྜྷ' => 'ྜྷ', - 'ྡྷ' => 'ྡྷ', - 'ྦྷ' => 'ྦྷ', - 'ྫྷ' => 'ྫྷ', - 'ྐྵ' => 'ྐྵ', - 'ဦ' => 'ဦ', - 'ᬆ' => 'ᬆ', - 'ᬈ' => 'ᬈ', - 'ᬊ' => 'ᬊ', - 'ᬌ' => 'ᬌ', - 'ᬎ' => 'ᬎ', - 'ᬒ' => 'ᬒ', - 'ᬻ' => 'ᬻ', - 'ᬽ' => 'ᬽ', - 'ᭀ' => 'ᭀ', - 'ᭁ' => 'ᭁ', - 'ᭃ' => 'ᭃ', - 'Ḁ' => 'Ḁ', - 'ḁ' => 'ḁ', - 'Ḃ' => 'Ḃ', - 'ḃ' => 'ḃ', - 'Ḅ' => 'Ḅ', - 'ḅ' => 'ḅ', - 'Ḇ' => 'Ḇ', - 'ḇ' => 'ḇ', - 'Ḉ' => 'Ḉ', - 'ḉ' => 'ḉ', - 'Ḋ' => 'Ḋ', - 'ḋ' => 'ḋ', - 'Ḍ' => 'Ḍ', - 'ḍ' => 'ḍ', - 'Ḏ' => 'Ḏ', - 'ḏ' => 'ḏ', - 'Ḑ' => 'Ḑ', - 'ḑ' => 'ḑ', - 'Ḓ' => 'Ḓ', - 'ḓ' => 'ḓ', - 'Ḕ' => 'Ḕ', - 'ḕ' => 'ḕ', - 'Ḗ' => 'Ḗ', - 'ḗ' => 'ḗ', - 'Ḙ' => 'Ḙ', - 'ḙ' => 'ḙ', - 'Ḛ' => 'Ḛ', - 'ḛ' => 'ḛ', - 'Ḝ' => 'Ḝ', - 'ḝ' => 'ḝ', - 'Ḟ' => 'Ḟ', - 'ḟ' => 'ḟ', - 'Ḡ' => 'Ḡ', - 'ḡ' => 'ḡ', - 'Ḣ' => 'Ḣ', - 'ḣ' => 'ḣ', - 'Ḥ' => 'Ḥ', - 'ḥ' => 'ḥ', - 'Ḧ' => 'Ḧ', - 'ḧ' => 'ḧ', - 'Ḩ' => 'Ḩ', - 'ḩ' => 'ḩ', - 'Ḫ' => 'Ḫ', - 'ḫ' => 'ḫ', - 'Ḭ' => 'Ḭ', - 'ḭ' => 'ḭ', - 'Ḯ' => 'Ḯ', - 'ḯ' => 'ḯ', - 'Ḱ' => 'Ḱ', - 'ḱ' => 'ḱ', - 'Ḳ' => 'Ḳ', - 'ḳ' => 'ḳ', - 'Ḵ' => 'Ḵ', - 'ḵ' => 'ḵ', - 'Ḷ' => 'Ḷ', - 'ḷ' => 'ḷ', - 'Ḹ' => 'Ḹ', - 'ḹ' => 'ḹ', - 'Ḻ' => 'Ḻ', - 'ḻ' => 'ḻ', - 'Ḽ' => 'Ḽ', - 'ḽ' => 'ḽ', - 'Ḿ' => 'Ḿ', - 'ḿ' => 'ḿ', - 'Ṁ' => 'Ṁ', - 'ṁ' => 'ṁ', - 'Ṃ' => 'Ṃ', - 'ṃ' => 'ṃ', - 'Ṅ' => 'Ṅ', - 'ṅ' => 'ṅ', - 'Ṇ' => 'Ṇ', - 'ṇ' => 'ṇ', - 'Ṉ' => 'Ṉ', - 'ṉ' => 'ṉ', - 'Ṋ' => 'Ṋ', - 'ṋ' => 'ṋ', - 'Ṍ' => 'Ṍ', - 'ṍ' => 'ṍ', - 'Ṏ' => 'Ṏ', - 'ṏ' => 'ṏ', - 'Ṑ' => 'Ṑ', - 'ṑ' => 'ṑ', - 'Ṓ' => 'Ṓ', - 'ṓ' => 'ṓ', - 'Ṕ' => 'Ṕ', - 'ṕ' => 'ṕ', - 'Ṗ' => 'Ṗ', - 'ṗ' => 'ṗ', - 'Ṙ' => 'Ṙ', - 'ṙ' => 'ṙ', - 'Ṛ' => 'Ṛ', - 'ṛ' => 'ṛ', - 'Ṝ' => 'Ṝ', - 'ṝ' => 'ṝ', - 'Ṟ' => 'Ṟ', - 'ṟ' => 'ṟ', - 'Ṡ' => 'Ṡ', - 'ṡ' => 'ṡ', - 'Ṣ' => 'Ṣ', - 'ṣ' => 'ṣ', - 'Ṥ' => 'Ṥ', - 'ṥ' => 'ṥ', - 'Ṧ' => 'Ṧ', - 'ṧ' => 'ṧ', - 'Ṩ' => 'Ṩ', - 'ṩ' => 'ṩ', - 'Ṫ' => 'Ṫ', - 'ṫ' => 'ṫ', - 'Ṭ' => 'Ṭ', - 'ṭ' => 'ṭ', - 'Ṯ' => 'Ṯ', - 'ṯ' => 'ṯ', - 'Ṱ' => 'Ṱ', - 'ṱ' => 'ṱ', - 'Ṳ' => 'Ṳ', - 'ṳ' => 'ṳ', - 'Ṵ' => 'Ṵ', - 'ṵ' => 'ṵ', - 'Ṷ' => 'Ṷ', - 'ṷ' => 'ṷ', - 'Ṹ' => 'Ṹ', - 'ṹ' => 'ṹ', - 'Ṻ' => 'Ṻ', - 'ṻ' => 'ṻ', - 'Ṽ' => 'Ṽ', - 'ṽ' => 'ṽ', - 'Ṿ' => 'Ṿ', - 'ṿ' => 'ṿ', - 'Ẁ' => 'Ẁ', - 'ẁ' => 'ẁ', - 'Ẃ' => 'Ẃ', - 'ẃ' => 'ẃ', - 'Ẅ' => 'Ẅ', - 'ẅ' => 'ẅ', - 'Ẇ' => 'Ẇ', - 'ẇ' => 'ẇ', - 'Ẉ' => 'Ẉ', - 'ẉ' => 'ẉ', - 'Ẋ' => 'Ẋ', - 'ẋ' => 'ẋ', - 'Ẍ' => 'Ẍ', - 'ẍ' => 'ẍ', - 'Ẏ' => 'Ẏ', - 'ẏ' => 'ẏ', - 'Ẑ' => 'Ẑ', - 'ẑ' => 'ẑ', - 'Ẓ' => 'Ẓ', - 'ẓ' => 'ẓ', - 'Ẕ' => 'Ẕ', - 'ẕ' => 'ẕ', - 'ẖ' => 'ẖ', - 'ẗ' => 'ẗ', - 'ẘ' => 'ẘ', - 'ẙ' => 'ẙ', - 'ẛ' => 'ẛ', - 'Ạ' => 'Ạ', - 'ạ' => 'ạ', - 'Ả' => 'Ả', - 'ả' => 'ả', - 'Ấ' => 'Ấ', - 'ấ' => 'ấ', - 'Ầ' => 'Ầ', - 'ầ' => 'ầ', - 'Ẩ' => 'Ẩ', - 'ẩ' => 'ẩ', - 'Ẫ' => 'Ẫ', - 'ẫ' => 'ẫ', - 'Ậ' => 'Ậ', - 'ậ' => 'ậ', - 'Ắ' => 'Ắ', - 'ắ' => 'ắ', - 'Ằ' => 'Ằ', - 'ằ' => 'ằ', - 'Ẳ' => 'Ẳ', - 'ẳ' => 'ẳ', - 'Ẵ' => 'Ẵ', - 'ẵ' => 'ẵ', - 'Ặ' => 'Ặ', - 'ặ' => 'ặ', - 'Ẹ' => 'Ẹ', - 'ẹ' => 'ẹ', - 'Ẻ' => 'Ẻ', - 'ẻ' => 'ẻ', - 'Ẽ' => 'Ẽ', - 'ẽ' => 'ẽ', - 'Ế' => 'Ế', - 'ế' => 'ế', - 'Ề' => 'Ề', - 'ề' => 'ề', - 'Ể' => 'Ể', - 'ể' => 'ể', - 'Ễ' => 'Ễ', - 'ễ' => 'ễ', - 'Ệ' => 'Ệ', - 'ệ' => 'ệ', - 'Ỉ' => 'Ỉ', - 'ỉ' => 'ỉ', - 'Ị' => 'Ị', - 'ị' => 'ị', - 'Ọ' => 'Ọ', - 'ọ' => 'ọ', - 'Ỏ' => 'Ỏ', - 'ỏ' => 'ỏ', - 'Ố' => 'Ố', - 'ố' => 'ố', - 'Ồ' => 'Ồ', - 'ồ' => 'ồ', - 'Ổ' => 'Ổ', - 'ổ' => 'ổ', - 'Ỗ' => 'Ỗ', - 'ỗ' => 'ỗ', - 'Ộ' => 'Ộ', - 'ộ' => 'ộ', - 'Ớ' => 'Ớ', - 'ớ' => 'ớ', - 'Ờ' => 'Ờ', - 'ờ' => 'ờ', - 'Ở' => 'Ở', - 'ở' => 'ở', - 'Ỡ' => 'Ỡ', - 'ỡ' => 'ỡ', - 'Ợ' => 'Ợ', - 'ợ' => 'ợ', - 'Ụ' => 'Ụ', - 'ụ' => 'ụ', - 'Ủ' => 'Ủ', - 'ủ' => 'ủ', - 'Ứ' => 'Ứ', - 'ứ' => 'ứ', - 'Ừ' => 'Ừ', - 'ừ' => 'ừ', - 'Ử' => 'Ử', - 'ử' => 'ử', - 'Ữ' => 'Ữ', - 'ữ' => 'ữ', - 'Ự' => 'Ự', - 'ự' => 'ự', - 'Ỳ' => 'Ỳ', - 'ỳ' => 'ỳ', - 'Ỵ' => 'Ỵ', - 'ỵ' => 'ỵ', - 'Ỷ' => 'Ỷ', - 'ỷ' => 'ỷ', - 'Ỹ' => 'Ỹ', - 'ỹ' => 'ỹ', - 'ἀ' => 'ἀ', - 'ἁ' => 'ἁ', - 'ἂ' => 'ἂ', - 'ἃ' => 'ἃ', - 'ἄ' => 'ἄ', - 'ἅ' => 'ἅ', - 'ἆ' => 'ἆ', - 'ἇ' => 'ἇ', - 'Ἀ' => 'Ἀ', - 'Ἁ' => 'Ἁ', - 'Ἂ' => 'Ἂ', - 'Ἃ' => 'Ἃ', - 'Ἄ' => 'Ἄ', - 'Ἅ' => 'Ἅ', - 'Ἆ' => 'Ἆ', - 'Ἇ' => 'Ἇ', - 'ἐ' => 'ἐ', - 'ἑ' => 'ἑ', - 'ἒ' => 'ἒ', - 'ἓ' => 'ἓ', - 'ἔ' => 'ἔ', - 'ἕ' => 'ἕ', - 'Ἐ' => 'Ἐ', - 'Ἑ' => 'Ἑ', - 'Ἒ' => 'Ἒ', - 'Ἓ' => 'Ἓ', - 'Ἔ' => 'Ἔ', - 'Ἕ' => 'Ἕ', - 'ἠ' => 'ἠ', - 'ἡ' => 'ἡ', - 'ἢ' => 'ἢ', - 'ἣ' => 'ἣ', - 'ἤ' => 'ἤ', - 'ἥ' => 'ἥ', - 'ἦ' => 'ἦ', - 'ἧ' => 'ἧ', - 'Ἠ' => 'Ἠ', - 'Ἡ' => 'Ἡ', - 'Ἢ' => 'Ἢ', - 'Ἣ' => 'Ἣ', - 'Ἤ' => 'Ἤ', - 'Ἥ' => 'Ἥ', - 'Ἦ' => 'Ἦ', - 'Ἧ' => 'Ἧ', - 'ἰ' => 'ἰ', - 'ἱ' => 'ἱ', - 'ἲ' => 'ἲ', - 'ἳ' => 'ἳ', - 'ἴ' => 'ἴ', - 'ἵ' => 'ἵ', - 'ἶ' => 'ἶ', - 'ἷ' => 'ἷ', - 'Ἰ' => 'Ἰ', - 'Ἱ' => 'Ἱ', - 'Ἲ' => 'Ἲ', - 'Ἳ' => 'Ἳ', - 'Ἴ' => 'Ἴ', - 'Ἵ' => 'Ἵ', - 'Ἶ' => 'Ἶ', - 'Ἷ' => 'Ἷ', - 'ὀ' => 'ὀ', - 'ὁ' => 'ὁ', - 'ὂ' => 'ὂ', - 'ὃ' => 'ὃ', - 'ὄ' => 'ὄ', - 'ὅ' => 'ὅ', - 'Ὀ' => 'Ὀ', - 'Ὁ' => 'Ὁ', - 'Ὂ' => 'Ὂ', - 'Ὃ' => 'Ὃ', - 'Ὄ' => 'Ὄ', - 'Ὅ' => 'Ὅ', - 'ὐ' => 'ὐ', - 'ὑ' => 'ὑ', - 'ὒ' => 'ὒ', - 'ὓ' => 'ὓ', - 'ὔ' => 'ὔ', - 'ὕ' => 'ὕ', - 'ὖ' => 'ὖ', - 'ὗ' => 'ὗ', - 'Ὑ' => 'Ὑ', - 'Ὓ' => 'Ὓ', - 'Ὕ' => 'Ὕ', - 'Ὗ' => 'Ὗ', - 'ὠ' => 'ὠ', - 'ὡ' => 'ὡ', - 'ὢ' => 'ὢ', - 'ὣ' => 'ὣ', - 'ὤ' => 'ὤ', - 'ὥ' => 'ὥ', - 'ὦ' => 'ὦ', - 'ὧ' => 'ὧ', - 'Ὠ' => 'Ὠ', - 'Ὡ' => 'Ὡ', - 'Ὢ' => 'Ὢ', - 'Ὣ' => 'Ὣ', - 'Ὤ' => 'Ὤ', - 'Ὥ' => 'Ὥ', - 'Ὦ' => 'Ὦ', - 'Ὧ' => 'Ὧ', - 'ὰ' => 'ὰ', - 'ά' => 'ά', - 'ὲ' => 'ὲ', - 'έ' => 'έ', - 'ὴ' => 'ὴ', - 'ή' => 'ή', - 'ὶ' => 'ὶ', - 'ί' => 'ί', - 'ὸ' => 'ὸ', - 'ό' => 'ό', - 'ὺ' => 'ὺ', - 'ύ' => 'ύ', - 'ὼ' => 'ὼ', - 'ώ' => 'ώ', - 'ᾀ' => 'ᾀ', - 'ᾁ' => 'ᾁ', - 'ᾂ' => 'ᾂ', - 'ᾃ' => 'ᾃ', - 'ᾄ' => 'ᾄ', - 'ᾅ' => 'ᾅ', - 'ᾆ' => 'ᾆ', - 'ᾇ' => 'ᾇ', - 'ᾈ' => 'ᾈ', - 'ᾉ' => 'ᾉ', - 'ᾊ' => 'ᾊ', - 'ᾋ' => 'ᾋ', - 'ᾌ' => 'ᾌ', - 'ᾍ' => 'ᾍ', - 'ᾎ' => 'ᾎ', - 'ᾏ' => 'ᾏ', - 'ᾐ' => 'ᾐ', - 'ᾑ' => 'ᾑ', - 'ᾒ' => 'ᾒ', - 'ᾓ' => 'ᾓ', - 'ᾔ' => 'ᾔ', - 'ᾕ' => 'ᾕ', - 'ᾖ' => 'ᾖ', - 'ᾗ' => 'ᾗ', - 'ᾘ' => 'ᾘ', - 'ᾙ' => 'ᾙ', - 'ᾚ' => 'ᾚ', - 'ᾛ' => 'ᾛ', - 'ᾜ' => 'ᾜ', - 'ᾝ' => 'ᾝ', - 'ᾞ' => 'ᾞ', - 'ᾟ' => 'ᾟ', - 'ᾠ' => 'ᾠ', - 'ᾡ' => 'ᾡ', - 'ᾢ' => 'ᾢ', - 'ᾣ' => 'ᾣ', - 'ᾤ' => 'ᾤ', - 'ᾥ' => 'ᾥ', - 'ᾦ' => 'ᾦ', - 'ᾧ' => 'ᾧ', - 'ᾨ' => 'ᾨ', - 'ᾩ' => 'ᾩ', - 'ᾪ' => 'ᾪ', - 'ᾫ' => 'ᾫ', - 'ᾬ' => 'ᾬ', - 'ᾭ' => 'ᾭ', - 'ᾮ' => 'ᾮ', - 'ᾯ' => 'ᾯ', - 'ᾰ' => 'ᾰ', - 'ᾱ' => 'ᾱ', - 'ᾲ' => 'ᾲ', - 'ᾳ' => 'ᾳ', - 'ᾴ' => 'ᾴ', - 'ᾶ' => 'ᾶ', - 'ᾷ' => 'ᾷ', - 'Ᾰ' => 'Ᾰ', - 'Ᾱ' => 'Ᾱ', - 'Ὰ' => 'Ὰ', - 'Ά' => 'Ά', - 'ᾼ' => 'ᾼ', - 'ι' => 'ι', - '῁' => '῁', - 'ῂ' => 'ῂ', - 'ῃ' => 'ῃ', - 'ῄ' => 'ῄ', - 'ῆ' => 'ῆ', - 'ῇ' => 'ῇ', - 'Ὲ' => 'Ὲ', - 'Έ' => 'Έ', - 'Ὴ' => 'Ὴ', - 'Ή' => 'Ή', - 'ῌ' => 'ῌ', - '῍' => '῍', - '῎' => '῎', - '῏' => '῏', - 'ῐ' => 'ῐ', - 'ῑ' => 'ῑ', - 'ῒ' => 'ῒ', - 'ΐ' => 'ΐ', - 'ῖ' => 'ῖ', - 'ῗ' => 'ῗ', - 'Ῐ' => 'Ῐ', - 'Ῑ' => 'Ῑ', - 'Ὶ' => 'Ὶ', - 'Ί' => 'Ί', - '῝' => '῝', - '῞' => '῞', - '῟' => '῟', - 'ῠ' => 'ῠ', - 'ῡ' => 'ῡ', - 'ῢ' => 'ῢ', - 'ΰ' => 'ΰ', - 'ῤ' => 'ῤ', - 'ῥ' => 'ῥ', - 'ῦ' => 'ῦ', - 'ῧ' => 'ῧ', - 'Ῠ' => 'Ῠ', - 'Ῡ' => 'Ῡ', - 'Ὺ' => 'Ὺ', - 'Ύ' => 'Ύ', - 'Ῥ' => 'Ῥ', - '῭' => '῭', - '΅' => '΅', - '`' => '`', - 'ῲ' => 'ῲ', - 'ῳ' => 'ῳ', - 'ῴ' => 'ῴ', - 'ῶ' => 'ῶ', - 'ῷ' => 'ῷ', - 'Ὸ' => 'Ὸ', - 'Ό' => 'Ό', - 'Ὼ' => 'Ὼ', - 'Ώ' => 'Ώ', - 'ῼ' => 'ῼ', - '´' => '´', - ' ' => ' ', - ' ' => ' ', - 'Ω' => 'Ω', - 'K' => 'K', - 'Å' => 'Å', - '↚' => '↚', - '↛' => '↛', - '↮' => '↮', - '⇍' => '⇍', - '⇎' => '⇎', - '⇏' => '⇏', - '∄' => '∄', - '∉' => '∉', - '∌' => '∌', - '∤' => '∤', - '∦' => '∦', - '≁' => '≁', - '≄' => '≄', - '≇' => '≇', - '≉' => '≉', - '≠' => '≠', - '≢' => '≢', - '≭' => '≭', - '≮' => '≮', - '≯' => '≯', - '≰' => '≰', - '≱' => '≱', - '≴' => '≴', - '≵' => '≵', - '≸' => '≸', - '≹' => '≹', - '⊀' => '⊀', - '⊁' => '⊁', - '⊄' => '⊄', - '⊅' => '⊅', - '⊈' => '⊈', - '⊉' => '⊉', - '⊬' => '⊬', - '⊭' => '⊭', - '⊮' => '⊮', - '⊯' => '⊯', - '⋠' => '⋠', - '⋡' => '⋡', - '⋢' => '⋢', - '⋣' => '⋣', - '⋪' => '⋪', - '⋫' => '⋫', - '⋬' => '⋬', - '⋭' => '⋭', - '〈' => '〈', - '〉' => '〉', - '⫝̸' => '⫝̸', - 'が' => 'が', - 'ぎ' => 'ぎ', - 'ぐ' => 'ぐ', - 'げ' => 'げ', - 'ご' => 'ご', - 'ざ' => 'ざ', - 'じ' => 'じ', - 'ず' => 'ず', - 'ぜ' => 'ぜ', - 'ぞ' => 'ぞ', - 'だ' => 'だ', - 'ぢ' => 'ぢ', - 'づ' => 'づ', - 'で' => 'で', - 'ど' => 'ど', - 'ば' => 'ば', - 'ぱ' => 'ぱ', - 'び' => 'び', - 'ぴ' => 'ぴ', - 'ぶ' => 'ぶ', - 'ぷ' => 'ぷ', - 'べ' => 'べ', - 'ぺ' => 'ぺ', - 'ぼ' => 'ぼ', - 'ぽ' => 'ぽ', - 'ゔ' => 'ゔ', - 'ゞ' => 'ゞ', - 'ガ' => 'ガ', - 'ギ' => 'ギ', - 'グ' => 'グ', - 'ゲ' => 'ゲ', - 'ゴ' => 'ゴ', - 'ザ' => 'ザ', - 'ジ' => 'ジ', - 'ズ' => 'ズ', - 'ゼ' => 'ゼ', - 'ゾ' => 'ゾ', - 'ダ' => 'ダ', - 'ヂ' => 'ヂ', - 'ヅ' => 'ヅ', - 'デ' => 'デ', - 'ド' => 'ド', - 'バ' => 'バ', - 'パ' => 'パ', - 'ビ' => 'ビ', - 'ピ' => 'ピ', - 'ブ' => 'ブ', - 'プ' => 'プ', - 'ベ' => 'ベ', - 'ペ' => 'ペ', - 'ボ' => 'ボ', - 'ポ' => 'ポ', - 'ヴ' => 'ヴ', - 'ヷ' => 'ヷ', - 'ヸ' => 'ヸ', - 'ヹ' => 'ヹ', - 'ヺ' => 'ヺ', - 'ヾ' => 'ヾ', - '豈' => '豈', - '更' => '更', - '車' => '車', - '賈' => '賈', - '滑' => '滑', - '串' => '串', - '句' => '句', - '龜' => '龜', - '龜' => '龜', - '契' => '契', - '金' => '金', - '喇' => '喇', - '奈' => '奈', - '懶' => '懶', - '癩' => '癩', - '羅' => '羅', - '蘿' => '蘿', - '螺' => '螺', - '裸' => '裸', - '邏' => '邏', - '樂' => '樂', - '洛' => '洛', - '烙' => '烙', - '珞' => '珞', - '落' => '落', - '酪' => '酪', - '駱' => '駱', - '亂' => '亂', - '卵' => '卵', - '欄' => '欄', - '爛' => '爛', - '蘭' => '蘭', - '鸞' => '鸞', - '嵐' => '嵐', - '濫' => '濫', - '藍' => '藍', - '襤' => '襤', - '拉' => '拉', - '臘' => '臘', - '蠟' => '蠟', - '廊' => '廊', - '朗' => '朗', - '浪' => '浪', - '狼' => '狼', - '郎' => '郎', - '來' => '來', - '冷' => '冷', - '勞' => '勞', - '擄' => '擄', - '櫓' => '櫓', - '爐' => '爐', - '盧' => '盧', - '老' => '老', - '蘆' => '蘆', - '虜' => '虜', - '路' => '路', - '露' => '露', - '魯' => '魯', - '鷺' => '鷺', - '碌' => '碌', - '祿' => '祿', - '綠' => '綠', - '菉' => '菉', - '錄' => '錄', - '鹿' => '鹿', - '論' => '論', - '壟' => '壟', - '弄' => '弄', - '籠' => '籠', - '聾' => '聾', - '牢' => '牢', - '磊' => '磊', - '賂' => '賂', - '雷' => '雷', - '壘' => '壘', - '屢' => '屢', - '樓' => '樓', - '淚' => '淚', - '漏' => '漏', - '累' => '累', - '縷' => '縷', - '陋' => '陋', - '勒' => '勒', - '肋' => '肋', - '凜' => '凜', - '凌' => '凌', - '稜' => '稜', - '綾' => '綾', - '菱' => '菱', - '陵' => '陵', - '讀' => '讀', - '拏' => '拏', - '樂' => '樂', - '諾' => '諾', - '丹' => '丹', - '寧' => '寧', - '怒' => '怒', - '率' => '率', - '異' => '異', - '北' => '北', - '磻' => '磻', - '便' => '便', - '復' => '復', - '不' => '不', - '泌' => '泌', - '數' => '數', - '索' => '索', - '參' => '參', - '塞' => '塞', - '省' => '省', - '葉' => '葉', - '說' => '說', - '殺' => '殺', - '辰' => '辰', - '沈' => '沈', - '拾' => '拾', - '若' => '若', - '掠' => '掠', - '略' => '略', - '亮' => '亮', - '兩' => '兩', - '凉' => '凉', - '梁' => '梁', - '糧' => '糧', - '良' => '良', - '諒' => '諒', - '量' => '量', - '勵' => '勵', - '呂' => '呂', - '女' => '女', - '廬' => '廬', - '旅' => '旅', - '濾' => '濾', - '礪' => '礪', - '閭' => '閭', - '驪' => '驪', - '麗' => '麗', - '黎' => '黎', - '力' => '力', - '曆' => '曆', - '歷' => '歷', - '轢' => '轢', - '年' => '年', - '憐' => '憐', - '戀' => '戀', - '撚' => '撚', - '漣' => '漣', - '煉' => '煉', - '璉' => '璉', - '秊' => '秊', - '練' => '練', - '聯' => '聯', - '輦' => '輦', - '蓮' => '蓮', - '連' => '連', - '鍊' => '鍊', - '列' => '列', - '劣' => '劣', - '咽' => '咽', - '烈' => '烈', - '裂' => '裂', - '說' => '說', - '廉' => '廉', - '念' => '念', - '捻' => '捻', - '殮' => '殮', - '簾' => '簾', - '獵' => '獵', - '令' => '令', - '囹' => '囹', - '寧' => '寧', - '嶺' => '嶺', - '怜' => '怜', - '玲' => '玲', - '瑩' => '瑩', - '羚' => '羚', - '聆' => '聆', - '鈴' => '鈴', - '零' => '零', - '靈' => '靈', - '領' => '領', - '例' => '例', - '禮' => '禮', - '醴' => '醴', - '隸' => '隸', - '惡' => '惡', - '了' => '了', - '僚' => '僚', - '寮' => '寮', - '尿' => '尿', - '料' => '料', - '樂' => '樂', - '燎' => '燎', - '療' => '療', - '蓼' => '蓼', - '遼' => '遼', - '龍' => '龍', - '暈' => '暈', - '阮' => '阮', - '劉' => '劉', - '杻' => '杻', - '柳' => '柳', - '流' => '流', - '溜' => '溜', - '琉' => '琉', - '留' => '留', - '硫' => '硫', - '紐' => '紐', - '類' => '類', - '六' => '六', - '戮' => '戮', - '陸' => '陸', - '倫' => '倫', - '崙' => '崙', - '淪' => '淪', - '輪' => '輪', - '律' => '律', - '慄' => '慄', - '栗' => '栗', - '率' => '率', - '隆' => '隆', - '利' => '利', - '吏' => '吏', - '履' => '履', - '易' => '易', - '李' => '李', - '梨' => '梨', - '泥' => '泥', - '理' => '理', - '痢' => '痢', - '罹' => '罹', - '裏' => '裏', - '裡' => '裡', - '里' => '里', - '離' => '離', - '匿' => '匿', - '溺' => '溺', - '吝' => '吝', - '燐' => '燐', - '璘' => '璘', - '藺' => '藺', - '隣' => '隣', - '鱗' => '鱗', - '麟' => '麟', - '林' => '林', - '淋' => '淋', - '臨' => '臨', - '立' => '立', - '笠' => '笠', - '粒' => '粒', - '狀' => '狀', - '炙' => '炙', - '識' => '識', - '什' => '什', - '茶' => '茶', - '刺' => '刺', - '切' => '切', - '度' => '度', - '拓' => '拓', - '糖' => '糖', - '宅' => '宅', - '洞' => '洞', - '暴' => '暴', - '輻' => '輻', - '行' => '行', - '降' => '降', - '見' => '見', - '廓' => '廓', - '兀' => '兀', - '嗀' => '嗀', - '塚' => '塚', - '晴' => '晴', - '凞' => '凞', - '猪' => '猪', - '益' => '益', - '礼' => '礼', - '神' => '神', - '祥' => '祥', - '福' => '福', - '靖' => '靖', - '精' => '精', - '羽' => '羽', - '蘒' => '蘒', - '諸' => '諸', - '逸' => '逸', - '都' => '都', - '飯' => '飯', - '飼' => '飼', - '館' => '館', - '鶴' => '鶴', - '郞' => '郞', - '隷' => '隷', - '侮' => '侮', - '僧' => '僧', - '免' => '免', - '勉' => '勉', - '勤' => '勤', - '卑' => '卑', - '喝' => '喝', - '嘆' => '嘆', - '器' => '器', - '塀' => '塀', - '墨' => '墨', - '層' => '層', - '屮' => '屮', - '悔' => '悔', - '慨' => '慨', - '憎' => '憎', - '懲' => '懲', - '敏' => '敏', - '既' => '既', - '暑' => '暑', - '梅' => '梅', - '海' => '海', - '渚' => '渚', - '漢' => '漢', - '煮' => '煮', - '爫' => '爫', - '琢' => '琢', - '碑' => '碑', - '社' => '社', - '祉' => '祉', - '祈' => '祈', - '祐' => '祐', - '祖' => '祖', - '祝' => '祝', - '禍' => '禍', - '禎' => '禎', - '穀' => '穀', - '突' => '突', - '節' => '節', - '練' => '練', - '縉' => '縉', - '繁' => '繁', - '署' => '署', - '者' => '者', - '臭' => '臭', - '艹' => '艹', - '艹' => '艹', - '著' => '著', - '褐' => '褐', - '視' => '視', - '謁' => '謁', - '謹' => '謹', - '賓' => '賓', - '贈' => '贈', - '辶' => '辶', - '逸' => '逸', - '難' => '難', - '響' => '響', - '頻' => '頻', - '恵' => '恵', - '𤋮' => '𤋮', - '舘' => '舘', - '並' => '並', - '况' => '况', - '全' => '全', - '侀' => '侀', - '充' => '充', - '冀' => '冀', - '勇' => '勇', - '勺' => '勺', - '喝' => '喝', - '啕' => '啕', - '喙' => '喙', - '嗢' => '嗢', - '塚' => '塚', - '墳' => '墳', - '奄' => '奄', - '奔' => '奔', - '婢' => '婢', - '嬨' => '嬨', - '廒' => '廒', - '廙' => '廙', - '彩' => '彩', - '徭' => '徭', - '惘' => '惘', - '慎' => '慎', - '愈' => '愈', - '憎' => '憎', - '慠' => '慠', - '懲' => '懲', - '戴' => '戴', - '揄' => '揄', - '搜' => '搜', - '摒' => '摒', - '敖' => '敖', - '晴' => '晴', - '朗' => '朗', - '望' => '望', - '杖' => '杖', - '歹' => '歹', - '殺' => '殺', - '流' => '流', - '滛' => '滛', - '滋' => '滋', - '漢' => '漢', - '瀞' => '瀞', - '煮' => '煮', - '瞧' => '瞧', - '爵' => '爵', - '犯' => '犯', - '猪' => '猪', - '瑱' => '瑱', - '甆' => '甆', - '画' => '画', - '瘝' => '瘝', - '瘟' => '瘟', - '益' => '益', - '盛' => '盛', - '直' => '直', - '睊' => '睊', - '着' => '着', - '磌' => '磌', - '窱' => '窱', - '節' => '節', - '类' => '类', - '絛' => '絛', - '練' => '練', - '缾' => '缾', - '者' => '者', - '荒' => '荒', - '華' => '華', - '蝹' => '蝹', - '襁' => '襁', - '覆' => '覆', - '視' => '視', - '調' => '調', - '諸' => '諸', - '請' => '請', - '謁' => '謁', - '諾' => '諾', - '諭' => '諭', - '謹' => '謹', - '變' => '變', - '贈' => '贈', - '輸' => '輸', - '遲' => '遲', - '醙' => '醙', - '鉶' => '鉶', - '陼' => '陼', - '難' => '難', - '靖' => '靖', - '韛' => '韛', - '響' => '響', - '頋' => '頋', - '頻' => '頻', - '鬒' => '鬒', - '龜' => '龜', - '𢡊' => '𢡊', - '𢡄' => '𢡄', - '𣏕' => '𣏕', - '㮝' => '㮝', - '䀘' => '䀘', - '䀹' => '䀹', - '𥉉' => '𥉉', - '𥳐' => '𥳐', - '𧻓' => '𧻓', - '齃' => '齃', - '龎' => '龎', - 'יִ' => 'יִ', - 'ײַ' => 'ײַ', - 'שׁ' => 'שׁ', - 'שׂ' => 'שׂ', - 'שּׁ' => 'שּׁ', - 'שּׂ' => 'שּׂ', - 'אַ' => 'אַ', - 'אָ' => 'אָ', - 'אּ' => 'אּ', - 'בּ' => 'בּ', - 'גּ' => 'גּ', - 'דּ' => 'דּ', - 'הּ' => 'הּ', - 'וּ' => 'וּ', - 'זּ' => 'זּ', - 'טּ' => 'טּ', - 'יּ' => 'יּ', - 'ךּ' => 'ךּ', - 'כּ' => 'כּ', - 'לּ' => 'לּ', - 'מּ' => 'מּ', - 'נּ' => 'נּ', - 'סּ' => 'סּ', - 'ףּ' => 'ףּ', - 'פּ' => 'פּ', - 'צּ' => 'צּ', - 'קּ' => 'קּ', - 'רּ' => 'רּ', - 'שּ' => 'שּ', - 'תּ' => 'תּ', - 'וֹ' => 'וֹ', - 'בֿ' => 'בֿ', - 'כֿ' => 'כֿ', - 'פֿ' => 'פֿ', - '𑂚' => '𑂚', - '𑂜' => '𑂜', - '𑂫' => '𑂫', - '𑄮' => '𑄮', - '𑄯' => '𑄯', - '𑍋' => '𑍋', - '𑍌' => '𑍌', - '𑒻' => '𑒻', - '𑒼' => '𑒼', - '𑒾' => '𑒾', - '𑖺' => '𑖺', - '𑖻' => '𑖻', - '𑤸' => '𑤸', - '𝅗𝅥' => '𝅗𝅥', - '𝅘𝅥' => '𝅘𝅥', - '𝅘𝅥𝅮' => '𝅘𝅥𝅮', - '𝅘𝅥𝅯' => '𝅘𝅥𝅯', - '𝅘𝅥𝅰' => '𝅘𝅥𝅰', - '𝅘𝅥𝅱' => '𝅘𝅥𝅱', - '𝅘𝅥𝅲' => '𝅘𝅥𝅲', - '𝆹𝅥' => '𝆹𝅥', - '𝆺𝅥' => '𝆺𝅥', - '𝆹𝅥𝅮' => '𝆹𝅥𝅮', - '𝆺𝅥𝅮' => '𝆺𝅥𝅮', - '𝆹𝅥𝅯' => '𝆹𝅥𝅯', - '𝆺𝅥𝅯' => '𝆺𝅥𝅯', - '丽' => '丽', - '丸' => '丸', - '乁' => '乁', - '𠄢' => '𠄢', - '你' => '你', - '侮' => '侮', - '侻' => '侻', - '倂' => '倂', - '偺' => '偺', - '備' => '備', - '僧' => '僧', - '像' => '像', - '㒞' => '㒞', - '𠘺' => '𠘺', - '免' => '免', - '兔' => '兔', - '兤' => '兤', - '具' => '具', - '𠔜' => '𠔜', - '㒹' => '㒹', - '內' => '內', - '再' => '再', - '𠕋' => '𠕋', - '冗' => '冗', - '冤' => '冤', - '仌' => '仌', - '冬' => '冬', - '况' => '况', - '𩇟' => '𩇟', - '凵' => '凵', - '刃' => '刃', - '㓟' => '㓟', - '刻' => '刻', - '剆' => '剆', - '割' => '割', - '剷' => '剷', - '㔕' => '㔕', - '勇' => '勇', - '勉' => '勉', - '勤' => '勤', - '勺' => '勺', - '包' => '包', - '匆' => '匆', - '北' => '北', - '卉' => '卉', - '卑' => '卑', - '博' => '博', - '即' => '即', - '卽' => '卽', - '卿' => '卿', - '卿' => '卿', - '卿' => '卿', - '𠨬' => '𠨬', - '灰' => '灰', - '及' => '及', - '叟' => '叟', - '𠭣' => '𠭣', - '叫' => '叫', - '叱' => '叱', - '吆' => '吆', - '咞' => '咞', - '吸' => '吸', - '呈' => '呈', - '周' => '周', - '咢' => '咢', - '哶' => '哶', - '唐' => '唐', - '啓' => '啓', - '啣' => '啣', - '善' => '善', - '善' => '善', - '喙' => '喙', - '喫' => '喫', - '喳' => '喳', - '嗂' => '嗂', - '圖' => '圖', - '嘆' => '嘆', - '圗' => '圗', - '噑' => '噑', - '噴' => '噴', - '切' => '切', - '壮' => '壮', - '城' => '城', - '埴' => '埴', - '堍' => '堍', - '型' => '型', - '堲' => '堲', - '報' => '報', - '墬' => '墬', - '𡓤' => '𡓤', - '売' => '売', - '壷' => '壷', - '夆' => '夆', - '多' => '多', - '夢' => '夢', - '奢' => '奢', - '𡚨' => '𡚨', - '𡛪' => '𡛪', - '姬' => '姬', - '娛' => '娛', - '娧' => '娧', - '姘' => '姘', - '婦' => '婦', - '㛮' => '㛮', - '㛼' => '㛼', - '嬈' => '嬈', - '嬾' => '嬾', - '嬾' => '嬾', - '𡧈' => '𡧈', - '寃' => '寃', - '寘' => '寘', - '寧' => '寧', - '寳' => '寳', - '𡬘' => '𡬘', - '寿' => '寿', - '将' => '将', - '当' => '当', - '尢' => '尢', - '㞁' => '㞁', - '屠' => '屠', - '屮' => '屮', - '峀' => '峀', - '岍' => '岍', - '𡷤' => '𡷤', - '嵃' => '嵃', - '𡷦' => '𡷦', - '嵮' => '嵮', - '嵫' => '嵫', - '嵼' => '嵼', - '巡' => '巡', - '巢' => '巢', - '㠯' => '㠯', - '巽' => '巽', - '帨' => '帨', - '帽' => '帽', - '幩' => '幩', - '㡢' => '㡢', - '𢆃' => '𢆃', - '㡼' => '㡼', - '庰' => '庰', - '庳' => '庳', - '庶' => '庶', - '廊' => '廊', - '𪎒' => '𪎒', - '廾' => '廾', - '𢌱' => '𢌱', - '𢌱' => '𢌱', - '舁' => '舁', - '弢' => '弢', - '弢' => '弢', - '㣇' => '㣇', - '𣊸' => '𣊸', - '𦇚' => '𦇚', - '形' => '形', - '彫' => '彫', - '㣣' => '㣣', - '徚' => '徚', - '忍' => '忍', - '志' => '志', - '忹' => '忹', - '悁' => '悁', - '㤺' => '㤺', - '㤜' => '㤜', - '悔' => '悔', - '𢛔' => '𢛔', - '惇' => '惇', - '慈' => '慈', - '慌' => '慌', - '慎' => '慎', - '慌' => '慌', - '慺' => '慺', - '憎' => '憎', - '憲' => '憲', - '憤' => '憤', - '憯' => '憯', - '懞' => '懞', - '懲' => '懲', - '懶' => '懶', - '成' => '成', - '戛' => '戛', - '扝' => '扝', - '抱' => '抱', - '拔' => '拔', - '捐' => '捐', - '𢬌' => '𢬌', - '挽' => '挽', - '拼' => '拼', - '捨' => '捨', - '掃' => '掃', - '揤' => '揤', - '𢯱' => '𢯱', - '搢' => '搢', - '揅' => '揅', - '掩' => '掩', - '㨮' => '㨮', - '摩' => '摩', - '摾' => '摾', - '撝' => '撝', - '摷' => '摷', - '㩬' => '㩬', - '敏' => '敏', - '敬' => '敬', - '𣀊' => '𣀊', - '旣' => '旣', - '書' => '書', - '晉' => '晉', - '㬙' => '㬙', - '暑' => '暑', - '㬈' => '㬈', - '㫤' => '㫤', - '冒' => '冒', - '冕' => '冕', - '最' => '最', - '暜' => '暜', - '肭' => '肭', - '䏙' => '䏙', - '朗' => '朗', - '望' => '望', - '朡' => '朡', - '杞' => '杞', - '杓' => '杓', - '𣏃' => '𣏃', - '㭉' => '㭉', - '柺' => '柺', - '枅' => '枅', - '桒' => '桒', - '梅' => '梅', - '𣑭' => '𣑭', - '梎' => '梎', - '栟' => '栟', - '椔' => '椔', - '㮝' => '㮝', - '楂' => '楂', - '榣' => '榣', - '槪' => '槪', - '檨' => '檨', - '𣚣' => '𣚣', - '櫛' => '櫛', - '㰘' => '㰘', - '次' => '次', - '𣢧' => '𣢧', - '歔' => '歔', - '㱎' => '㱎', - '歲' => '歲', - '殟' => '殟', - '殺' => '殺', - '殻' => '殻', - '𣪍' => '𣪍', - '𡴋' => '𡴋', - '𣫺' => '𣫺', - '汎' => '汎', - '𣲼' => '𣲼', - '沿' => '沿', - '泍' => '泍', - '汧' => '汧', - '洖' => '洖', - '派' => '派', - '海' => '海', - '流' => '流', - '浩' => '浩', - '浸' => '浸', - '涅' => '涅', - '𣴞' => '𣴞', - '洴' => '洴', - '港' => '港', - '湮' => '湮', - '㴳' => '㴳', - '滋' => '滋', - '滇' => '滇', - '𣻑' => '𣻑', - '淹' => '淹', - '潮' => '潮', - '𣽞' => '𣽞', - '𣾎' => '𣾎', - '濆' => '濆', - '瀹' => '瀹', - '瀞' => '瀞', - '瀛' => '瀛', - '㶖' => '㶖', - '灊' => '灊', - '災' => '災', - '灷' => '灷', - '炭' => '炭', - '𠔥' => '𠔥', - '煅' => '煅', - '𤉣' => '𤉣', - '熜' => '熜', - '𤎫' => '𤎫', - '爨' => '爨', - '爵' => '爵', - '牐' => '牐', - '𤘈' => '𤘈', - '犀' => '犀', - '犕' => '犕', - '𤜵' => '𤜵', - '𤠔' => '𤠔', - '獺' => '獺', - '王' => '王', - '㺬' => '㺬', - '玥' => '玥', - '㺸' => '㺸', - '㺸' => '㺸', - '瑇' => '瑇', - '瑜' => '瑜', - '瑱' => '瑱', - '璅' => '璅', - '瓊' => '瓊', - '㼛' => '㼛', - '甤' => '甤', - '𤰶' => '𤰶', - '甾' => '甾', - '𤲒' => '𤲒', - '異' => '異', - '𢆟' => '𢆟', - '瘐' => '瘐', - '𤾡' => '𤾡', - '𤾸' => '𤾸', - '𥁄' => '𥁄', - '㿼' => '㿼', - '䀈' => '䀈', - '直' => '直', - '𥃳' => '𥃳', - '𥃲' => '𥃲', - '𥄙' => '𥄙', - '𥄳' => '𥄳', - '眞' => '眞', - '真' => '真', - '真' => '真', - '睊' => '睊', - '䀹' => '䀹', - '瞋' => '瞋', - '䁆' => '䁆', - '䂖' => '䂖', - '𥐝' => '𥐝', - '硎' => '硎', - '碌' => '碌', - '磌' => '磌', - '䃣' => '䃣', - '𥘦' => '𥘦', - '祖' => '祖', - '𥚚' => '𥚚', - '𥛅' => '𥛅', - '福' => '福', - '秫' => '秫', - '䄯' => '䄯', - '穀' => '穀', - '穊' => '穊', - '穏' => '穏', - '𥥼' => '𥥼', - '𥪧' => '𥪧', - '𥪧' => '𥪧', - '竮' => '竮', - '䈂' => '䈂', - '𥮫' => '𥮫', - '篆' => '篆', - '築' => '築', - '䈧' => '䈧', - '𥲀' => '𥲀', - '糒' => '糒', - '䊠' => '䊠', - '糨' => '糨', - '糣' => '糣', - '紀' => '紀', - '𥾆' => '𥾆', - '絣' => '絣', - '䌁' => '䌁', - '緇' => '緇', - '縂' => '縂', - '繅' => '繅', - '䌴' => '䌴', - '𦈨' => '𦈨', - '𦉇' => '𦉇', - '䍙' => '䍙', - '𦋙' => '𦋙', - '罺' => '罺', - '𦌾' => '𦌾', - '羕' => '羕', - '翺' => '翺', - '者' => '者', - '𦓚' => '𦓚', - '𦔣' => '𦔣', - '聠' => '聠', - '𦖨' => '𦖨', - '聰' => '聰', - '𣍟' => '𣍟', - '䏕' => '䏕', - '育' => '育', - '脃' => '脃', - '䐋' => '䐋', - '脾' => '脾', - '媵' => '媵', - '𦞧' => '𦞧', - '𦞵' => '𦞵', - '𣎓' => '𣎓', - '𣎜' => '𣎜', - '舁' => '舁', - '舄' => '舄', - '辞' => '辞', - '䑫' => '䑫', - '芑' => '芑', - '芋' => '芋', - '芝' => '芝', - '劳' => '劳', - '花' => '花', - '芳' => '芳', - '芽' => '芽', - '苦' => '苦', - '𦬼' => '𦬼', - '若' => '若', - '茝' => '茝', - '荣' => '荣', - '莭' => '莭', - '茣' => '茣', - '莽' => '莽', - '菧' => '菧', - '著' => '著', - '荓' => '荓', - '菊' => '菊', - '菌' => '菌', - '菜' => '菜', - '𦰶' => '𦰶', - '𦵫' => '𦵫', - '𦳕' => '𦳕', - '䔫' => '䔫', - '蓱' => '蓱', - '蓳' => '蓳', - '蔖' => '蔖', - '𧏊' => '𧏊', - '蕤' => '蕤', - '𦼬' => '𦼬', - '䕝' => '䕝', - '䕡' => '䕡', - '𦾱' => '𦾱', - '𧃒' => '𧃒', - '䕫' => '䕫', - '虐' => '虐', - '虜' => '虜', - '虧' => '虧', - '虩' => '虩', - '蚩' => '蚩', - '蚈' => '蚈', - '蜎' => '蜎', - '蛢' => '蛢', - '蝹' => '蝹', - '蜨' => '蜨', - '蝫' => '蝫', - '螆' => '螆', - '䗗' => '䗗', - '蟡' => '蟡', - '蠁' => '蠁', - '䗹' => '䗹', - '衠' => '衠', - '衣' => '衣', - '𧙧' => '𧙧', - '裗' => '裗', - '裞' => '裞', - '䘵' => '䘵', - '裺' => '裺', - '㒻' => '㒻', - '𧢮' => '𧢮', - '𧥦' => '𧥦', - '䚾' => '䚾', - '䛇' => '䛇', - '誠' => '誠', - '諭' => '諭', - '變' => '變', - '豕' => '豕', - '𧲨' => '𧲨', - '貫' => '貫', - '賁' => '賁', - '贛' => '贛', - '起' => '起', - '𧼯' => '𧼯', - '𠠄' => '𠠄', - '跋' => '跋', - '趼' => '趼', - '跰' => '跰', - '𠣞' => '𠣞', - '軔' => '軔', - '輸' => '輸', - '𨗒' => '𨗒', - '𨗭' => '𨗭', - '邔' => '邔', - '郱' => '郱', - '鄑' => '鄑', - '𨜮' => '𨜮', - '鄛' => '鄛', - '鈸' => '鈸', - '鋗' => '鋗', - '鋘' => '鋘', - '鉼' => '鉼', - '鏹' => '鏹', - '鐕' => '鐕', - '𨯺' => '𨯺', - '開' => '開', - '䦕' => '䦕', - '閷' => '閷', - '𨵷' => '𨵷', - '䧦' => '䧦', - '雃' => '雃', - '嶲' => '嶲', - '霣' => '霣', - '𩅅' => '𩅅', - '𩈚' => '𩈚', - '䩮' => '䩮', - '䩶' => '䩶', - '韠' => '韠', - '𩐊' => '𩐊', - '䪲' => '䪲', - '𩒖' => '𩒖', - '頋' => '頋', - '頋' => '頋', - '頩' => '頩', - '𩖶' => '𩖶', - '飢' => '飢', - '䬳' => '䬳', - '餩' => '餩', - '馧' => '馧', - '駂' => '駂', - '駾' => '駾', - '䯎' => '䯎', - '𩬰' => '𩬰', - '鬒' => '鬒', - '鱀' => '鱀', - '鳽' => '鳽', - '䳎' => '䳎', - '䳭' => '䳭', - '鵧' => '鵧', - '𪃎' => '𪃎', - '䳸' => '䳸', - '𪄅' => '𪄅', - '𪈎' => '𪈎', - '𪊑' => '𪊑', - '麻' => '麻', - '䵖' => '䵖', - '黹' => '黹', - '黾' => '黾', - '鼅' => '鼅', - '鼏' => '鼏', - '鼖' => '鼖', - '鼻' => '鼻', - '𪘀' => '𪘀', -); diff --git a/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php deleted file mode 100644 index ec90f36eb..000000000 --- a/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php +++ /dev/null @@ -1,876 +0,0 @@ - 230, - '́' => 230, - '̂' => 230, - '̃' => 230, - '̄' => 230, - '̅' => 230, - '̆' => 230, - '̇' => 230, - '̈' => 230, - '̉' => 230, - '̊' => 230, - '̋' => 230, - '̌' => 230, - '̍' => 230, - '̎' => 230, - '̏' => 230, - '̐' => 230, - '̑' => 230, - '̒' => 230, - '̓' => 230, - '̔' => 230, - '̕' => 232, - '̖' => 220, - '̗' => 220, - '̘' => 220, - '̙' => 220, - '̚' => 232, - '̛' => 216, - '̜' => 220, - '̝' => 220, - '̞' => 220, - '̟' => 220, - '̠' => 220, - '̡' => 202, - '̢' => 202, - '̣' => 220, - '̤' => 220, - '̥' => 220, - '̦' => 220, - '̧' => 202, - '̨' => 202, - '̩' => 220, - '̪' => 220, - '̫' => 220, - '̬' => 220, - '̭' => 220, - '̮' => 220, - '̯' => 220, - '̰' => 220, - '̱' => 220, - '̲' => 220, - '̳' => 220, - '̴' => 1, - '̵' => 1, - '̶' => 1, - '̷' => 1, - '̸' => 1, - '̹' => 220, - '̺' => 220, - '̻' => 220, - '̼' => 220, - '̽' => 230, - '̾' => 230, - '̿' => 230, - '̀' => 230, - '́' => 230, - '͂' => 230, - '̓' => 230, - '̈́' => 230, - 'ͅ' => 240, - '͆' => 230, - '͇' => 220, - '͈' => 220, - '͉' => 220, - '͊' => 230, - '͋' => 230, - '͌' => 230, - '͍' => 220, - '͎' => 220, - '͐' => 230, - '͑' => 230, - '͒' => 230, - '͓' => 220, - '͔' => 220, - '͕' => 220, - '͖' => 220, - '͗' => 230, - '͘' => 232, - '͙' => 220, - '͚' => 220, - '͛' => 230, - '͜' => 233, - '͝' => 234, - '͞' => 234, - '͟' => 233, - '͠' => 234, - '͡' => 234, - '͢' => 233, - 'ͣ' => 230, - 'ͤ' => 230, - 'ͥ' => 230, - 'ͦ' => 230, - 'ͧ' => 230, - 'ͨ' => 230, - 'ͩ' => 230, - 'ͪ' => 230, - 'ͫ' => 230, - 'ͬ' => 230, - 'ͭ' => 230, - 'ͮ' => 230, - 'ͯ' => 230, - '҃' => 230, - '҄' => 230, - '҅' => 230, - '҆' => 230, - '҇' => 230, - '֑' => 220, - '֒' => 230, - '֓' => 230, - '֔' => 230, - '֕' => 230, - '֖' => 220, - '֗' => 230, - '֘' => 230, - '֙' => 230, - '֚' => 222, - '֛' => 220, - '֜' => 230, - '֝' => 230, - '֞' => 230, - '֟' => 230, - '֠' => 230, - '֡' => 230, - '֢' => 220, - '֣' => 220, - '֤' => 220, - '֥' => 220, - '֦' => 220, - '֧' => 220, - '֨' => 230, - '֩' => 230, - '֪' => 220, - '֫' => 230, - '֬' => 230, - '֭' => 222, - '֮' => 228, - '֯' => 230, - 'ְ' => 10, - 'ֱ' => 11, - 'ֲ' => 12, - 'ֳ' => 13, - 'ִ' => 14, - 'ֵ' => 15, - 'ֶ' => 16, - 'ַ' => 17, - 'ָ' => 18, - 'ֹ' => 19, - 'ֺ' => 19, - 'ֻ' => 20, - 'ּ' => 21, - 'ֽ' => 22, - 'ֿ' => 23, - 'ׁ' => 24, - 'ׂ' => 25, - 'ׄ' => 230, - 'ׅ' => 220, - 'ׇ' => 18, - 'ؐ' => 230, - 'ؑ' => 230, - 'ؒ' => 230, - 'ؓ' => 230, - 'ؔ' => 230, - 'ؕ' => 230, - 'ؖ' => 230, - 'ؗ' => 230, - 'ؘ' => 30, - 'ؙ' => 31, - 'ؚ' => 32, - 'ً' => 27, - 'ٌ' => 28, - 'ٍ' => 29, - 'َ' => 30, - 'ُ' => 31, - 'ِ' => 32, - 'ّ' => 33, - 'ْ' => 34, - 'ٓ' => 230, - 'ٔ' => 230, - 'ٕ' => 220, - 'ٖ' => 220, - 'ٗ' => 230, - '٘' => 230, - 'ٙ' => 230, - 'ٚ' => 230, - 'ٛ' => 230, - 'ٜ' => 220, - 'ٝ' => 230, - 'ٞ' => 230, - 'ٟ' => 220, - 'ٰ' => 35, - 'ۖ' => 230, - 'ۗ' => 230, - 'ۘ' => 230, - 'ۙ' => 230, - 'ۚ' => 230, - 'ۛ' => 230, - 'ۜ' => 230, - '۟' => 230, - '۠' => 230, - 'ۡ' => 230, - 'ۢ' => 230, - 'ۣ' => 220, - 'ۤ' => 230, - 'ۧ' => 230, - 'ۨ' => 230, - '۪' => 220, - '۫' => 230, - '۬' => 230, - 'ۭ' => 220, - 'ܑ' => 36, - 'ܰ' => 230, - 'ܱ' => 220, - 'ܲ' => 230, - 'ܳ' => 230, - 'ܴ' => 220, - 'ܵ' => 230, - 'ܶ' => 230, - 'ܷ' => 220, - 'ܸ' => 220, - 'ܹ' => 220, - 'ܺ' => 230, - 'ܻ' => 220, - 'ܼ' => 220, - 'ܽ' => 230, - 'ܾ' => 220, - 'ܿ' => 230, - '݀' => 230, - '݁' => 230, - '݂' => 220, - '݃' => 230, - '݄' => 220, - '݅' => 230, - '݆' => 220, - '݇' => 230, - '݈' => 220, - '݉' => 230, - '݊' => 230, - '߫' => 230, - '߬' => 230, - '߭' => 230, - '߮' => 230, - '߯' => 230, - '߰' => 230, - '߱' => 230, - '߲' => 220, - '߳' => 230, - '߽' => 220, - 'ࠖ' => 230, - 'ࠗ' => 230, - '࠘' => 230, - '࠙' => 230, - 'ࠛ' => 230, - 'ࠜ' => 230, - 'ࠝ' => 230, - 'ࠞ' => 230, - 'ࠟ' => 230, - 'ࠠ' => 230, - 'ࠡ' => 230, - 'ࠢ' => 230, - 'ࠣ' => 230, - 'ࠥ' => 230, - 'ࠦ' => 230, - 'ࠧ' => 230, - 'ࠩ' => 230, - 'ࠪ' => 230, - 'ࠫ' => 230, - 'ࠬ' => 230, - '࠭' => 230, - '࡙' => 220, - '࡚' => 220, - '࡛' => 220, - '࣓' => 220, - 'ࣔ' => 230, - 'ࣕ' => 230, - 'ࣖ' => 230, - 'ࣗ' => 230, - 'ࣘ' => 230, - 'ࣙ' => 230, - 'ࣚ' => 230, - 'ࣛ' => 230, - 'ࣜ' => 230, - 'ࣝ' => 230, - 'ࣞ' => 230, - 'ࣟ' => 230, - '࣠' => 230, - '࣡' => 230, - 'ࣣ' => 220, - 'ࣤ' => 230, - 'ࣥ' => 230, - 'ࣦ' => 220, - 'ࣧ' => 230, - 'ࣨ' => 230, - 'ࣩ' => 220, - '࣪' => 230, - '࣫' => 230, - '࣬' => 230, - '࣭' => 220, - '࣮' => 220, - '࣯' => 220, - 'ࣰ' => 27, - 'ࣱ' => 28, - 'ࣲ' => 29, - 'ࣳ' => 230, - 'ࣴ' => 230, - 'ࣵ' => 230, - 'ࣶ' => 220, - 'ࣷ' => 230, - 'ࣸ' => 230, - 'ࣹ' => 220, - 'ࣺ' => 220, - 'ࣻ' => 230, - 'ࣼ' => 230, - 'ࣽ' => 230, - 'ࣾ' => 230, - 'ࣿ' => 230, - '़' => 7, - '्' => 9, - '॑' => 230, - '॒' => 220, - '॓' => 230, - '॔' => 230, - '়' => 7, - '্' => 9, - '৾' => 230, - '਼' => 7, - '੍' => 9, - '઼' => 7, - '્' => 9, - '଼' => 7, - '୍' => 9, - '்' => 9, - '్' => 9, - 'ౕ' => 84, - 'ౖ' => 91, - '಼' => 7, - '್' => 9, - '഻' => 9, - '഼' => 9, - '്' => 9, - '්' => 9, - 'ุ' => 103, - 'ู' => 103, - 'ฺ' => 9, - '่' => 107, - '้' => 107, - '๊' => 107, - '๋' => 107, - 'ຸ' => 118, - 'ູ' => 118, - '຺' => 9, - '່' => 122, - '້' => 122, - '໊' => 122, - '໋' => 122, - '༘' => 220, - '༙' => 220, - '༵' => 220, - '༷' => 220, - '༹' => 216, - 'ཱ' => 129, - 'ི' => 130, - 'ུ' => 132, - 'ེ' => 130, - 'ཻ' => 130, - 'ོ' => 130, - 'ཽ' => 130, - 'ྀ' => 130, - 'ྂ' => 230, - 'ྃ' => 230, - '྄' => 9, - '྆' => 230, - '྇' => 230, - '࿆' => 220, - '့' => 7, - '္' => 9, - '်' => 9, - 'ႍ' => 220, - '፝' => 230, - '፞' => 230, - '፟' => 230, - '᜔' => 9, - '᜴' => 9, - '្' => 9, - '៝' => 230, - 'ᢩ' => 228, - '᤹' => 222, - '᤺' => 230, - '᤻' => 220, - 'ᨗ' => 230, - 'ᨘ' => 220, - '᩠' => 9, - '᩵' => 230, - '᩶' => 230, - '᩷' => 230, - '᩸' => 230, - '᩹' => 230, - '᩺' => 230, - '᩻' => 230, - '᩼' => 230, - '᩿' => 220, - '᪰' => 230, - '᪱' => 230, - '᪲' => 230, - '᪳' => 230, - '᪴' => 230, - '᪵' => 220, - '᪶' => 220, - '᪷' => 220, - '᪸' => 220, - '᪹' => 220, - '᪺' => 220, - '᪻' => 230, - '᪼' => 230, - '᪽' => 220, - 'ᪿ' => 220, - 'ᫀ' => 220, - '᬴' => 7, - '᭄' => 9, - '᭫' => 230, - '᭬' => 220, - '᭭' => 230, - '᭮' => 230, - '᭯' => 230, - '᭰' => 230, - '᭱' => 230, - '᭲' => 230, - '᭳' => 230, - '᮪' => 9, - '᮫' => 9, - '᯦' => 7, - '᯲' => 9, - '᯳' => 9, - '᰷' => 7, - '᳐' => 230, - '᳑' => 230, - '᳒' => 230, - '᳔' => 1, - '᳕' => 220, - '᳖' => 220, - '᳗' => 220, - '᳘' => 220, - '᳙' => 220, - '᳚' => 230, - '᳛' => 230, - '᳜' => 220, - '᳝' => 220, - '᳞' => 220, - '᳟' => 220, - '᳠' => 230, - '᳢' => 1, - '᳣' => 1, - '᳤' => 1, - '᳥' => 1, - '᳦' => 1, - '᳧' => 1, - '᳨' => 1, - '᳭' => 220, - '᳴' => 230, - '᳸' => 230, - '᳹' => 230, - '᷀' => 230, - '᷁' => 230, - '᷂' => 220, - '᷃' => 230, - '᷄' => 230, - '᷅' => 230, - '᷆' => 230, - '᷇' => 230, - '᷈' => 230, - '᷉' => 230, - '᷊' => 220, - '᷋' => 230, - '᷌' => 230, - '᷍' => 234, - '᷎' => 214, - '᷏' => 220, - '᷐' => 202, - '᷑' => 230, - '᷒' => 230, - 'ᷓ' => 230, - 'ᷔ' => 230, - 'ᷕ' => 230, - 'ᷖ' => 230, - 'ᷗ' => 230, - 'ᷘ' => 230, - 'ᷙ' => 230, - 'ᷚ' => 230, - 'ᷛ' => 230, - 'ᷜ' => 230, - 'ᷝ' => 230, - 'ᷞ' => 230, - 'ᷟ' => 230, - 'ᷠ' => 230, - 'ᷡ' => 230, - 'ᷢ' => 230, - 'ᷣ' => 230, - 'ᷤ' => 230, - 'ᷥ' => 230, - 'ᷦ' => 230, - 'ᷧ' => 230, - 'ᷨ' => 230, - 'ᷩ' => 230, - 'ᷪ' => 230, - 'ᷫ' => 230, - 'ᷬ' => 230, - 'ᷭ' => 230, - 'ᷮ' => 230, - 'ᷯ' => 230, - 'ᷰ' => 230, - 'ᷱ' => 230, - 'ᷲ' => 230, - 'ᷳ' => 230, - 'ᷴ' => 230, - '᷵' => 230, - '᷶' => 232, - '᷷' => 228, - '᷸' => 228, - '᷹' => 220, - '᷻' => 230, - '᷼' => 233, - '᷽' => 220, - '᷾' => 230, - '᷿' => 220, - '⃐' => 230, - '⃑' => 230, - '⃒' => 1, - '⃓' => 1, - '⃔' => 230, - '⃕' => 230, - '⃖' => 230, - '⃗' => 230, - '⃘' => 1, - '⃙' => 1, - '⃚' => 1, - '⃛' => 230, - '⃜' => 230, - '⃡' => 230, - '⃥' => 1, - '⃦' => 1, - '⃧' => 230, - '⃨' => 220, - '⃩' => 230, - '⃪' => 1, - '⃫' => 1, - '⃬' => 220, - '⃭' => 220, - '⃮' => 220, - '⃯' => 220, - '⃰' => 230, - '⳯' => 230, - '⳰' => 230, - '⳱' => 230, - '⵿' => 9, - 'ⷠ' => 230, - 'ⷡ' => 230, - 'ⷢ' => 230, - 'ⷣ' => 230, - 'ⷤ' => 230, - 'ⷥ' => 230, - 'ⷦ' => 230, - 'ⷧ' => 230, - 'ⷨ' => 230, - 'ⷩ' => 230, - 'ⷪ' => 230, - 'ⷫ' => 230, - 'ⷬ' => 230, - 'ⷭ' => 230, - 'ⷮ' => 230, - 'ⷯ' => 230, - 'ⷰ' => 230, - 'ⷱ' => 230, - 'ⷲ' => 230, - 'ⷳ' => 230, - 'ⷴ' => 230, - 'ⷵ' => 230, - 'ⷶ' => 230, - 'ⷷ' => 230, - 'ⷸ' => 230, - 'ⷹ' => 230, - 'ⷺ' => 230, - 'ⷻ' => 230, - 'ⷼ' => 230, - 'ⷽ' => 230, - 'ⷾ' => 230, - 'ⷿ' => 230, - '〪' => 218, - '〫' => 228, - '〬' => 232, - '〭' => 222, - '〮' => 224, - '〯' => 224, - '゙' => 8, - '゚' => 8, - '꙯' => 230, - 'ꙴ' => 230, - 'ꙵ' => 230, - 'ꙶ' => 230, - 'ꙷ' => 230, - 'ꙸ' => 230, - 'ꙹ' => 230, - 'ꙺ' => 230, - 'ꙻ' => 230, - '꙼' => 230, - '꙽' => 230, - 'ꚞ' => 230, - 'ꚟ' => 230, - '꛰' => 230, - '꛱' => 230, - '꠆' => 9, - '꠬' => 9, - '꣄' => 9, - '꣠' => 230, - '꣡' => 230, - '꣢' => 230, - '꣣' => 230, - '꣤' => 230, - '꣥' => 230, - '꣦' => 230, - '꣧' => 230, - '꣨' => 230, - '꣩' => 230, - '꣪' => 230, - '꣫' => 230, - '꣬' => 230, - '꣭' => 230, - '꣮' => 230, - '꣯' => 230, - '꣰' => 230, - '꣱' => 230, - '꤫' => 220, - '꤬' => 220, - '꤭' => 220, - '꥓' => 9, - '꦳' => 7, - '꧀' => 9, - 'ꪰ' => 230, - 'ꪲ' => 230, - 'ꪳ' => 230, - 'ꪴ' => 220, - 'ꪷ' => 230, - 'ꪸ' => 230, - 'ꪾ' => 230, - '꪿' => 230, - '꫁' => 230, - '꫶' => 9, - '꯭' => 9, - 'ﬞ' => 26, - '︠' => 230, - '︡' => 230, - '︢' => 230, - '︣' => 230, - '︤' => 230, - '︥' => 230, - '︦' => 230, - '︧' => 220, - '︨' => 220, - '︩' => 220, - '︪' => 220, - '︫' => 220, - '︬' => 220, - '︭' => 220, - '︮' => 230, - '︯' => 230, - '𐇽' => 220, - '𐋠' => 220, - '𐍶' => 230, - '𐍷' => 230, - '𐍸' => 230, - '𐍹' => 230, - '𐍺' => 230, - '𐨍' => 220, - '𐨏' => 230, - '𐨸' => 230, - '𐨹' => 1, - '𐨺' => 220, - '𐨿' => 9, - '𐫥' => 230, - '𐫦' => 220, - '𐴤' => 230, - '𐴥' => 230, - '𐴦' => 230, - '𐴧' => 230, - '𐺫' => 230, - '𐺬' => 230, - '𐽆' => 220, - '𐽇' => 220, - '𐽈' => 230, - '𐽉' => 230, - '𐽊' => 230, - '𐽋' => 220, - '𐽌' => 230, - '𐽍' => 220, - '𐽎' => 220, - '𐽏' => 220, - '𐽐' => 220, - '𑁆' => 9, - '𑁿' => 9, - '𑂹' => 9, - '𑂺' => 7, - '𑄀' => 230, - '𑄁' => 230, - '𑄂' => 230, - '𑄳' => 9, - '𑄴' => 9, - '𑅳' => 7, - '𑇀' => 9, - '𑇊' => 7, - '𑈵' => 9, - '𑈶' => 7, - '𑋩' => 7, - '𑋪' => 9, - '𑌻' => 7, - '𑌼' => 7, - '𑍍' => 9, - '𑍦' => 230, - '𑍧' => 230, - '𑍨' => 230, - '𑍩' => 230, - '𑍪' => 230, - '𑍫' => 230, - '𑍬' => 230, - '𑍰' => 230, - '𑍱' => 230, - '𑍲' => 230, - '𑍳' => 230, - '𑍴' => 230, - '𑑂' => 9, - '𑑆' => 7, - '𑑞' => 230, - '𑓂' => 9, - '𑓃' => 7, - '𑖿' => 9, - '𑗀' => 7, - '𑘿' => 9, - '𑚶' => 9, - '𑚷' => 7, - '𑜫' => 9, - '𑠹' => 9, - '𑠺' => 7, - '𑤽' => 9, - '𑤾' => 9, - '𑥃' => 7, - '𑧠' => 9, - '𑨴' => 9, - '𑩇' => 9, - '𑪙' => 9, - '𑰿' => 9, - '𑵂' => 7, - '𑵄' => 9, - '𑵅' => 9, - '𑶗' => 9, - '𖫰' => 1, - '𖫱' => 1, - '𖫲' => 1, - '𖫳' => 1, - '𖫴' => 1, - '𖬰' => 230, - '𖬱' => 230, - '𖬲' => 230, - '𖬳' => 230, - '𖬴' => 230, - '𖬵' => 230, - '𖬶' => 230, - '𖿰' => 6, - '𖿱' => 6, - '𛲞' => 1, - '𝅥' => 216, - '𝅦' => 216, - '𝅧' => 1, - '𝅨' => 1, - '𝅩' => 1, - '𝅭' => 226, - '𝅮' => 216, - '𝅯' => 216, - '𝅰' => 216, - '𝅱' => 216, - '𝅲' => 216, - '𝅻' => 220, - '𝅼' => 220, - '𝅽' => 220, - '𝅾' => 220, - '𝅿' => 220, - '𝆀' => 220, - '𝆁' => 220, - '𝆂' => 220, - '𝆅' => 230, - '𝆆' => 230, - '𝆇' => 230, - '𝆈' => 230, - '𝆉' => 230, - '𝆊' => 220, - '𝆋' => 220, - '𝆪' => 230, - '𝆫' => 230, - '𝆬' => 230, - '𝆭' => 230, - '𝉂' => 230, - '𝉃' => 230, - '𝉄' => 230, - '𞀀' => 230, - '𞀁' => 230, - '𞀂' => 230, - '𞀃' => 230, - '𞀄' => 230, - '𞀅' => 230, - '𞀆' => 230, - '𞀈' => 230, - '𞀉' => 230, - '𞀊' => 230, - '𞀋' => 230, - '𞀌' => 230, - '𞀍' => 230, - '𞀎' => 230, - '𞀏' => 230, - '𞀐' => 230, - '𞀑' => 230, - '𞀒' => 230, - '𞀓' => 230, - '𞀔' => 230, - '𞀕' => 230, - '𞀖' => 230, - '𞀗' => 230, - '𞀘' => 230, - '𞀛' => 230, - '𞀜' => 230, - '𞀝' => 230, - '𞀞' => 230, - '𞀟' => 230, - '𞀠' => 230, - '𞀡' => 230, - '𞀣' => 230, - '𞀤' => 230, - '𞀦' => 230, - '𞀧' => 230, - '𞀨' => 230, - '𞀩' => 230, - '𞀪' => 230, - '𞄰' => 230, - '𞄱' => 230, - '𞄲' => 230, - '𞄳' => 230, - '𞄴' => 230, - '𞄵' => 230, - '𞄶' => 230, - '𞋬' => 230, - '𞋭' => 230, - '𞋮' => 230, - '𞋯' => 230, - '𞣐' => 220, - '𞣑' => 220, - '𞣒' => 220, - '𞣓' => 220, - '𞣔' => 220, - '𞣕' => 220, - '𞣖' => 220, - '𞥄' => 230, - '𞥅' => 230, - '𞥆' => 230, - '𞥇' => 230, - '𞥈' => 230, - '𞥉' => 230, - '𞥊' => 7, -); diff --git a/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php deleted file mode 100644 index 157490289..000000000 --- a/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php +++ /dev/null @@ -1,3695 +0,0 @@ - ' ', - '¨' => ' ̈', - 'ª' => 'a', - '¯' => ' ̄', - '²' => '2', - '³' => '3', - '´' => ' ́', - 'µ' => 'μ', - '¸' => ' ̧', - '¹' => '1', - 'º' => 'o', - '¼' => '1⁄4', - '½' => '1⁄2', - '¾' => '3⁄4', - 'IJ' => 'IJ', - 'ij' => 'ij', - 'Ŀ' => 'L·', - 'ŀ' => 'l·', - 'ʼn' => 'ʼn', - 'ſ' => 's', - 'DŽ' => 'DŽ', - 'Dž' => 'Dž', - 'dž' => 'dž', - 'LJ' => 'LJ', - 'Lj' => 'Lj', - 'lj' => 'lj', - 'NJ' => 'NJ', - 'Nj' => 'Nj', - 'nj' => 'nj', - 'DZ' => 'DZ', - 'Dz' => 'Dz', - 'dz' => 'dz', - 'ʰ' => 'h', - 'ʱ' => 'ɦ', - 'ʲ' => 'j', - 'ʳ' => 'r', - 'ʴ' => 'ɹ', - 'ʵ' => 'ɻ', - 'ʶ' => 'ʁ', - 'ʷ' => 'w', - 'ʸ' => 'y', - '˘' => ' ̆', - '˙' => ' ̇', - '˚' => ' ̊', - '˛' => ' ̨', - '˜' => ' ̃', - '˝' => ' ̋', - 'ˠ' => 'ɣ', - 'ˡ' => 'l', - 'ˢ' => 's', - 'ˣ' => 'x', - 'ˤ' => 'ʕ', - 'ͺ' => ' ͅ', - '΄' => ' ́', - '΅' => ' ̈́', - 'ϐ' => 'β', - 'ϑ' => 'θ', - 'ϒ' => 'Υ', - 'ϓ' => 'Ύ', - 'ϔ' => 'Ϋ', - 'ϕ' => 'φ', - 'ϖ' => 'π', - 'ϰ' => 'κ', - 'ϱ' => 'ρ', - 'ϲ' => 'ς', - 'ϴ' => 'Θ', - 'ϵ' => 'ε', - 'Ϲ' => 'Σ', - 'և' => 'եւ', - 'ٵ' => 'اٴ', - 'ٶ' => 'وٴ', - 'ٷ' => 'ۇٴ', - 'ٸ' => 'يٴ', - 'ำ' => 'ํา', - 'ຳ' => 'ໍາ', - 'ໜ' => 'ຫນ', - 'ໝ' => 'ຫມ', - '༌' => '་', - 'ཷ' => 'ྲཱྀ', - 'ཹ' => 'ླཱྀ', - 'ჼ' => 'ნ', - 'ᴬ' => 'A', - 'ᴭ' => 'Æ', - 'ᴮ' => 'B', - 'ᴰ' => 'D', - 'ᴱ' => 'E', - 'ᴲ' => 'Ǝ', - 'ᴳ' => 'G', - 'ᴴ' => 'H', - 'ᴵ' => 'I', - 'ᴶ' => 'J', - 'ᴷ' => 'K', - 'ᴸ' => 'L', - 'ᴹ' => 'M', - 'ᴺ' => 'N', - 'ᴼ' => 'O', - 'ᴽ' => 'Ȣ', - 'ᴾ' => 'P', - 'ᴿ' => 'R', - 'ᵀ' => 'T', - 'ᵁ' => 'U', - 'ᵂ' => 'W', - 'ᵃ' => 'a', - 'ᵄ' => 'ɐ', - 'ᵅ' => 'ɑ', - 'ᵆ' => 'ᴂ', - 'ᵇ' => 'b', - 'ᵈ' => 'd', - 'ᵉ' => 'e', - 'ᵊ' => 'ə', - 'ᵋ' => 'ɛ', - 'ᵌ' => 'ɜ', - 'ᵍ' => 'g', - 'ᵏ' => 'k', - 'ᵐ' => 'm', - 'ᵑ' => 'ŋ', - 'ᵒ' => 'o', - 'ᵓ' => 'ɔ', - 'ᵔ' => 'ᴖ', - 'ᵕ' => 'ᴗ', - 'ᵖ' => 'p', - 'ᵗ' => 't', - 'ᵘ' => 'u', - 'ᵙ' => 'ᴝ', - 'ᵚ' => 'ɯ', - 'ᵛ' => 'v', - 'ᵜ' => 'ᴥ', - 'ᵝ' => 'β', - 'ᵞ' => 'γ', - 'ᵟ' => 'δ', - 'ᵠ' => 'φ', - 'ᵡ' => 'χ', - 'ᵢ' => 'i', - 'ᵣ' => 'r', - 'ᵤ' => 'u', - 'ᵥ' => 'v', - 'ᵦ' => 'β', - 'ᵧ' => 'γ', - 'ᵨ' => 'ρ', - 'ᵩ' => 'φ', - 'ᵪ' => 'χ', - 'ᵸ' => 'н', - 'ᶛ' => 'ɒ', - 'ᶜ' => 'c', - 'ᶝ' => 'ɕ', - 'ᶞ' => 'ð', - 'ᶟ' => 'ɜ', - 'ᶠ' => 'f', - 'ᶡ' => 'ɟ', - 'ᶢ' => 'ɡ', - 'ᶣ' => 'ɥ', - 'ᶤ' => 'ɨ', - 'ᶥ' => 'ɩ', - 'ᶦ' => 'ɪ', - 'ᶧ' => 'ᵻ', - 'ᶨ' => 'ʝ', - 'ᶩ' => 'ɭ', - 'ᶪ' => 'ᶅ', - 'ᶫ' => 'ʟ', - 'ᶬ' => 'ɱ', - 'ᶭ' => 'ɰ', - 'ᶮ' => 'ɲ', - 'ᶯ' => 'ɳ', - 'ᶰ' => 'ɴ', - 'ᶱ' => 'ɵ', - 'ᶲ' => 'ɸ', - 'ᶳ' => 'ʂ', - 'ᶴ' => 'ʃ', - 'ᶵ' => 'ƫ', - 'ᶶ' => 'ʉ', - 'ᶷ' => 'ʊ', - 'ᶸ' => 'ᴜ', - 'ᶹ' => 'ʋ', - 'ᶺ' => 'ʌ', - 'ᶻ' => 'z', - 'ᶼ' => 'ʐ', - 'ᶽ' => 'ʑ', - 'ᶾ' => 'ʒ', - 'ᶿ' => 'θ', - 'ẚ' => 'aʾ', - 'ẛ' => 'ṡ', - '᾽' => ' ̓', - '᾿' => ' ̓', - '῀' => ' ͂', - '῁' => ' ̈͂', - '῍' => ' ̓̀', - '῎' => ' ̓́', - '῏' => ' ̓͂', - '῝' => ' ̔̀', - '῞' => ' ̔́', - '῟' => ' ̔͂', - '῭' => ' ̈̀', - '΅' => ' ̈́', - '´' => ' ́', - '῾' => ' ̔', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - ' ' => ' ', - '‑' => '‐', - '‗' => ' ̳', - '․' => '.', - '‥' => '..', - '…' => '...', - ' ' => ' ', - '″' => '′′', - '‴' => '′′′', - '‶' => '‵‵', - '‷' => '‵‵‵', - '‼' => '!!', - '‾' => ' ̅', - '⁇' => '??', - '⁈' => '?!', - '⁉' => '!?', - '⁗' => '′′′′', - ' ' => ' ', - '⁰' => '0', - 'ⁱ' => 'i', - '⁴' => '4', - '⁵' => '5', - '⁶' => '6', - '⁷' => '7', - '⁸' => '8', - '⁹' => '9', - '⁺' => '+', - '⁻' => '−', - '⁼' => '=', - '⁽' => '(', - '⁾' => ')', - 'ⁿ' => 'n', - '₀' => '0', - '₁' => '1', - '₂' => '2', - '₃' => '3', - '₄' => '4', - '₅' => '5', - '₆' => '6', - '₇' => '7', - '₈' => '8', - '₉' => '9', - '₊' => '+', - '₋' => '−', - '₌' => '=', - '₍' => '(', - '₎' => ')', - 'ₐ' => 'a', - 'ₑ' => 'e', - 'ₒ' => 'o', - 'ₓ' => 'x', - 'ₔ' => 'ə', - 'ₕ' => 'h', - 'ₖ' => 'k', - 'ₗ' => 'l', - 'ₘ' => 'm', - 'ₙ' => 'n', - 'ₚ' => 'p', - 'ₛ' => 's', - 'ₜ' => 't', - '₨' => 'Rs', - '℀' => 'a/c', - '℁' => 'a/s', - 'ℂ' => 'C', - '℃' => '°C', - '℅' => 'c/o', - '℆' => 'c/u', - 'ℇ' => 'Ɛ', - '℉' => '°F', - 'ℊ' => 'g', - 'ℋ' => 'H', - 'ℌ' => 'H', - 'ℍ' => 'H', - 'ℎ' => 'h', - 'ℏ' => 'ħ', - 'ℐ' => 'I', - 'ℑ' => 'I', - 'ℒ' => 'L', - 'ℓ' => 'l', - 'ℕ' => 'N', - '№' => 'No', - 'ℙ' => 'P', - 'ℚ' => 'Q', - 'ℛ' => 'R', - 'ℜ' => 'R', - 'ℝ' => 'R', - '℠' => 'SM', - '℡' => 'TEL', - '™' => 'TM', - 'ℤ' => 'Z', - 'ℨ' => 'Z', - 'ℬ' => 'B', - 'ℭ' => 'C', - 'ℯ' => 'e', - 'ℰ' => 'E', - 'ℱ' => 'F', - 'ℳ' => 'M', - 'ℴ' => 'o', - 'ℵ' => 'א', - 'ℶ' => 'ב', - 'ℷ' => 'ג', - 'ℸ' => 'ד', - 'ℹ' => 'i', - '℻' => 'FAX', - 'ℼ' => 'π', - 'ℽ' => 'γ', - 'ℾ' => 'Γ', - 'ℿ' => 'Π', - '⅀' => '∑', - 'ⅅ' => 'D', - 'ⅆ' => 'd', - 'ⅇ' => 'e', - 'ⅈ' => 'i', - 'ⅉ' => 'j', - '⅐' => '1⁄7', - '⅑' => '1⁄9', - '⅒' => '1⁄10', - '⅓' => '1⁄3', - '⅔' => '2⁄3', - '⅕' => '1⁄5', - '⅖' => '2⁄5', - '⅗' => '3⁄5', - '⅘' => '4⁄5', - '⅙' => '1⁄6', - '⅚' => '5⁄6', - '⅛' => '1⁄8', - '⅜' => '3⁄8', - '⅝' => '5⁄8', - '⅞' => '7⁄8', - '⅟' => '1⁄', - 'Ⅰ' => 'I', - 'Ⅱ' => 'II', - 'Ⅲ' => 'III', - 'Ⅳ' => 'IV', - 'Ⅴ' => 'V', - 'Ⅵ' => 'VI', - 'Ⅶ' => 'VII', - 'Ⅷ' => 'VIII', - 'Ⅸ' => 'IX', - 'Ⅹ' => 'X', - 'Ⅺ' => 'XI', - 'Ⅻ' => 'XII', - 'Ⅼ' => 'L', - 'Ⅽ' => 'C', - 'Ⅾ' => 'D', - 'Ⅿ' => 'M', - 'ⅰ' => 'i', - 'ⅱ' => 'ii', - 'ⅲ' => 'iii', - 'ⅳ' => 'iv', - 'ⅴ' => 'v', - 'ⅵ' => 'vi', - 'ⅶ' => 'vii', - 'ⅷ' => 'viii', - 'ⅸ' => 'ix', - 'ⅹ' => 'x', - 'ⅺ' => 'xi', - 'ⅻ' => 'xii', - 'ⅼ' => 'l', - 'ⅽ' => 'c', - 'ⅾ' => 'd', - 'ⅿ' => 'm', - '↉' => '0⁄3', - '∬' => '∫∫', - '∭' => '∫∫∫', - '∯' => '∮∮', - '∰' => '∮∮∮', - '①' => '1', - '②' => '2', - '③' => '3', - '④' => '4', - '⑤' => '5', - '⑥' => '6', - '⑦' => '7', - '⑧' => '8', - '⑨' => '9', - '⑩' => '10', - '⑪' => '11', - '⑫' => '12', - '⑬' => '13', - '⑭' => '14', - '⑮' => '15', - '⑯' => '16', - '⑰' => '17', - '⑱' => '18', - '⑲' => '19', - '⑳' => '20', - '⑴' => '(1)', - '⑵' => '(2)', - '⑶' => '(3)', - '⑷' => '(4)', - '⑸' => '(5)', - '⑹' => '(6)', - '⑺' => '(7)', - '⑻' => '(8)', - '⑼' => '(9)', - '⑽' => '(10)', - '⑾' => '(11)', - '⑿' => '(12)', - '⒀' => '(13)', - '⒁' => '(14)', - '⒂' => '(15)', - '⒃' => '(16)', - '⒄' => '(17)', - '⒅' => '(18)', - '⒆' => '(19)', - '⒇' => '(20)', - '⒈' => '1.', - '⒉' => '2.', - '⒊' => '3.', - '⒋' => '4.', - '⒌' => '5.', - '⒍' => '6.', - '⒎' => '7.', - '⒏' => '8.', - '⒐' => '9.', - '⒑' => '10.', - '⒒' => '11.', - '⒓' => '12.', - '⒔' => '13.', - '⒕' => '14.', - '⒖' => '15.', - '⒗' => '16.', - '⒘' => '17.', - '⒙' => '18.', - '⒚' => '19.', - '⒛' => '20.', - '⒜' => '(a)', - '⒝' => '(b)', - '⒞' => '(c)', - '⒟' => '(d)', - '⒠' => '(e)', - '⒡' => '(f)', - '⒢' => '(g)', - '⒣' => '(h)', - '⒤' => '(i)', - '⒥' => '(j)', - '⒦' => '(k)', - '⒧' => '(l)', - '⒨' => '(m)', - '⒩' => '(n)', - '⒪' => '(o)', - '⒫' => '(p)', - '⒬' => '(q)', - '⒭' => '(r)', - '⒮' => '(s)', - '⒯' => '(t)', - '⒰' => '(u)', - '⒱' => '(v)', - '⒲' => '(w)', - '⒳' => '(x)', - '⒴' => '(y)', - '⒵' => '(z)', - 'Ⓐ' => 'A', - 'Ⓑ' => 'B', - 'Ⓒ' => 'C', - 'Ⓓ' => 'D', - 'Ⓔ' => 'E', - 'Ⓕ' => 'F', - 'Ⓖ' => 'G', - 'Ⓗ' => 'H', - 'Ⓘ' => 'I', - 'Ⓙ' => 'J', - 'Ⓚ' => 'K', - 'Ⓛ' => 'L', - 'Ⓜ' => 'M', - 'Ⓝ' => 'N', - 'Ⓞ' => 'O', - 'Ⓟ' => 'P', - 'Ⓠ' => 'Q', - 'Ⓡ' => 'R', - 'Ⓢ' => 'S', - 'Ⓣ' => 'T', - 'Ⓤ' => 'U', - 'Ⓥ' => 'V', - 'Ⓦ' => 'W', - 'Ⓧ' => 'X', - 'Ⓨ' => 'Y', - 'Ⓩ' => 'Z', - 'ⓐ' => 'a', - 'ⓑ' => 'b', - 'ⓒ' => 'c', - 'ⓓ' => 'd', - 'ⓔ' => 'e', - 'ⓕ' => 'f', - 'ⓖ' => 'g', - 'ⓗ' => 'h', - 'ⓘ' => 'i', - 'ⓙ' => 'j', - 'ⓚ' => 'k', - 'ⓛ' => 'l', - 'ⓜ' => 'm', - 'ⓝ' => 'n', - 'ⓞ' => 'o', - 'ⓟ' => 'p', - 'ⓠ' => 'q', - 'ⓡ' => 'r', - 'ⓢ' => 's', - 'ⓣ' => 't', - 'ⓤ' => 'u', - 'ⓥ' => 'v', - 'ⓦ' => 'w', - 'ⓧ' => 'x', - 'ⓨ' => 'y', - 'ⓩ' => 'z', - '⓪' => '0', - '⨌' => '∫∫∫∫', - '⩴' => '::=', - '⩵' => '==', - '⩶' => '===', - 'ⱼ' => 'j', - 'ⱽ' => 'V', - 'ⵯ' => 'ⵡ', - '⺟' => '母', - '⻳' => '龟', - '⼀' => '一', - '⼁' => '丨', - '⼂' => '丶', - '⼃' => '丿', - '⼄' => '乙', - '⼅' => '亅', - '⼆' => '二', - '⼇' => '亠', - '⼈' => '人', - '⼉' => '儿', - '⼊' => '入', - '⼋' => '八', - '⼌' => '冂', - '⼍' => '冖', - '⼎' => '冫', - '⼏' => '几', - '⼐' => '凵', - '⼑' => '刀', - '⼒' => '力', - '⼓' => '勹', - '⼔' => '匕', - '⼕' => '匚', - '⼖' => '匸', - '⼗' => '十', - '⼘' => '卜', - '⼙' => '卩', - '⼚' => '厂', - '⼛' => '厶', - '⼜' => '又', - '⼝' => '口', - '⼞' => '囗', - '⼟' => '土', - '⼠' => '士', - '⼡' => '夂', - '⼢' => '夊', - '⼣' => '夕', - '⼤' => '大', - '⼥' => '女', - '⼦' => '子', - '⼧' => '宀', - '⼨' => '寸', - '⼩' => '小', - '⼪' => '尢', - '⼫' => '尸', - '⼬' => '屮', - '⼭' => '山', - '⼮' => '巛', - '⼯' => '工', - '⼰' => '己', - '⼱' => '巾', - '⼲' => '干', - '⼳' => '幺', - '⼴' => '广', - '⼵' => '廴', - '⼶' => '廾', - '⼷' => '弋', - '⼸' => '弓', - '⼹' => '彐', - '⼺' => '彡', - '⼻' => '彳', - '⼼' => '心', - '⼽' => '戈', - '⼾' => '戶', - '⼿' => '手', - '⽀' => '支', - '⽁' => '攴', - '⽂' => '文', - '⽃' => '斗', - '⽄' => '斤', - '⽅' => '方', - '⽆' => '无', - '⽇' => '日', - '⽈' => '曰', - '⽉' => '月', - '⽊' => '木', - '⽋' => '欠', - '⽌' => '止', - '⽍' => '歹', - '⽎' => '殳', - '⽏' => '毋', - '⽐' => '比', - '⽑' => '毛', - '⽒' => '氏', - '⽓' => '气', - '⽔' => '水', - '⽕' => '火', - '⽖' => '爪', - '⽗' => '父', - '⽘' => '爻', - '⽙' => '爿', - '⽚' => '片', - '⽛' => '牙', - '⽜' => '牛', - '⽝' => '犬', - '⽞' => '玄', - '⽟' => '玉', - '⽠' => '瓜', - '⽡' => '瓦', - '⽢' => '甘', - '⽣' => '生', - '⽤' => '用', - '⽥' => '田', - '⽦' => '疋', - '⽧' => '疒', - '⽨' => '癶', - '⽩' => '白', - '⽪' => '皮', - '⽫' => '皿', - '⽬' => '目', - '⽭' => '矛', - '⽮' => '矢', - '⽯' => '石', - '⽰' => '示', - '⽱' => '禸', - '⽲' => '禾', - '⽳' => '穴', - '⽴' => '立', - '⽵' => '竹', - '⽶' => '米', - '⽷' => '糸', - '⽸' => '缶', - '⽹' => '网', - '⽺' => '羊', - '⽻' => '羽', - '⽼' => '老', - '⽽' => '而', - '⽾' => '耒', - '⽿' => '耳', - '⾀' => '聿', - '⾁' => '肉', - '⾂' => '臣', - '⾃' => '自', - '⾄' => '至', - '⾅' => '臼', - '⾆' => '舌', - '⾇' => '舛', - '⾈' => '舟', - '⾉' => '艮', - '⾊' => '色', - '⾋' => '艸', - '⾌' => '虍', - '⾍' => '虫', - '⾎' => '血', - '⾏' => '行', - '⾐' => '衣', - '⾑' => '襾', - '⾒' => '見', - '⾓' => '角', - '⾔' => '言', - '⾕' => '谷', - '⾖' => '豆', - '⾗' => '豕', - '⾘' => '豸', - '⾙' => '貝', - '⾚' => '赤', - '⾛' => '走', - '⾜' => '足', - '⾝' => '身', - '⾞' => '車', - '⾟' => '辛', - '⾠' => '辰', - '⾡' => '辵', - '⾢' => '邑', - '⾣' => '酉', - '⾤' => '釆', - '⾥' => '里', - '⾦' => '金', - '⾧' => '長', - '⾨' => '門', - '⾩' => '阜', - '⾪' => '隶', - '⾫' => '隹', - '⾬' => '雨', - '⾭' => '靑', - '⾮' => '非', - '⾯' => '面', - '⾰' => '革', - '⾱' => '韋', - '⾲' => '韭', - '⾳' => '音', - '⾴' => '頁', - '⾵' => '風', - '⾶' => '飛', - '⾷' => '食', - '⾸' => '首', - '⾹' => '香', - '⾺' => '馬', - '⾻' => '骨', - '⾼' => '高', - '⾽' => '髟', - '⾾' => '鬥', - '⾿' => '鬯', - '⿀' => '鬲', - '⿁' => '鬼', - '⿂' => '魚', - '⿃' => '鳥', - '⿄' => '鹵', - '⿅' => '鹿', - '⿆' => '麥', - '⿇' => '麻', - '⿈' => '黃', - '⿉' => '黍', - '⿊' => '黑', - '⿋' => '黹', - '⿌' => '黽', - '⿍' => '鼎', - '⿎' => '鼓', - '⿏' => '鼠', - '⿐' => '鼻', - '⿑' => '齊', - '⿒' => '齒', - '⿓' => '龍', - '⿔' => '龜', - '⿕' => '龠', - ' ' => ' ', - '〶' => '〒', - '〸' => '十', - '〹' => '卄', - '〺' => '卅', - '゛' => ' ゙', - '゜' => ' ゚', - 'ゟ' => 'より', - 'ヿ' => 'コト', - 'ㄱ' => 'ᄀ', - 'ㄲ' => 'ᄁ', - 'ㄳ' => 'ᆪ', - 'ㄴ' => 'ᄂ', - 'ㄵ' => 'ᆬ', - 'ㄶ' => 'ᆭ', - 'ㄷ' => 'ᄃ', - 'ㄸ' => 'ᄄ', - 'ㄹ' => 'ᄅ', - 'ㄺ' => 'ᆰ', - 'ㄻ' => 'ᆱ', - 'ㄼ' => 'ᆲ', - 'ㄽ' => 'ᆳ', - 'ㄾ' => 'ᆴ', - 'ㄿ' => 'ᆵ', - 'ㅀ' => 'ᄚ', - 'ㅁ' => 'ᄆ', - 'ㅂ' => 'ᄇ', - 'ㅃ' => 'ᄈ', - 'ㅄ' => 'ᄡ', - 'ㅅ' => 'ᄉ', - 'ㅆ' => 'ᄊ', - 'ㅇ' => 'ᄋ', - 'ㅈ' => 'ᄌ', - 'ㅉ' => 'ᄍ', - 'ㅊ' => 'ᄎ', - 'ㅋ' => 'ᄏ', - 'ㅌ' => 'ᄐ', - 'ㅍ' => 'ᄑ', - 'ㅎ' => 'ᄒ', - 'ㅏ' => 'ᅡ', - 'ㅐ' => 'ᅢ', - 'ㅑ' => 'ᅣ', - 'ㅒ' => 'ᅤ', - 'ㅓ' => 'ᅥ', - 'ㅔ' => 'ᅦ', - 'ㅕ' => 'ᅧ', - 'ㅖ' => 'ᅨ', - 'ㅗ' => 'ᅩ', - 'ㅘ' => 'ᅪ', - 'ㅙ' => 'ᅫ', - 'ㅚ' => 'ᅬ', - 'ㅛ' => 'ᅭ', - 'ㅜ' => 'ᅮ', - 'ㅝ' => 'ᅯ', - 'ㅞ' => 'ᅰ', - 'ㅟ' => 'ᅱ', - 'ㅠ' => 'ᅲ', - 'ㅡ' => 'ᅳ', - 'ㅢ' => 'ᅴ', - 'ㅣ' => 'ᅵ', - 'ㅤ' => 'ᅠ', - 'ㅥ' => 'ᄔ', - 'ㅦ' => 'ᄕ', - 'ㅧ' => 'ᇇ', - 'ㅨ' => 'ᇈ', - 'ㅩ' => 'ᇌ', - 'ㅪ' => 'ᇎ', - 'ㅫ' => 'ᇓ', - 'ㅬ' => 'ᇗ', - 'ㅭ' => 'ᇙ', - 'ㅮ' => 'ᄜ', - 'ㅯ' => 'ᇝ', - 'ㅰ' => 'ᇟ', - 'ㅱ' => 'ᄝ', - 'ㅲ' => 'ᄞ', - 'ㅳ' => 'ᄠ', - 'ㅴ' => 'ᄢ', - 'ㅵ' => 'ᄣ', - 'ㅶ' => 'ᄧ', - 'ㅷ' => 'ᄩ', - 'ㅸ' => 'ᄫ', - 'ㅹ' => 'ᄬ', - 'ㅺ' => 'ᄭ', - 'ㅻ' => 'ᄮ', - 'ㅼ' => 'ᄯ', - 'ㅽ' => 'ᄲ', - 'ㅾ' => 'ᄶ', - 'ㅿ' => 'ᅀ', - 'ㆀ' => 'ᅇ', - 'ㆁ' => 'ᅌ', - 'ㆂ' => 'ᇱ', - 'ㆃ' => 'ᇲ', - 'ㆄ' => 'ᅗ', - 'ㆅ' => 'ᅘ', - 'ㆆ' => 'ᅙ', - 'ㆇ' => 'ᆄ', - 'ㆈ' => 'ᆅ', - 'ㆉ' => 'ᆈ', - 'ㆊ' => 'ᆑ', - 'ㆋ' => 'ᆒ', - 'ㆌ' => 'ᆔ', - 'ㆍ' => 'ᆞ', - 'ㆎ' => 'ᆡ', - '㆒' => '一', - '㆓' => '二', - '㆔' => '三', - '㆕' => '四', - '㆖' => '上', - '㆗' => '中', - '㆘' => '下', - '㆙' => '甲', - '㆚' => '乙', - '㆛' => '丙', - '㆜' => '丁', - '㆝' => '天', - '㆞' => '地', - '㆟' => '人', - '㈀' => '(ᄀ)', - '㈁' => '(ᄂ)', - '㈂' => '(ᄃ)', - '㈃' => '(ᄅ)', - '㈄' => '(ᄆ)', - '㈅' => '(ᄇ)', - '㈆' => '(ᄉ)', - '㈇' => '(ᄋ)', - '㈈' => '(ᄌ)', - '㈉' => '(ᄎ)', - '㈊' => '(ᄏ)', - '㈋' => '(ᄐ)', - '㈌' => '(ᄑ)', - '㈍' => '(ᄒ)', - '㈎' => '(가)', - '㈏' => '(나)', - '㈐' => '(다)', - '㈑' => '(라)', - '㈒' => '(마)', - '㈓' => '(바)', - '㈔' => '(사)', - '㈕' => '(아)', - '㈖' => '(자)', - '㈗' => '(차)', - '㈘' => '(카)', - '㈙' => '(타)', - '㈚' => '(파)', - '㈛' => '(하)', - '㈜' => '(주)', - '㈝' => '(오전)', - '㈞' => '(오후)', - '㈠' => '(一)', - '㈡' => '(二)', - '㈢' => '(三)', - '㈣' => '(四)', - '㈤' => '(五)', - '㈥' => '(六)', - '㈦' => '(七)', - '㈧' => '(八)', - '㈨' => '(九)', - '㈩' => '(十)', - '㈪' => '(月)', - '㈫' => '(火)', - '㈬' => '(水)', - '㈭' => '(木)', - '㈮' => '(金)', - '㈯' => '(土)', - '㈰' => '(日)', - '㈱' => '(株)', - '㈲' => '(有)', - '㈳' => '(社)', - '㈴' => '(名)', - '㈵' => '(特)', - '㈶' => '(財)', - '㈷' => '(祝)', - '㈸' => '(労)', - '㈹' => '(代)', - '㈺' => '(呼)', - '㈻' => '(学)', - '㈼' => '(監)', - '㈽' => '(企)', - '㈾' => '(資)', - '㈿' => '(協)', - '㉀' => '(祭)', - '㉁' => '(休)', - '㉂' => '(自)', - '㉃' => '(至)', - '㉄' => '問', - '㉅' => '幼', - '㉆' => '文', - '㉇' => '箏', - '㉐' => 'PTE', - '㉑' => '21', - '㉒' => '22', - '㉓' => '23', - '㉔' => '24', - '㉕' => '25', - '㉖' => '26', - '㉗' => '27', - '㉘' => '28', - '㉙' => '29', - '㉚' => '30', - '㉛' => '31', - '㉜' => '32', - '㉝' => '33', - '㉞' => '34', - '㉟' => '35', - '㉠' => 'ᄀ', - '㉡' => 'ᄂ', - '㉢' => 'ᄃ', - '㉣' => 'ᄅ', - '㉤' => 'ᄆ', - '㉥' => 'ᄇ', - '㉦' => 'ᄉ', - '㉧' => 'ᄋ', - '㉨' => 'ᄌ', - '㉩' => 'ᄎ', - '㉪' => 'ᄏ', - '㉫' => 'ᄐ', - '㉬' => 'ᄑ', - '㉭' => 'ᄒ', - '㉮' => '가', - '㉯' => '나', - '㉰' => '다', - '㉱' => '라', - '㉲' => '마', - '㉳' => '바', - '㉴' => '사', - '㉵' => '아', - '㉶' => '자', - '㉷' => '차', - '㉸' => '카', - '㉹' => '타', - '㉺' => '파', - '㉻' => '하', - '㉼' => '참고', - '㉽' => '주의', - '㉾' => '우', - '㊀' => '一', - '㊁' => '二', - '㊂' => '三', - '㊃' => '四', - '㊄' => '五', - '㊅' => '六', - '㊆' => '七', - '㊇' => '八', - '㊈' => '九', - '㊉' => '十', - '㊊' => '月', - '㊋' => '火', - '㊌' => '水', - '㊍' => '木', - '㊎' => '金', - '㊏' => '土', - '㊐' => '日', - '㊑' => '株', - '㊒' => '有', - '㊓' => '社', - '㊔' => '名', - '㊕' => '特', - '㊖' => '財', - '㊗' => '祝', - '㊘' => '労', - '㊙' => '秘', - '㊚' => '男', - '㊛' => '女', - '㊜' => '適', - '㊝' => '優', - '㊞' => '印', - '㊟' => '注', - '㊠' => '項', - '㊡' => '休', - '㊢' => '写', - '㊣' => '正', - '㊤' => '上', - '㊥' => '中', - '㊦' => '下', - '㊧' => '左', - '㊨' => '右', - '㊩' => '医', - '㊪' => '宗', - '㊫' => '学', - '㊬' => '監', - '㊭' => '企', - '㊮' => '資', - '㊯' => '協', - '㊰' => '夜', - '㊱' => '36', - '㊲' => '37', - '㊳' => '38', - '㊴' => '39', - '㊵' => '40', - '㊶' => '41', - '㊷' => '42', - '㊸' => '43', - '㊹' => '44', - '㊺' => '45', - '㊻' => '46', - '㊼' => '47', - '㊽' => '48', - '㊾' => '49', - '㊿' => '50', - '㋀' => '1月', - '㋁' => '2月', - '㋂' => '3月', - '㋃' => '4月', - '㋄' => '5月', - '㋅' => '6月', - '㋆' => '7月', - '㋇' => '8月', - '㋈' => '9月', - '㋉' => '10月', - '㋊' => '11月', - '㋋' => '12月', - '㋌' => 'Hg', - '㋍' => 'erg', - '㋎' => 'eV', - '㋏' => 'LTD', - '㋐' => 'ア', - '㋑' => 'イ', - '㋒' => 'ウ', - '㋓' => 'エ', - '㋔' => 'オ', - '㋕' => 'カ', - '㋖' => 'キ', - '㋗' => 'ク', - '㋘' => 'ケ', - '㋙' => 'コ', - '㋚' => 'サ', - '㋛' => 'シ', - '㋜' => 'ス', - '㋝' => 'セ', - '㋞' => 'ソ', - '㋟' => 'タ', - '㋠' => 'チ', - '㋡' => 'ツ', - '㋢' => 'テ', - '㋣' => 'ト', - '㋤' => 'ナ', - '㋥' => 'ニ', - '㋦' => 'ヌ', - '㋧' => 'ネ', - '㋨' => 'ノ', - '㋩' => 'ハ', - '㋪' => 'ヒ', - '㋫' => 'フ', - '㋬' => 'ヘ', - '㋭' => 'ホ', - '㋮' => 'マ', - '㋯' => 'ミ', - '㋰' => 'ム', - '㋱' => 'メ', - '㋲' => 'モ', - '㋳' => 'ヤ', - '㋴' => 'ユ', - '㋵' => 'ヨ', - '㋶' => 'ラ', - '㋷' => 'リ', - '㋸' => 'ル', - '㋹' => 'レ', - '㋺' => 'ロ', - '㋻' => 'ワ', - '㋼' => 'ヰ', - '㋽' => 'ヱ', - '㋾' => 'ヲ', - '㋿' => '令和', - '㌀' => 'アパート', - '㌁' => 'アルファ', - '㌂' => 'アンペア', - '㌃' => 'アール', - '㌄' => 'イニング', - '㌅' => 'インチ', - '㌆' => 'ウォン', - '㌇' => 'エスクード', - '㌈' => 'エーカー', - '㌉' => 'オンス', - '㌊' => 'オーム', - '㌋' => 'カイリ', - '㌌' => 'カラット', - '㌍' => 'カロリー', - '㌎' => 'ガロン', - '㌏' => 'ガンマ', - '㌐' => 'ギガ', - '㌑' => 'ギニー', - '㌒' => 'キュリー', - '㌓' => 'ギルダー', - '㌔' => 'キロ', - '㌕' => 'キログラム', - '㌖' => 'キロメートル', - '㌗' => 'キロワット', - '㌘' => 'グラム', - '㌙' => 'グラムトン', - '㌚' => 'クルゼイロ', - '㌛' => 'クローネ', - '㌜' => 'ケース', - '㌝' => 'コルナ', - '㌞' => 'コーポ', - '㌟' => 'サイクル', - '㌠' => 'サンチーム', - '㌡' => 'シリング', - '㌢' => 'センチ', - '㌣' => 'セント', - '㌤' => 'ダース', - '㌥' => 'デシ', - '㌦' => 'ドル', - '㌧' => 'トン', - '㌨' => 'ナノ', - '㌩' => 'ノット', - '㌪' => 'ハイツ', - '㌫' => 'パーセント', - '㌬' => 'パーツ', - '㌭' => 'バーレル', - '㌮' => 'ピアストル', - '㌯' => 'ピクル', - '㌰' => 'ピコ', - '㌱' => 'ビル', - '㌲' => 'ファラッド', - '㌳' => 'フィート', - '㌴' => 'ブッシェル', - '㌵' => 'フラン', - '㌶' => 'ヘクタール', - '㌷' => 'ペソ', - '㌸' => 'ペニヒ', - '㌹' => 'ヘルツ', - '㌺' => 'ペンス', - '㌻' => 'ページ', - '㌼' => 'ベータ', - '㌽' => 'ポイント', - '㌾' => 'ボルト', - '㌿' => 'ホン', - '㍀' => 'ポンド', - '㍁' => 'ホール', - '㍂' => 'ホーン', - '㍃' => 'マイクロ', - '㍄' => 'マイル', - '㍅' => 'マッハ', - '㍆' => 'マルク', - '㍇' => 'マンション', - '㍈' => 'ミクロン', - '㍉' => 'ミリ', - '㍊' => 'ミリバール', - '㍋' => 'メガ', - '㍌' => 'メガトン', - '㍍' => 'メートル', - '㍎' => 'ヤード', - '㍏' => 'ヤール', - '㍐' => 'ユアン', - '㍑' => 'リットル', - '㍒' => 'リラ', - '㍓' => 'ルピー', - '㍔' => 'ルーブル', - '㍕' => 'レム', - '㍖' => 'レントゲン', - '㍗' => 'ワット', - '㍘' => '0点', - '㍙' => '1点', - '㍚' => '2点', - '㍛' => '3点', - '㍜' => '4点', - '㍝' => '5点', - '㍞' => '6点', - '㍟' => '7点', - '㍠' => '8点', - '㍡' => '9点', - '㍢' => '10点', - '㍣' => '11点', - '㍤' => '12点', - '㍥' => '13点', - '㍦' => '14点', - '㍧' => '15点', - '㍨' => '16点', - '㍩' => '17点', - '㍪' => '18点', - '㍫' => '19点', - '㍬' => '20点', - '㍭' => '21点', - '㍮' => '22点', - '㍯' => '23点', - '㍰' => '24点', - '㍱' => 'hPa', - '㍲' => 'da', - '㍳' => 'AU', - '㍴' => 'bar', - '㍵' => 'oV', - '㍶' => 'pc', - '㍷' => 'dm', - '㍸' => 'dm2', - '㍹' => 'dm3', - '㍺' => 'IU', - '㍻' => '平成', - '㍼' => '昭和', - '㍽' => '大正', - '㍾' => '明治', - '㍿' => '株式会社', - '㎀' => 'pA', - '㎁' => 'nA', - '㎂' => 'μA', - '㎃' => 'mA', - '㎄' => 'kA', - '㎅' => 'KB', - '㎆' => 'MB', - '㎇' => 'GB', - '㎈' => 'cal', - '㎉' => 'kcal', - '㎊' => 'pF', - '㎋' => 'nF', - '㎌' => 'μF', - '㎍' => 'μg', - '㎎' => 'mg', - '㎏' => 'kg', - '㎐' => 'Hz', - '㎑' => 'kHz', - '㎒' => 'MHz', - '㎓' => 'GHz', - '㎔' => 'THz', - '㎕' => 'μl', - '㎖' => 'ml', - '㎗' => 'dl', - '㎘' => 'kl', - '㎙' => 'fm', - '㎚' => 'nm', - '㎛' => 'μm', - '㎜' => 'mm', - '㎝' => 'cm', - '㎞' => 'km', - '㎟' => 'mm2', - '㎠' => 'cm2', - '㎡' => 'm2', - '㎢' => 'km2', - '㎣' => 'mm3', - '㎤' => 'cm3', - '㎥' => 'm3', - '㎦' => 'km3', - '㎧' => 'm∕s', - '㎨' => 'm∕s2', - '㎩' => 'Pa', - '㎪' => 'kPa', - '㎫' => 'MPa', - '㎬' => 'GPa', - '㎭' => 'rad', - '㎮' => 'rad∕s', - '㎯' => 'rad∕s2', - '㎰' => 'ps', - '㎱' => 'ns', - '㎲' => 'μs', - '㎳' => 'ms', - '㎴' => 'pV', - '㎵' => 'nV', - '㎶' => 'μV', - '㎷' => 'mV', - '㎸' => 'kV', - '㎹' => 'MV', - '㎺' => 'pW', - '㎻' => 'nW', - '㎼' => 'μW', - '㎽' => 'mW', - '㎾' => 'kW', - '㎿' => 'MW', - '㏀' => 'kΩ', - '㏁' => 'MΩ', - '㏂' => 'a.m.', - '㏃' => 'Bq', - '㏄' => 'cc', - '㏅' => 'cd', - '㏆' => 'C∕kg', - '㏇' => 'Co.', - '㏈' => 'dB', - '㏉' => 'Gy', - '㏊' => 'ha', - '㏋' => 'HP', - '㏌' => 'in', - '㏍' => 'KK', - '㏎' => 'KM', - '㏏' => 'kt', - '㏐' => 'lm', - '㏑' => 'ln', - '㏒' => 'log', - '㏓' => 'lx', - '㏔' => 'mb', - '㏕' => 'mil', - '㏖' => 'mol', - '㏗' => 'PH', - '㏘' => 'p.m.', - '㏙' => 'PPM', - '㏚' => 'PR', - '㏛' => 'sr', - '㏜' => 'Sv', - '㏝' => 'Wb', - '㏞' => 'V∕m', - '㏟' => 'A∕m', - '㏠' => '1日', - '㏡' => '2日', - '㏢' => '3日', - '㏣' => '4日', - '㏤' => '5日', - '㏥' => '6日', - '㏦' => '7日', - '㏧' => '8日', - '㏨' => '9日', - '㏩' => '10日', - '㏪' => '11日', - '㏫' => '12日', - '㏬' => '13日', - '㏭' => '14日', - '㏮' => '15日', - '㏯' => '16日', - '㏰' => '17日', - '㏱' => '18日', - '㏲' => '19日', - '㏳' => '20日', - '㏴' => '21日', - '㏵' => '22日', - '㏶' => '23日', - '㏷' => '24日', - '㏸' => '25日', - '㏹' => '26日', - '㏺' => '27日', - '㏻' => '28日', - '㏼' => '29日', - '㏽' => '30日', - '㏾' => '31日', - '㏿' => 'gal', - 'ꚜ' => 'ъ', - 'ꚝ' => 'ь', - 'ꝰ' => 'ꝯ', - 'ꟸ' => 'Ħ', - 'ꟹ' => 'œ', - 'ꭜ' => 'ꜧ', - 'ꭝ' => 'ꬷ', - 'ꭞ' => 'ɫ', - 'ꭟ' => 'ꭒ', - 'ꭩ' => 'ʍ', - 'ff' => 'ff', - 'fi' => 'fi', - 'fl' => 'fl', - 'ffi' => 'ffi', - 'ffl' => 'ffl', - 'ſt' => 'st', - 'st' => 'st', - 'ﬓ' => 'մն', - 'ﬔ' => 'մե', - 'ﬕ' => 'մի', - 'ﬖ' => 'վն', - 'ﬗ' => 'մխ', - 'ﬠ' => 'ע', - 'ﬡ' => 'א', - 'ﬢ' => 'ד', - 'ﬣ' => 'ה', - 'ﬤ' => 'כ', - 'ﬥ' => 'ל', - 'ﬦ' => 'ם', - 'ﬧ' => 'ר', - 'ﬨ' => 'ת', - '﬩' => '+', - 'ﭏ' => 'אל', - 'ﭐ' => 'ٱ', - 'ﭑ' => 'ٱ', - 'ﭒ' => 'ٻ', - 'ﭓ' => 'ٻ', - 'ﭔ' => 'ٻ', - 'ﭕ' => 'ٻ', - 'ﭖ' => 'پ', - 'ﭗ' => 'پ', - 'ﭘ' => 'پ', - 'ﭙ' => 'پ', - 'ﭚ' => 'ڀ', - 'ﭛ' => 'ڀ', - 'ﭜ' => 'ڀ', - 'ﭝ' => 'ڀ', - 'ﭞ' => 'ٺ', - 'ﭟ' => 'ٺ', - 'ﭠ' => 'ٺ', - 'ﭡ' => 'ٺ', - 'ﭢ' => 'ٿ', - 'ﭣ' => 'ٿ', - 'ﭤ' => 'ٿ', - 'ﭥ' => 'ٿ', - 'ﭦ' => 'ٹ', - 'ﭧ' => 'ٹ', - 'ﭨ' => 'ٹ', - 'ﭩ' => 'ٹ', - 'ﭪ' => 'ڤ', - 'ﭫ' => 'ڤ', - 'ﭬ' => 'ڤ', - 'ﭭ' => 'ڤ', - 'ﭮ' => 'ڦ', - 'ﭯ' => 'ڦ', - 'ﭰ' => 'ڦ', - 'ﭱ' => 'ڦ', - 'ﭲ' => 'ڄ', - 'ﭳ' => 'ڄ', - 'ﭴ' => 'ڄ', - 'ﭵ' => 'ڄ', - 'ﭶ' => 'ڃ', - 'ﭷ' => 'ڃ', - 'ﭸ' => 'ڃ', - 'ﭹ' => 'ڃ', - 'ﭺ' => 'چ', - 'ﭻ' => 'چ', - 'ﭼ' => 'چ', - 'ﭽ' => 'چ', - 'ﭾ' => 'ڇ', - 'ﭿ' => 'ڇ', - 'ﮀ' => 'ڇ', - 'ﮁ' => 'ڇ', - 'ﮂ' => 'ڍ', - 'ﮃ' => 'ڍ', - 'ﮄ' => 'ڌ', - 'ﮅ' => 'ڌ', - 'ﮆ' => 'ڎ', - 'ﮇ' => 'ڎ', - 'ﮈ' => 'ڈ', - 'ﮉ' => 'ڈ', - 'ﮊ' => 'ژ', - 'ﮋ' => 'ژ', - 'ﮌ' => 'ڑ', - 'ﮍ' => 'ڑ', - 'ﮎ' => 'ک', - 'ﮏ' => 'ک', - 'ﮐ' => 'ک', - 'ﮑ' => 'ک', - 'ﮒ' => 'گ', - 'ﮓ' => 'گ', - 'ﮔ' => 'گ', - 'ﮕ' => 'گ', - 'ﮖ' => 'ڳ', - 'ﮗ' => 'ڳ', - 'ﮘ' => 'ڳ', - 'ﮙ' => 'ڳ', - 'ﮚ' => 'ڱ', - 'ﮛ' => 'ڱ', - 'ﮜ' => 'ڱ', - 'ﮝ' => 'ڱ', - 'ﮞ' => 'ں', - 'ﮟ' => 'ں', - 'ﮠ' => 'ڻ', - 'ﮡ' => 'ڻ', - 'ﮢ' => 'ڻ', - 'ﮣ' => 'ڻ', - 'ﮤ' => 'ۀ', - 'ﮥ' => 'ۀ', - 'ﮦ' => 'ہ', - 'ﮧ' => 'ہ', - 'ﮨ' => 'ہ', - 'ﮩ' => 'ہ', - 'ﮪ' => 'ھ', - 'ﮫ' => 'ھ', - 'ﮬ' => 'ھ', - 'ﮭ' => 'ھ', - 'ﮮ' => 'ے', - 'ﮯ' => 'ے', - 'ﮰ' => 'ۓ', - 'ﮱ' => 'ۓ', - 'ﯓ' => 'ڭ', - 'ﯔ' => 'ڭ', - 'ﯕ' => 'ڭ', - 'ﯖ' => 'ڭ', - 'ﯗ' => 'ۇ', - 'ﯘ' => 'ۇ', - 'ﯙ' => 'ۆ', - 'ﯚ' => 'ۆ', - 'ﯛ' => 'ۈ', - 'ﯜ' => 'ۈ', - 'ﯝ' => 'ۇٴ', - 'ﯞ' => 'ۋ', - 'ﯟ' => 'ۋ', - 'ﯠ' => 'ۅ', - 'ﯡ' => 'ۅ', - 'ﯢ' => 'ۉ', - 'ﯣ' => 'ۉ', - 'ﯤ' => 'ې', - 'ﯥ' => 'ې', - 'ﯦ' => 'ې', - 'ﯧ' => 'ې', - 'ﯨ' => 'ى', - 'ﯩ' => 'ى', - 'ﯪ' => 'ئا', - 'ﯫ' => 'ئا', - 'ﯬ' => 'ئە', - 'ﯭ' => 'ئە', - 'ﯮ' => 'ئو', - 'ﯯ' => 'ئو', - 'ﯰ' => 'ئۇ', - 'ﯱ' => 'ئۇ', - 'ﯲ' => 'ئۆ', - 'ﯳ' => 'ئۆ', - 'ﯴ' => 'ئۈ', - 'ﯵ' => 'ئۈ', - 'ﯶ' => 'ئې', - 'ﯷ' => 'ئې', - 'ﯸ' => 'ئې', - 'ﯹ' => 'ئى', - 'ﯺ' => 'ئى', - 'ﯻ' => 'ئى', - 'ﯼ' => 'ی', - 'ﯽ' => 'ی', - 'ﯾ' => 'ی', - 'ﯿ' => 'ی', - 'ﰀ' => 'ئج', - 'ﰁ' => 'ئح', - 'ﰂ' => 'ئم', - 'ﰃ' => 'ئى', - 'ﰄ' => 'ئي', - 'ﰅ' => 'بج', - 'ﰆ' => 'بح', - 'ﰇ' => 'بخ', - 'ﰈ' => 'بم', - 'ﰉ' => 'بى', - 'ﰊ' => 'بي', - 'ﰋ' => 'تج', - 'ﰌ' => 'تح', - 'ﰍ' => 'تخ', - 'ﰎ' => 'تم', - 'ﰏ' => 'تى', - 'ﰐ' => 'تي', - 'ﰑ' => 'ثج', - 'ﰒ' => 'ثم', - 'ﰓ' => 'ثى', - 'ﰔ' => 'ثي', - 'ﰕ' => 'جح', - 'ﰖ' => 'جم', - 'ﰗ' => 'حج', - 'ﰘ' => 'حم', - 'ﰙ' => 'خج', - 'ﰚ' => 'خح', - 'ﰛ' => 'خم', - 'ﰜ' => 'سج', - 'ﰝ' => 'سح', - 'ﰞ' => 'سخ', - 'ﰟ' => 'سم', - 'ﰠ' => 'صح', - 'ﰡ' => 'صم', - 'ﰢ' => 'ضج', - 'ﰣ' => 'ضح', - 'ﰤ' => 'ضخ', - 'ﰥ' => 'ضم', - 'ﰦ' => 'طح', - 'ﰧ' => 'طم', - 'ﰨ' => 'ظم', - 'ﰩ' => 'عج', - 'ﰪ' => 'عم', - 'ﰫ' => 'غج', - 'ﰬ' => 'غم', - 'ﰭ' => 'فج', - 'ﰮ' => 'فح', - 'ﰯ' => 'فخ', - 'ﰰ' => 'فم', - 'ﰱ' => 'فى', - 'ﰲ' => 'في', - 'ﰳ' => 'قح', - 'ﰴ' => 'قم', - 'ﰵ' => 'قى', - 'ﰶ' => 'قي', - 'ﰷ' => 'كا', - 'ﰸ' => 'كج', - 'ﰹ' => 'كح', - 'ﰺ' => 'كخ', - 'ﰻ' => 'كل', - 'ﰼ' => 'كم', - 'ﰽ' => 'كى', - 'ﰾ' => 'كي', - 'ﰿ' => 'لج', - 'ﱀ' => 'لح', - 'ﱁ' => 'لخ', - 'ﱂ' => 'لم', - 'ﱃ' => 'لى', - 'ﱄ' => 'لي', - 'ﱅ' => 'مج', - 'ﱆ' => 'مح', - 'ﱇ' => 'مخ', - 'ﱈ' => 'مم', - 'ﱉ' => 'مى', - 'ﱊ' => 'مي', - 'ﱋ' => 'نج', - 'ﱌ' => 'نح', - 'ﱍ' => 'نخ', - 'ﱎ' => 'نم', - 'ﱏ' => 'نى', - 'ﱐ' => 'ني', - 'ﱑ' => 'هج', - 'ﱒ' => 'هم', - 'ﱓ' => 'هى', - 'ﱔ' => 'هي', - 'ﱕ' => 'يج', - 'ﱖ' => 'يح', - 'ﱗ' => 'يخ', - 'ﱘ' => 'يم', - 'ﱙ' => 'يى', - 'ﱚ' => 'يي', - 'ﱛ' => 'ذٰ', - 'ﱜ' => 'رٰ', - 'ﱝ' => 'ىٰ', - 'ﱞ' => ' ٌّ', - 'ﱟ' => ' ٍّ', - 'ﱠ' => ' َّ', - 'ﱡ' => ' ُّ', - 'ﱢ' => ' ِّ', - 'ﱣ' => ' ّٰ', - 'ﱤ' => 'ئر', - 'ﱥ' => 'ئز', - 'ﱦ' => 'ئم', - 'ﱧ' => 'ئن', - 'ﱨ' => 'ئى', - 'ﱩ' => 'ئي', - 'ﱪ' => 'بر', - 'ﱫ' => 'بز', - 'ﱬ' => 'بم', - 'ﱭ' => 'بن', - 'ﱮ' => 'بى', - 'ﱯ' => 'بي', - 'ﱰ' => 'تر', - 'ﱱ' => 'تز', - 'ﱲ' => 'تم', - 'ﱳ' => 'تن', - 'ﱴ' => 'تى', - 'ﱵ' => 'تي', - 'ﱶ' => 'ثر', - 'ﱷ' => 'ثز', - 'ﱸ' => 'ثم', - 'ﱹ' => 'ثن', - 'ﱺ' => 'ثى', - 'ﱻ' => 'ثي', - 'ﱼ' => 'فى', - 'ﱽ' => 'في', - 'ﱾ' => 'قى', - 'ﱿ' => 'قي', - 'ﲀ' => 'كا', - 'ﲁ' => 'كل', - 'ﲂ' => 'كم', - 'ﲃ' => 'كى', - 'ﲄ' => 'كي', - 'ﲅ' => 'لم', - 'ﲆ' => 'لى', - 'ﲇ' => 'لي', - 'ﲈ' => 'ما', - 'ﲉ' => 'مم', - 'ﲊ' => 'نر', - 'ﲋ' => 'نز', - 'ﲌ' => 'نم', - 'ﲍ' => 'نن', - 'ﲎ' => 'نى', - 'ﲏ' => 'ني', - 'ﲐ' => 'ىٰ', - 'ﲑ' => 'ير', - 'ﲒ' => 'يز', - 'ﲓ' => 'يم', - 'ﲔ' => 'ين', - 'ﲕ' => 'يى', - 'ﲖ' => 'يي', - 'ﲗ' => 'ئج', - 'ﲘ' => 'ئح', - 'ﲙ' => 'ئخ', - 'ﲚ' => 'ئم', - 'ﲛ' => 'ئه', - 'ﲜ' => 'بج', - 'ﲝ' => 'بح', - 'ﲞ' => 'بخ', - 'ﲟ' => 'بم', - 'ﲠ' => 'به', - 'ﲡ' => 'تج', - 'ﲢ' => 'تح', - 'ﲣ' => 'تخ', - 'ﲤ' => 'تم', - 'ﲥ' => 'ته', - 'ﲦ' => 'ثم', - 'ﲧ' => 'جح', - 'ﲨ' => 'جم', - 'ﲩ' => 'حج', - 'ﲪ' => 'حم', - 'ﲫ' => 'خج', - 'ﲬ' => 'خم', - 'ﲭ' => 'سج', - 'ﲮ' => 'سح', - 'ﲯ' => 'سخ', - 'ﲰ' => 'سم', - 'ﲱ' => 'صح', - 'ﲲ' => 'صخ', - 'ﲳ' => 'صم', - 'ﲴ' => 'ضج', - 'ﲵ' => 'ضح', - 'ﲶ' => 'ضخ', - 'ﲷ' => 'ضم', - 'ﲸ' => 'طح', - 'ﲹ' => 'ظم', - 'ﲺ' => 'عج', - 'ﲻ' => 'عم', - 'ﲼ' => 'غج', - 'ﲽ' => 'غم', - 'ﲾ' => 'فج', - 'ﲿ' => 'فح', - 'ﳀ' => 'فخ', - 'ﳁ' => 'فم', - 'ﳂ' => 'قح', - 'ﳃ' => 'قم', - 'ﳄ' => 'كج', - 'ﳅ' => 'كح', - 'ﳆ' => 'كخ', - 'ﳇ' => 'كل', - 'ﳈ' => 'كم', - 'ﳉ' => 'لج', - 'ﳊ' => 'لح', - 'ﳋ' => 'لخ', - 'ﳌ' => 'لم', - 'ﳍ' => 'له', - 'ﳎ' => 'مج', - 'ﳏ' => 'مح', - 'ﳐ' => 'مخ', - 'ﳑ' => 'مم', - 'ﳒ' => 'نج', - 'ﳓ' => 'نح', - 'ﳔ' => 'نخ', - 'ﳕ' => 'نم', - 'ﳖ' => 'نه', - 'ﳗ' => 'هج', - 'ﳘ' => 'هم', - 'ﳙ' => 'هٰ', - 'ﳚ' => 'يج', - 'ﳛ' => 'يح', - 'ﳜ' => 'يخ', - 'ﳝ' => 'يم', - 'ﳞ' => 'يه', - 'ﳟ' => 'ئم', - 'ﳠ' => 'ئه', - 'ﳡ' => 'بم', - 'ﳢ' => 'به', - 'ﳣ' => 'تم', - 'ﳤ' => 'ته', - 'ﳥ' => 'ثم', - 'ﳦ' => 'ثه', - 'ﳧ' => 'سم', - 'ﳨ' => 'سه', - 'ﳩ' => 'شم', - 'ﳪ' => 'شه', - 'ﳫ' => 'كل', - 'ﳬ' => 'كم', - 'ﳭ' => 'لم', - 'ﳮ' => 'نم', - 'ﳯ' => 'نه', - 'ﳰ' => 'يم', - 'ﳱ' => 'يه', - 'ﳲ' => 'ـَّ', - 'ﳳ' => 'ـُّ', - 'ﳴ' => 'ـِّ', - 'ﳵ' => 'طى', - 'ﳶ' => 'طي', - 'ﳷ' => 'عى', - 'ﳸ' => 'عي', - 'ﳹ' => 'غى', - 'ﳺ' => 'غي', - 'ﳻ' => 'سى', - 'ﳼ' => 'سي', - 'ﳽ' => 'شى', - 'ﳾ' => 'شي', - 'ﳿ' => 'حى', - 'ﴀ' => 'حي', - 'ﴁ' => 'جى', - 'ﴂ' => 'جي', - 'ﴃ' => 'خى', - 'ﴄ' => 'خي', - 'ﴅ' => 'صى', - 'ﴆ' => 'صي', - 'ﴇ' => 'ضى', - 'ﴈ' => 'ضي', - 'ﴉ' => 'شج', - 'ﴊ' => 'شح', - 'ﴋ' => 'شخ', - 'ﴌ' => 'شم', - 'ﴍ' => 'شر', - 'ﴎ' => 'سر', - 'ﴏ' => 'صر', - 'ﴐ' => 'ضر', - 'ﴑ' => 'طى', - 'ﴒ' => 'طي', - 'ﴓ' => 'عى', - 'ﴔ' => 'عي', - 'ﴕ' => 'غى', - 'ﴖ' => 'غي', - 'ﴗ' => 'سى', - 'ﴘ' => 'سي', - 'ﴙ' => 'شى', - 'ﴚ' => 'شي', - 'ﴛ' => 'حى', - 'ﴜ' => 'حي', - 'ﴝ' => 'جى', - 'ﴞ' => 'جي', - 'ﴟ' => 'خى', - 'ﴠ' => 'خي', - 'ﴡ' => 'صى', - 'ﴢ' => 'صي', - 'ﴣ' => 'ضى', - 'ﴤ' => 'ضي', - 'ﴥ' => 'شج', - 'ﴦ' => 'شح', - 'ﴧ' => 'شخ', - 'ﴨ' => 'شم', - 'ﴩ' => 'شر', - 'ﴪ' => 'سر', - 'ﴫ' => 'صر', - 'ﴬ' => 'ضر', - 'ﴭ' => 'شج', - 'ﴮ' => 'شح', - 'ﴯ' => 'شخ', - 'ﴰ' => 'شم', - 'ﴱ' => 'سه', - 'ﴲ' => 'شه', - 'ﴳ' => 'طم', - 'ﴴ' => 'سج', - 'ﴵ' => 'سح', - 'ﴶ' => 'سخ', - 'ﴷ' => 'شج', - 'ﴸ' => 'شح', - 'ﴹ' => 'شخ', - 'ﴺ' => 'طم', - 'ﴻ' => 'ظم', - 'ﴼ' => 'اً', - 'ﴽ' => 'اً', - 'ﵐ' => 'تجم', - 'ﵑ' => 'تحج', - 'ﵒ' => 'تحج', - 'ﵓ' => 'تحم', - 'ﵔ' => 'تخم', - 'ﵕ' => 'تمج', - 'ﵖ' => 'تمح', - 'ﵗ' => 'تمخ', - 'ﵘ' => 'جمح', - 'ﵙ' => 'جمح', - 'ﵚ' => 'حمي', - 'ﵛ' => 'حمى', - 'ﵜ' => 'سحج', - 'ﵝ' => 'سجح', - 'ﵞ' => 'سجى', - 'ﵟ' => 'سمح', - 'ﵠ' => 'سمح', - 'ﵡ' => 'سمج', - 'ﵢ' => 'سمم', - 'ﵣ' => 'سمم', - 'ﵤ' => 'صحح', - 'ﵥ' => 'صحح', - 'ﵦ' => 'صمم', - 'ﵧ' => 'شحم', - 'ﵨ' => 'شحم', - 'ﵩ' => 'شجي', - 'ﵪ' => 'شمخ', - 'ﵫ' => 'شمخ', - 'ﵬ' => 'شمم', - 'ﵭ' => 'شمم', - 'ﵮ' => 'ضحى', - 'ﵯ' => 'ضخم', - 'ﵰ' => 'ضخم', - 'ﵱ' => 'طمح', - 'ﵲ' => 'طمح', - 'ﵳ' => 'طمم', - 'ﵴ' => 'طمي', - 'ﵵ' => 'عجم', - 'ﵶ' => 'عمم', - 'ﵷ' => 'عمم', - 'ﵸ' => 'عمى', - 'ﵹ' => 'غمم', - 'ﵺ' => 'غمي', - 'ﵻ' => 'غمى', - 'ﵼ' => 'فخم', - 'ﵽ' => 'فخم', - 'ﵾ' => 'قمح', - 'ﵿ' => 'قمم', - 'ﶀ' => 'لحم', - 'ﶁ' => 'لحي', - 'ﶂ' => 'لحى', - 'ﶃ' => 'لجج', - 'ﶄ' => 'لجج', - 'ﶅ' => 'لخم', - 'ﶆ' => 'لخم', - 'ﶇ' => 'لمح', - 'ﶈ' => 'لمح', - 'ﶉ' => 'محج', - 'ﶊ' => 'محم', - 'ﶋ' => 'محي', - 'ﶌ' => 'مجح', - 'ﶍ' => 'مجم', - 'ﶎ' => 'مخج', - 'ﶏ' => 'مخم', - 'ﶒ' => 'مجخ', - 'ﶓ' => 'همج', - 'ﶔ' => 'همم', - 'ﶕ' => 'نحم', - 'ﶖ' => 'نحى', - 'ﶗ' => 'نجم', - 'ﶘ' => 'نجم', - 'ﶙ' => 'نجى', - 'ﶚ' => 'نمي', - 'ﶛ' => 'نمى', - 'ﶜ' => 'يمم', - 'ﶝ' => 'يمم', - 'ﶞ' => 'بخي', - 'ﶟ' => 'تجي', - 'ﶠ' => 'تجى', - 'ﶡ' => 'تخي', - 'ﶢ' => 'تخى', - 'ﶣ' => 'تمي', - 'ﶤ' => 'تمى', - 'ﶥ' => 'جمي', - 'ﶦ' => 'جحى', - 'ﶧ' => 'جمى', - 'ﶨ' => 'سخى', - 'ﶩ' => 'صحي', - 'ﶪ' => 'شحي', - 'ﶫ' => 'ضحي', - 'ﶬ' => 'لجي', - 'ﶭ' => 'لمي', - 'ﶮ' => 'يحي', - 'ﶯ' => 'يجي', - 'ﶰ' => 'يمي', - 'ﶱ' => 'ممي', - 'ﶲ' => 'قمي', - 'ﶳ' => 'نحي', - 'ﶴ' => 'قمح', - 'ﶵ' => 'لحم', - 'ﶶ' => 'عمي', - 'ﶷ' => 'كمي', - 'ﶸ' => 'نجح', - 'ﶹ' => 'مخي', - 'ﶺ' => 'لجم', - 'ﶻ' => 'كمم', - 'ﶼ' => 'لجم', - 'ﶽ' => 'نجح', - 'ﶾ' => 'جحي', - 'ﶿ' => 'حجي', - 'ﷀ' => 'مجي', - 'ﷁ' => 'فمي', - 'ﷂ' => 'بحي', - 'ﷃ' => 'كمم', - 'ﷄ' => 'عجم', - 'ﷅ' => 'صمم', - 'ﷆ' => 'سخي', - 'ﷇ' => 'نجي', - 'ﷰ' => 'صلے', - 'ﷱ' => 'قلے', - 'ﷲ' => 'الله', - 'ﷳ' => 'اكبر', - 'ﷴ' => 'محمد', - 'ﷵ' => 'صلعم', - 'ﷶ' => 'رسول', - 'ﷷ' => 'عليه', - 'ﷸ' => 'وسلم', - 'ﷹ' => 'صلى', - 'ﷺ' => 'صلى الله عليه وسلم', - 'ﷻ' => 'جل جلاله', - '﷼' => 'ریال', - '︐' => ',', - '︑' => '、', - '︒' => '。', - '︓' => ':', - '︔' => ';', - '︕' => '!', - '︖' => '?', - '︗' => '〖', - '︘' => '〗', - '︙' => '...', - '︰' => '..', - '︱' => '—', - '︲' => '–', - '︳' => '_', - '︴' => '_', - '︵' => '(', - '︶' => ')', - '︷' => '{', - '︸' => '}', - '︹' => '〔', - '︺' => '〕', - '︻' => '【', - '︼' => '】', - '︽' => '《', - '︾' => '》', - '︿' => '〈', - '﹀' => '〉', - '﹁' => '「', - '﹂' => '」', - '﹃' => '『', - '﹄' => '』', - '﹇' => '[', - '﹈' => ']', - '﹉' => ' ̅', - '﹊' => ' ̅', - '﹋' => ' ̅', - '﹌' => ' ̅', - '﹍' => '_', - '﹎' => '_', - '﹏' => '_', - '﹐' => ',', - '﹑' => '、', - '﹒' => '.', - '﹔' => ';', - '﹕' => ':', - '﹖' => '?', - '﹗' => '!', - '﹘' => '—', - '﹙' => '(', - '﹚' => ')', - '﹛' => '{', - '﹜' => '}', - '﹝' => '〔', - '﹞' => '〕', - '﹟' => '#', - '﹠' => '&', - '﹡' => '*', - '﹢' => '+', - '﹣' => '-', - '﹤' => '<', - '﹥' => '>', - '﹦' => '=', - '﹨' => '\\', - '﹩' => '$', - '﹪' => '%', - '﹫' => '@', - 'ﹰ' => ' ً', - 'ﹱ' => 'ـً', - 'ﹲ' => ' ٌ', - 'ﹴ' => ' ٍ', - 'ﹶ' => ' َ', - 'ﹷ' => 'ـَ', - 'ﹸ' => ' ُ', - 'ﹹ' => 'ـُ', - 'ﹺ' => ' ِ', - 'ﹻ' => 'ـِ', - 'ﹼ' => ' ّ', - 'ﹽ' => 'ـّ', - 'ﹾ' => ' ْ', - 'ﹿ' => 'ـْ', - 'ﺀ' => 'ء', - 'ﺁ' => 'آ', - 'ﺂ' => 'آ', - 'ﺃ' => 'أ', - 'ﺄ' => 'أ', - 'ﺅ' => 'ؤ', - 'ﺆ' => 'ؤ', - 'ﺇ' => 'إ', - 'ﺈ' => 'إ', - 'ﺉ' => 'ئ', - 'ﺊ' => 'ئ', - 'ﺋ' => 'ئ', - 'ﺌ' => 'ئ', - 'ﺍ' => 'ا', - 'ﺎ' => 'ا', - 'ﺏ' => 'ب', - 'ﺐ' => 'ب', - 'ﺑ' => 'ب', - 'ﺒ' => 'ب', - 'ﺓ' => 'ة', - 'ﺔ' => 'ة', - 'ﺕ' => 'ت', - 'ﺖ' => 'ت', - 'ﺗ' => 'ت', - 'ﺘ' => 'ت', - 'ﺙ' => 'ث', - 'ﺚ' => 'ث', - 'ﺛ' => 'ث', - 'ﺜ' => 'ث', - 'ﺝ' => 'ج', - 'ﺞ' => 'ج', - 'ﺟ' => 'ج', - 'ﺠ' => 'ج', - 'ﺡ' => 'ح', - 'ﺢ' => 'ح', - 'ﺣ' => 'ح', - 'ﺤ' => 'ح', - 'ﺥ' => 'خ', - 'ﺦ' => 'خ', - 'ﺧ' => 'خ', - 'ﺨ' => 'خ', - 'ﺩ' => 'د', - 'ﺪ' => 'د', - 'ﺫ' => 'ذ', - 'ﺬ' => 'ذ', - 'ﺭ' => 'ر', - 'ﺮ' => 'ر', - 'ﺯ' => 'ز', - 'ﺰ' => 'ز', - 'ﺱ' => 'س', - 'ﺲ' => 'س', - 'ﺳ' => 'س', - 'ﺴ' => 'س', - 'ﺵ' => 'ش', - 'ﺶ' => 'ش', - 'ﺷ' => 'ش', - 'ﺸ' => 'ش', - 'ﺹ' => 'ص', - 'ﺺ' => 'ص', - 'ﺻ' => 'ص', - 'ﺼ' => 'ص', - 'ﺽ' => 'ض', - 'ﺾ' => 'ض', - 'ﺿ' => 'ض', - 'ﻀ' => 'ض', - 'ﻁ' => 'ط', - 'ﻂ' => 'ط', - 'ﻃ' => 'ط', - 'ﻄ' => 'ط', - 'ﻅ' => 'ظ', - 'ﻆ' => 'ظ', - 'ﻇ' => 'ظ', - 'ﻈ' => 'ظ', - 'ﻉ' => 'ع', - 'ﻊ' => 'ع', - 'ﻋ' => 'ع', - 'ﻌ' => 'ع', - 'ﻍ' => 'غ', - 'ﻎ' => 'غ', - 'ﻏ' => 'غ', - 'ﻐ' => 'غ', - 'ﻑ' => 'ف', - 'ﻒ' => 'ف', - 'ﻓ' => 'ف', - 'ﻔ' => 'ف', - 'ﻕ' => 'ق', - 'ﻖ' => 'ق', - 'ﻗ' => 'ق', - 'ﻘ' => 'ق', - 'ﻙ' => 'ك', - 'ﻚ' => 'ك', - 'ﻛ' => 'ك', - 'ﻜ' => 'ك', - 'ﻝ' => 'ل', - 'ﻞ' => 'ل', - 'ﻟ' => 'ل', - 'ﻠ' => 'ل', - 'ﻡ' => 'م', - 'ﻢ' => 'م', - 'ﻣ' => 'م', - 'ﻤ' => 'م', - 'ﻥ' => 'ن', - 'ﻦ' => 'ن', - 'ﻧ' => 'ن', - 'ﻨ' => 'ن', - 'ﻩ' => 'ه', - 'ﻪ' => 'ه', - 'ﻫ' => 'ه', - 'ﻬ' => 'ه', - 'ﻭ' => 'و', - 'ﻮ' => 'و', - 'ﻯ' => 'ى', - 'ﻰ' => 'ى', - 'ﻱ' => 'ي', - 'ﻲ' => 'ي', - 'ﻳ' => 'ي', - 'ﻴ' => 'ي', - 'ﻵ' => 'لآ', - 'ﻶ' => 'لآ', - 'ﻷ' => 'لأ', - 'ﻸ' => 'لأ', - 'ﻹ' => 'لإ', - 'ﻺ' => 'لإ', - 'ﻻ' => 'لا', - 'ﻼ' => 'لا', - '!' => '!', - '"' => '"', - '#' => '#', - '$' => '$', - '%' => '%', - '&' => '&', - ''' => '\'', - '(' => '(', - ')' => ')', - '*' => '*', - '+' => '+', - ',' => ',', - '-' => '-', - '.' => '.', - '/' => '/', - '0' => '0', - '1' => '1', - '2' => '2', - '3' => '3', - '4' => '4', - '5' => '5', - '6' => '6', - '7' => '7', - '8' => '8', - '9' => '9', - ':' => ':', - ';' => ';', - '<' => '<', - '=' => '=', - '>' => '>', - '?' => '?', - '@' => '@', - 'A' => 'A', - 'B' => 'B', - 'C' => 'C', - 'D' => 'D', - 'E' => 'E', - 'F' => 'F', - 'G' => 'G', - 'H' => 'H', - 'I' => 'I', - 'J' => 'J', - 'K' => 'K', - 'L' => 'L', - 'M' => 'M', - 'N' => 'N', - 'O' => 'O', - 'P' => 'P', - 'Q' => 'Q', - 'R' => 'R', - 'S' => 'S', - 'T' => 'T', - 'U' => 'U', - 'V' => 'V', - 'W' => 'W', - 'X' => 'X', - 'Y' => 'Y', - 'Z' => 'Z', - '[' => '[', - '\' => '\\', - ']' => ']', - '^' => '^', - '_' => '_', - '`' => '`', - 'a' => 'a', - 'b' => 'b', - 'c' => 'c', - 'd' => 'd', - 'e' => 'e', - 'f' => 'f', - 'g' => 'g', - 'h' => 'h', - 'i' => 'i', - 'j' => 'j', - 'k' => 'k', - 'l' => 'l', - 'm' => 'm', - 'n' => 'n', - 'o' => 'o', - 'p' => 'p', - 'q' => 'q', - 'r' => 'r', - 's' => 's', - 't' => 't', - 'u' => 'u', - 'v' => 'v', - 'w' => 'w', - 'x' => 'x', - 'y' => 'y', - 'z' => 'z', - '{' => '{', - '|' => '|', - '}' => '}', - '~' => '~', - '⦅' => '⦅', - '⦆' => '⦆', - '。' => '。', - '「' => '「', - '」' => '」', - '、' => '、', - '・' => '・', - 'ヲ' => 'ヲ', - 'ァ' => 'ァ', - 'ィ' => 'ィ', - 'ゥ' => 'ゥ', - 'ェ' => 'ェ', - 'ォ' => 'ォ', - 'ャ' => 'ャ', - 'ュ' => 'ュ', - 'ョ' => 'ョ', - 'ッ' => 'ッ', - 'ー' => 'ー', - 'ア' => 'ア', - 'イ' => 'イ', - 'ウ' => 'ウ', - 'エ' => 'エ', - 'オ' => 'オ', - 'カ' => 'カ', - 'キ' => 'キ', - 'ク' => 'ク', - 'ケ' => 'ケ', - 'コ' => 'コ', - 'サ' => 'サ', - 'シ' => 'シ', - 'ス' => 'ス', - 'セ' => 'セ', - 'ソ' => 'ソ', - 'タ' => 'タ', - 'チ' => 'チ', - 'ツ' => 'ツ', - 'テ' => 'テ', - 'ト' => 'ト', - 'ナ' => 'ナ', - 'ニ' => 'ニ', - 'ヌ' => 'ヌ', - 'ネ' => 'ネ', - 'ノ' => 'ノ', - 'ハ' => 'ハ', - 'ヒ' => 'ヒ', - 'フ' => 'フ', - 'ヘ' => 'ヘ', - 'ホ' => 'ホ', - 'マ' => 'マ', - 'ミ' => 'ミ', - 'ム' => 'ム', - 'メ' => 'メ', - 'モ' => 'モ', - 'ヤ' => 'ヤ', - 'ユ' => 'ユ', - 'ヨ' => 'ヨ', - 'ラ' => 'ラ', - 'リ' => 'リ', - 'ル' => 'ル', - 'レ' => 'レ', - 'ロ' => 'ロ', - 'ワ' => 'ワ', - 'ン' => 'ン', - '゙' => '゙', - '゚' => '゚', - 'ᅠ' => 'ᅠ', - 'ᄀ' => 'ᄀ', - 'ᄁ' => 'ᄁ', - 'ᆪ' => 'ᆪ', - 'ᄂ' => 'ᄂ', - 'ᆬ' => 'ᆬ', - 'ᆭ' => 'ᆭ', - 'ᄃ' => 'ᄃ', - 'ᄄ' => 'ᄄ', - 'ᄅ' => 'ᄅ', - 'ᆰ' => 'ᆰ', - 'ᆱ' => 'ᆱ', - 'ᆲ' => 'ᆲ', - 'ᆳ' => 'ᆳ', - 'ᆴ' => 'ᆴ', - 'ᆵ' => 'ᆵ', - 'ᄚ' => 'ᄚ', - 'ᄆ' => 'ᄆ', - 'ᄇ' => 'ᄇ', - 'ᄈ' => 'ᄈ', - 'ᄡ' => 'ᄡ', - 'ᄉ' => 'ᄉ', - 'ᄊ' => 'ᄊ', - 'ᄋ' => 'ᄋ', - 'ᄌ' => 'ᄌ', - 'ᄍ' => 'ᄍ', - 'ᄎ' => 'ᄎ', - 'ᄏ' => 'ᄏ', - 'ᄐ' => 'ᄐ', - 'ᄑ' => 'ᄑ', - 'ᄒ' => 'ᄒ', - 'ᅡ' => 'ᅡ', - 'ᅢ' => 'ᅢ', - 'ᅣ' => 'ᅣ', - 'ᅤ' => 'ᅤ', - 'ᅥ' => 'ᅥ', - 'ᅦ' => 'ᅦ', - 'ᅧ' => 'ᅧ', - 'ᅨ' => 'ᅨ', - 'ᅩ' => 'ᅩ', - 'ᅪ' => 'ᅪ', - 'ᅫ' => 'ᅫ', - 'ᅬ' => 'ᅬ', - 'ᅭ' => 'ᅭ', - 'ᅮ' => 'ᅮ', - 'ᅯ' => 'ᅯ', - 'ᅰ' => 'ᅰ', - 'ᅱ' => 'ᅱ', - 'ᅲ' => 'ᅲ', - 'ᅳ' => 'ᅳ', - 'ᅴ' => 'ᅴ', - 'ᅵ' => 'ᅵ', - '¢' => '¢', - '£' => '£', - '¬' => '¬', - ' ̄' => ' ̄', - '¦' => '¦', - '¥' => '¥', - '₩' => '₩', - '│' => '│', - '←' => '←', - '↑' => '↑', - '→' => '→', - '↓' => '↓', - '■' => '■', - '○' => '○', - '𝐀' => 'A', - '𝐁' => 'B', - '𝐂' => 'C', - '𝐃' => 'D', - '𝐄' => 'E', - '𝐅' => 'F', - '𝐆' => 'G', - '𝐇' => 'H', - '𝐈' => 'I', - '𝐉' => 'J', - '𝐊' => 'K', - '𝐋' => 'L', - '𝐌' => 'M', - '𝐍' => 'N', - '𝐎' => 'O', - '𝐏' => 'P', - '𝐐' => 'Q', - '𝐑' => 'R', - '𝐒' => 'S', - '𝐓' => 'T', - '𝐔' => 'U', - '𝐕' => 'V', - '𝐖' => 'W', - '𝐗' => 'X', - '𝐘' => 'Y', - '𝐙' => 'Z', - '𝐚' => 'a', - '𝐛' => 'b', - '𝐜' => 'c', - '𝐝' => 'd', - '𝐞' => 'e', - '𝐟' => 'f', - '𝐠' => 'g', - '𝐡' => 'h', - '𝐢' => 'i', - '𝐣' => 'j', - '𝐤' => 'k', - '𝐥' => 'l', - '𝐦' => 'm', - '𝐧' => 'n', - '𝐨' => 'o', - '𝐩' => 'p', - '𝐪' => 'q', - '𝐫' => 'r', - '𝐬' => 's', - '𝐭' => 't', - '𝐮' => 'u', - '𝐯' => 'v', - '𝐰' => 'w', - '𝐱' => 'x', - '𝐲' => 'y', - '𝐳' => 'z', - '𝐴' => 'A', - '𝐵' => 'B', - '𝐶' => 'C', - '𝐷' => 'D', - '𝐸' => 'E', - '𝐹' => 'F', - '𝐺' => 'G', - '𝐻' => 'H', - '𝐼' => 'I', - '𝐽' => 'J', - '𝐾' => 'K', - '𝐿' => 'L', - '𝑀' => 'M', - '𝑁' => 'N', - '𝑂' => 'O', - '𝑃' => 'P', - '𝑄' => 'Q', - '𝑅' => 'R', - '𝑆' => 'S', - '𝑇' => 'T', - '𝑈' => 'U', - '𝑉' => 'V', - '𝑊' => 'W', - '𝑋' => 'X', - '𝑌' => 'Y', - '𝑍' => 'Z', - '𝑎' => 'a', - '𝑏' => 'b', - '𝑐' => 'c', - '𝑑' => 'd', - '𝑒' => 'e', - '𝑓' => 'f', - '𝑔' => 'g', - '𝑖' => 'i', - '𝑗' => 'j', - '𝑘' => 'k', - '𝑙' => 'l', - '𝑚' => 'm', - '𝑛' => 'n', - '𝑜' => 'o', - '𝑝' => 'p', - '𝑞' => 'q', - '𝑟' => 'r', - '𝑠' => 's', - '𝑡' => 't', - '𝑢' => 'u', - '𝑣' => 'v', - '𝑤' => 'w', - '𝑥' => 'x', - '𝑦' => 'y', - '𝑧' => 'z', - '𝑨' => 'A', - '𝑩' => 'B', - '𝑪' => 'C', - '𝑫' => 'D', - '𝑬' => 'E', - '𝑭' => 'F', - '𝑮' => 'G', - '𝑯' => 'H', - '𝑰' => 'I', - '𝑱' => 'J', - '𝑲' => 'K', - '𝑳' => 'L', - '𝑴' => 'M', - '𝑵' => 'N', - '𝑶' => 'O', - '𝑷' => 'P', - '𝑸' => 'Q', - '𝑹' => 'R', - '𝑺' => 'S', - '𝑻' => 'T', - '𝑼' => 'U', - '𝑽' => 'V', - '𝑾' => 'W', - '𝑿' => 'X', - '𝒀' => 'Y', - '𝒁' => 'Z', - '𝒂' => 'a', - '𝒃' => 'b', - '𝒄' => 'c', - '𝒅' => 'd', - '𝒆' => 'e', - '𝒇' => 'f', - '𝒈' => 'g', - '𝒉' => 'h', - '𝒊' => 'i', - '𝒋' => 'j', - '𝒌' => 'k', - '𝒍' => 'l', - '𝒎' => 'm', - '𝒏' => 'n', - '𝒐' => 'o', - '𝒑' => 'p', - '𝒒' => 'q', - '𝒓' => 'r', - '𝒔' => 's', - '𝒕' => 't', - '𝒖' => 'u', - '𝒗' => 'v', - '𝒘' => 'w', - '𝒙' => 'x', - '𝒚' => 'y', - '𝒛' => 'z', - '𝒜' => 'A', - '𝒞' => 'C', - '𝒟' => 'D', - '𝒢' => 'G', - '𝒥' => 'J', - '𝒦' => 'K', - '𝒩' => 'N', - '𝒪' => 'O', - '𝒫' => 'P', - '𝒬' => 'Q', - '𝒮' => 'S', - '𝒯' => 'T', - '𝒰' => 'U', - '𝒱' => 'V', - '𝒲' => 'W', - '𝒳' => 'X', - '𝒴' => 'Y', - '𝒵' => 'Z', - '𝒶' => 'a', - '𝒷' => 'b', - '𝒸' => 'c', - '𝒹' => 'd', - '𝒻' => 'f', - '𝒽' => 'h', - '𝒾' => 'i', - '𝒿' => 'j', - '𝓀' => 'k', - '𝓁' => 'l', - '𝓂' => 'm', - '𝓃' => 'n', - '𝓅' => 'p', - '𝓆' => 'q', - '𝓇' => 'r', - '𝓈' => 's', - '𝓉' => 't', - '𝓊' => 'u', - '𝓋' => 'v', - '𝓌' => 'w', - '𝓍' => 'x', - '𝓎' => 'y', - '𝓏' => 'z', - '𝓐' => 'A', - '𝓑' => 'B', - '𝓒' => 'C', - '𝓓' => 'D', - '𝓔' => 'E', - '𝓕' => 'F', - '𝓖' => 'G', - '𝓗' => 'H', - '𝓘' => 'I', - '𝓙' => 'J', - '𝓚' => 'K', - '𝓛' => 'L', - '𝓜' => 'M', - '𝓝' => 'N', - '𝓞' => 'O', - '𝓟' => 'P', - '𝓠' => 'Q', - '𝓡' => 'R', - '𝓢' => 'S', - '𝓣' => 'T', - '𝓤' => 'U', - '𝓥' => 'V', - '𝓦' => 'W', - '𝓧' => 'X', - '𝓨' => 'Y', - '𝓩' => 'Z', - '𝓪' => 'a', - '𝓫' => 'b', - '𝓬' => 'c', - '𝓭' => 'd', - '𝓮' => 'e', - '𝓯' => 'f', - '𝓰' => 'g', - '𝓱' => 'h', - '𝓲' => 'i', - '𝓳' => 'j', - '𝓴' => 'k', - '𝓵' => 'l', - '𝓶' => 'm', - '𝓷' => 'n', - '𝓸' => 'o', - '𝓹' => 'p', - '𝓺' => 'q', - '𝓻' => 'r', - '𝓼' => 's', - '𝓽' => 't', - '𝓾' => 'u', - '𝓿' => 'v', - '𝔀' => 'w', - '𝔁' => 'x', - '𝔂' => 'y', - '𝔃' => 'z', - '𝔄' => 'A', - '𝔅' => 'B', - '𝔇' => 'D', - '𝔈' => 'E', - '𝔉' => 'F', - '𝔊' => 'G', - '𝔍' => 'J', - '𝔎' => 'K', - '𝔏' => 'L', - '𝔐' => 'M', - '𝔑' => 'N', - '𝔒' => 'O', - '𝔓' => 'P', - '𝔔' => 'Q', - '𝔖' => 'S', - '𝔗' => 'T', - '𝔘' => 'U', - '𝔙' => 'V', - '𝔚' => 'W', - '𝔛' => 'X', - '𝔜' => 'Y', - '𝔞' => 'a', - '𝔟' => 'b', - '𝔠' => 'c', - '𝔡' => 'd', - '𝔢' => 'e', - '𝔣' => 'f', - '𝔤' => 'g', - '𝔥' => 'h', - '𝔦' => 'i', - '𝔧' => 'j', - '𝔨' => 'k', - '𝔩' => 'l', - '𝔪' => 'm', - '𝔫' => 'n', - '𝔬' => 'o', - '𝔭' => 'p', - '𝔮' => 'q', - '𝔯' => 'r', - '𝔰' => 's', - '𝔱' => 't', - '𝔲' => 'u', - '𝔳' => 'v', - '𝔴' => 'w', - '𝔵' => 'x', - '𝔶' => 'y', - '𝔷' => 'z', - '𝔸' => 'A', - '𝔹' => 'B', - '𝔻' => 'D', - '𝔼' => 'E', - '𝔽' => 'F', - '𝔾' => 'G', - '𝕀' => 'I', - '𝕁' => 'J', - '𝕂' => 'K', - '𝕃' => 'L', - '𝕄' => 'M', - '𝕆' => 'O', - '𝕊' => 'S', - '𝕋' => 'T', - '𝕌' => 'U', - '𝕍' => 'V', - '𝕎' => 'W', - '𝕏' => 'X', - '𝕐' => 'Y', - '𝕒' => 'a', - '𝕓' => 'b', - '𝕔' => 'c', - '𝕕' => 'd', - '𝕖' => 'e', - '𝕗' => 'f', - '𝕘' => 'g', - '𝕙' => 'h', - '𝕚' => 'i', - '𝕛' => 'j', - '𝕜' => 'k', - '𝕝' => 'l', - '𝕞' => 'm', - '𝕟' => 'n', - '𝕠' => 'o', - '𝕡' => 'p', - '𝕢' => 'q', - '𝕣' => 'r', - '𝕤' => 's', - '𝕥' => 't', - '𝕦' => 'u', - '𝕧' => 'v', - '𝕨' => 'w', - '𝕩' => 'x', - '𝕪' => 'y', - '𝕫' => 'z', - '𝕬' => 'A', - '𝕭' => 'B', - '𝕮' => 'C', - '𝕯' => 'D', - '𝕰' => 'E', - '𝕱' => 'F', - '𝕲' => 'G', - '𝕳' => 'H', - '𝕴' => 'I', - '𝕵' => 'J', - '𝕶' => 'K', - '𝕷' => 'L', - '𝕸' => 'M', - '𝕹' => 'N', - '𝕺' => 'O', - '𝕻' => 'P', - '𝕼' => 'Q', - '𝕽' => 'R', - '𝕾' => 'S', - '𝕿' => 'T', - '𝖀' => 'U', - '𝖁' => 'V', - '𝖂' => 'W', - '𝖃' => 'X', - '𝖄' => 'Y', - '𝖅' => 'Z', - '𝖆' => 'a', - '𝖇' => 'b', - '𝖈' => 'c', - '𝖉' => 'd', - '𝖊' => 'e', - '𝖋' => 'f', - '𝖌' => 'g', - '𝖍' => 'h', - '𝖎' => 'i', - '𝖏' => 'j', - '𝖐' => 'k', - '𝖑' => 'l', - '𝖒' => 'm', - '𝖓' => 'n', - '𝖔' => 'o', - '𝖕' => 'p', - '𝖖' => 'q', - '𝖗' => 'r', - '𝖘' => 's', - '𝖙' => 't', - '𝖚' => 'u', - '𝖛' => 'v', - '𝖜' => 'w', - '𝖝' => 'x', - '𝖞' => 'y', - '𝖟' => 'z', - '𝖠' => 'A', - '𝖡' => 'B', - '𝖢' => 'C', - '𝖣' => 'D', - '𝖤' => 'E', - '𝖥' => 'F', - '𝖦' => 'G', - '𝖧' => 'H', - '𝖨' => 'I', - '𝖩' => 'J', - '𝖪' => 'K', - '𝖫' => 'L', - '𝖬' => 'M', - '𝖭' => 'N', - '𝖮' => 'O', - '𝖯' => 'P', - '𝖰' => 'Q', - '𝖱' => 'R', - '𝖲' => 'S', - '𝖳' => 'T', - '𝖴' => 'U', - '𝖵' => 'V', - '𝖶' => 'W', - '𝖷' => 'X', - '𝖸' => 'Y', - '𝖹' => 'Z', - '𝖺' => 'a', - '𝖻' => 'b', - '𝖼' => 'c', - '𝖽' => 'd', - '𝖾' => 'e', - '𝖿' => 'f', - '𝗀' => 'g', - '𝗁' => 'h', - '𝗂' => 'i', - '𝗃' => 'j', - '𝗄' => 'k', - '𝗅' => 'l', - '𝗆' => 'm', - '𝗇' => 'n', - '𝗈' => 'o', - '𝗉' => 'p', - '𝗊' => 'q', - '𝗋' => 'r', - '𝗌' => 's', - '𝗍' => 't', - '𝗎' => 'u', - '𝗏' => 'v', - '𝗐' => 'w', - '𝗑' => 'x', - '𝗒' => 'y', - '𝗓' => 'z', - '𝗔' => 'A', - '𝗕' => 'B', - '𝗖' => 'C', - '𝗗' => 'D', - '𝗘' => 'E', - '𝗙' => 'F', - '𝗚' => 'G', - '𝗛' => 'H', - '𝗜' => 'I', - '𝗝' => 'J', - '𝗞' => 'K', - '𝗟' => 'L', - '𝗠' => 'M', - '𝗡' => 'N', - '𝗢' => 'O', - '𝗣' => 'P', - '𝗤' => 'Q', - '𝗥' => 'R', - '𝗦' => 'S', - '𝗧' => 'T', - '𝗨' => 'U', - '𝗩' => 'V', - '𝗪' => 'W', - '𝗫' => 'X', - '𝗬' => 'Y', - '𝗭' => 'Z', - '𝗮' => 'a', - '𝗯' => 'b', - '𝗰' => 'c', - '𝗱' => 'd', - '𝗲' => 'e', - '𝗳' => 'f', - '𝗴' => 'g', - '𝗵' => 'h', - '𝗶' => 'i', - '𝗷' => 'j', - '𝗸' => 'k', - '𝗹' => 'l', - '𝗺' => 'm', - '𝗻' => 'n', - '𝗼' => 'o', - '𝗽' => 'p', - '𝗾' => 'q', - '𝗿' => 'r', - '𝘀' => 's', - '𝘁' => 't', - '𝘂' => 'u', - '𝘃' => 'v', - '𝘄' => 'w', - '𝘅' => 'x', - '𝘆' => 'y', - '𝘇' => 'z', - '𝘈' => 'A', - '𝘉' => 'B', - '𝘊' => 'C', - '𝘋' => 'D', - '𝘌' => 'E', - '𝘍' => 'F', - '𝘎' => 'G', - '𝘏' => 'H', - '𝘐' => 'I', - '𝘑' => 'J', - '𝘒' => 'K', - '𝘓' => 'L', - '𝘔' => 'M', - '𝘕' => 'N', - '𝘖' => 'O', - '𝘗' => 'P', - '𝘘' => 'Q', - '𝘙' => 'R', - '𝘚' => 'S', - '𝘛' => 'T', - '𝘜' => 'U', - '𝘝' => 'V', - '𝘞' => 'W', - '𝘟' => 'X', - '𝘠' => 'Y', - '𝘡' => 'Z', - '𝘢' => 'a', - '𝘣' => 'b', - '𝘤' => 'c', - '𝘥' => 'd', - '𝘦' => 'e', - '𝘧' => 'f', - '𝘨' => 'g', - '𝘩' => 'h', - '𝘪' => 'i', - '𝘫' => 'j', - '𝘬' => 'k', - '𝘭' => 'l', - '𝘮' => 'm', - '𝘯' => 'n', - '𝘰' => 'o', - '𝘱' => 'p', - '𝘲' => 'q', - '𝘳' => 'r', - '𝘴' => 's', - '𝘵' => 't', - '𝘶' => 'u', - '𝘷' => 'v', - '𝘸' => 'w', - '𝘹' => 'x', - '𝘺' => 'y', - '𝘻' => 'z', - '𝘼' => 'A', - '𝘽' => 'B', - '𝘾' => 'C', - '𝘿' => 'D', - '𝙀' => 'E', - '𝙁' => 'F', - '𝙂' => 'G', - '𝙃' => 'H', - '𝙄' => 'I', - '𝙅' => 'J', - '𝙆' => 'K', - '𝙇' => 'L', - '𝙈' => 'M', - '𝙉' => 'N', - '𝙊' => 'O', - '𝙋' => 'P', - '𝙌' => 'Q', - '𝙍' => 'R', - '𝙎' => 'S', - '𝙏' => 'T', - '𝙐' => 'U', - '𝙑' => 'V', - '𝙒' => 'W', - '𝙓' => 'X', - '𝙔' => 'Y', - '𝙕' => 'Z', - '𝙖' => 'a', - '𝙗' => 'b', - '𝙘' => 'c', - '𝙙' => 'd', - '𝙚' => 'e', - '𝙛' => 'f', - '𝙜' => 'g', - '𝙝' => 'h', - '𝙞' => 'i', - '𝙟' => 'j', - '𝙠' => 'k', - '𝙡' => 'l', - '𝙢' => 'm', - '𝙣' => 'n', - '𝙤' => 'o', - '𝙥' => 'p', - '𝙦' => 'q', - '𝙧' => 'r', - '𝙨' => 's', - '𝙩' => 't', - '𝙪' => 'u', - '𝙫' => 'v', - '𝙬' => 'w', - '𝙭' => 'x', - '𝙮' => 'y', - '𝙯' => 'z', - '𝙰' => 'A', - '𝙱' => 'B', - '𝙲' => 'C', - '𝙳' => 'D', - '𝙴' => 'E', - '𝙵' => 'F', - '𝙶' => 'G', - '𝙷' => 'H', - '𝙸' => 'I', - '𝙹' => 'J', - '𝙺' => 'K', - '𝙻' => 'L', - '𝙼' => 'M', - '𝙽' => 'N', - '𝙾' => 'O', - '𝙿' => 'P', - '𝚀' => 'Q', - '𝚁' => 'R', - '𝚂' => 'S', - '𝚃' => 'T', - '𝚄' => 'U', - '𝚅' => 'V', - '𝚆' => 'W', - '𝚇' => 'X', - '𝚈' => 'Y', - '𝚉' => 'Z', - '𝚊' => 'a', - '𝚋' => 'b', - '𝚌' => 'c', - '𝚍' => 'd', - '𝚎' => 'e', - '𝚏' => 'f', - '𝚐' => 'g', - '𝚑' => 'h', - '𝚒' => 'i', - '𝚓' => 'j', - '𝚔' => 'k', - '𝚕' => 'l', - '𝚖' => 'm', - '𝚗' => 'n', - '𝚘' => 'o', - '𝚙' => 'p', - '𝚚' => 'q', - '𝚛' => 'r', - '𝚜' => 's', - '𝚝' => 't', - '𝚞' => 'u', - '𝚟' => 'v', - '𝚠' => 'w', - '𝚡' => 'x', - '𝚢' => 'y', - '𝚣' => 'z', - '𝚤' => 'ı', - '𝚥' => 'ȷ', - '𝚨' => 'Α', - '𝚩' => 'Β', - '𝚪' => 'Γ', - '𝚫' => 'Δ', - '𝚬' => 'Ε', - '𝚭' => 'Ζ', - '𝚮' => 'Η', - '𝚯' => 'Θ', - '𝚰' => 'Ι', - '𝚱' => 'Κ', - '𝚲' => 'Λ', - '𝚳' => 'Μ', - '𝚴' => 'Ν', - '𝚵' => 'Ξ', - '𝚶' => 'Ο', - '𝚷' => 'Π', - '𝚸' => 'Ρ', - '𝚹' => 'Θ', - '𝚺' => 'Σ', - '𝚻' => 'Τ', - '𝚼' => 'Υ', - '𝚽' => 'Φ', - '𝚾' => 'Χ', - '𝚿' => 'Ψ', - '𝛀' => 'Ω', - '𝛁' => '∇', - '𝛂' => 'α', - '𝛃' => 'β', - '𝛄' => 'γ', - '𝛅' => 'δ', - '𝛆' => 'ε', - '𝛇' => 'ζ', - '𝛈' => 'η', - '𝛉' => 'θ', - '𝛊' => 'ι', - '𝛋' => 'κ', - '𝛌' => 'λ', - '𝛍' => 'μ', - '𝛎' => 'ν', - '𝛏' => 'ξ', - '𝛐' => 'ο', - '𝛑' => 'π', - '𝛒' => 'ρ', - '𝛓' => 'ς', - '𝛔' => 'σ', - '𝛕' => 'τ', - '𝛖' => 'υ', - '𝛗' => 'φ', - '𝛘' => 'χ', - '𝛙' => 'ψ', - '𝛚' => 'ω', - '𝛛' => '∂', - '𝛜' => 'ε', - '𝛝' => 'θ', - '𝛞' => 'κ', - '𝛟' => 'φ', - '𝛠' => 'ρ', - '𝛡' => 'π', - '𝛢' => 'Α', - '𝛣' => 'Β', - '𝛤' => 'Γ', - '𝛥' => 'Δ', - '𝛦' => 'Ε', - '𝛧' => 'Ζ', - '𝛨' => 'Η', - '𝛩' => 'Θ', - '𝛪' => 'Ι', - '𝛫' => 'Κ', - '𝛬' => 'Λ', - '𝛭' => 'Μ', - '𝛮' => 'Ν', - '𝛯' => 'Ξ', - '𝛰' => 'Ο', - '𝛱' => 'Π', - '𝛲' => 'Ρ', - '𝛳' => 'Θ', - '𝛴' => 'Σ', - '𝛵' => 'Τ', - '𝛶' => 'Υ', - '𝛷' => 'Φ', - '𝛸' => 'Χ', - '𝛹' => 'Ψ', - '𝛺' => 'Ω', - '𝛻' => '∇', - '𝛼' => 'α', - '𝛽' => 'β', - '𝛾' => 'γ', - '𝛿' => 'δ', - '𝜀' => 'ε', - '𝜁' => 'ζ', - '𝜂' => 'η', - '𝜃' => 'θ', - '𝜄' => 'ι', - '𝜅' => 'κ', - '𝜆' => 'λ', - '𝜇' => 'μ', - '𝜈' => 'ν', - '𝜉' => 'ξ', - '𝜊' => 'ο', - '𝜋' => 'π', - '𝜌' => 'ρ', - '𝜍' => 'ς', - '𝜎' => 'σ', - '𝜏' => 'τ', - '𝜐' => 'υ', - '𝜑' => 'φ', - '𝜒' => 'χ', - '𝜓' => 'ψ', - '𝜔' => 'ω', - '𝜕' => '∂', - '𝜖' => 'ε', - '𝜗' => 'θ', - '𝜘' => 'κ', - '𝜙' => 'φ', - '𝜚' => 'ρ', - '𝜛' => 'π', - '𝜜' => 'Α', - '𝜝' => 'Β', - '𝜞' => 'Γ', - '𝜟' => 'Δ', - '𝜠' => 'Ε', - '𝜡' => 'Ζ', - '𝜢' => 'Η', - '𝜣' => 'Θ', - '𝜤' => 'Ι', - '𝜥' => 'Κ', - '𝜦' => 'Λ', - '𝜧' => 'Μ', - '𝜨' => 'Ν', - '𝜩' => 'Ξ', - '𝜪' => 'Ο', - '𝜫' => 'Π', - '𝜬' => 'Ρ', - '𝜭' => 'Θ', - '𝜮' => 'Σ', - '𝜯' => 'Τ', - '𝜰' => 'Υ', - '𝜱' => 'Φ', - '𝜲' => 'Χ', - '𝜳' => 'Ψ', - '𝜴' => 'Ω', - '𝜵' => '∇', - '𝜶' => 'α', - '𝜷' => 'β', - '𝜸' => 'γ', - '𝜹' => 'δ', - '𝜺' => 'ε', - '𝜻' => 'ζ', - '𝜼' => 'η', - '𝜽' => 'θ', - '𝜾' => 'ι', - '𝜿' => 'κ', - '𝝀' => 'λ', - '𝝁' => 'μ', - '𝝂' => 'ν', - '𝝃' => 'ξ', - '𝝄' => 'ο', - '𝝅' => 'π', - '𝝆' => 'ρ', - '𝝇' => 'ς', - '𝝈' => 'σ', - '𝝉' => 'τ', - '𝝊' => 'υ', - '𝝋' => 'φ', - '𝝌' => 'χ', - '𝝍' => 'ψ', - '𝝎' => 'ω', - '𝝏' => '∂', - '𝝐' => 'ε', - '𝝑' => 'θ', - '𝝒' => 'κ', - '𝝓' => 'φ', - '𝝔' => 'ρ', - '𝝕' => 'π', - '𝝖' => 'Α', - '𝝗' => 'Β', - '𝝘' => 'Γ', - '𝝙' => 'Δ', - '𝝚' => 'Ε', - '𝝛' => 'Ζ', - '𝝜' => 'Η', - '𝝝' => 'Θ', - '𝝞' => 'Ι', - '𝝟' => 'Κ', - '𝝠' => 'Λ', - '𝝡' => 'Μ', - '𝝢' => 'Ν', - '𝝣' => 'Ξ', - '𝝤' => 'Ο', - '𝝥' => 'Π', - '𝝦' => 'Ρ', - '𝝧' => 'Θ', - '𝝨' => 'Σ', - '𝝩' => 'Τ', - '𝝪' => 'Υ', - '𝝫' => 'Φ', - '𝝬' => 'Χ', - '𝝭' => 'Ψ', - '𝝮' => 'Ω', - '𝝯' => '∇', - '𝝰' => 'α', - '𝝱' => 'β', - '𝝲' => 'γ', - '𝝳' => 'δ', - '𝝴' => 'ε', - '𝝵' => 'ζ', - '𝝶' => 'η', - '𝝷' => 'θ', - '𝝸' => 'ι', - '𝝹' => 'κ', - '𝝺' => 'λ', - '𝝻' => 'μ', - '𝝼' => 'ν', - '𝝽' => 'ξ', - '𝝾' => 'ο', - '𝝿' => 'π', - '𝞀' => 'ρ', - '𝞁' => 'ς', - '𝞂' => 'σ', - '𝞃' => 'τ', - '𝞄' => 'υ', - '𝞅' => 'φ', - '𝞆' => 'χ', - '𝞇' => 'ψ', - '𝞈' => 'ω', - '𝞉' => '∂', - '𝞊' => 'ε', - '𝞋' => 'θ', - '𝞌' => 'κ', - '𝞍' => 'φ', - '𝞎' => 'ρ', - '𝞏' => 'π', - '𝞐' => 'Α', - '𝞑' => 'Β', - '𝞒' => 'Γ', - '𝞓' => 'Δ', - '𝞔' => 'Ε', - '𝞕' => 'Ζ', - '𝞖' => 'Η', - '𝞗' => 'Θ', - '𝞘' => 'Ι', - '𝞙' => 'Κ', - '𝞚' => 'Λ', - '𝞛' => 'Μ', - '𝞜' => 'Ν', - '𝞝' => 'Ξ', - '𝞞' => 'Ο', - '𝞟' => 'Π', - '𝞠' => 'Ρ', - '𝞡' => 'Θ', - '𝞢' => 'Σ', - '𝞣' => 'Τ', - '𝞤' => 'Υ', - '𝞥' => 'Φ', - '𝞦' => 'Χ', - '𝞧' => 'Ψ', - '𝞨' => 'Ω', - '𝞩' => '∇', - '𝞪' => 'α', - '𝞫' => 'β', - '𝞬' => 'γ', - '𝞭' => 'δ', - '𝞮' => 'ε', - '𝞯' => 'ζ', - '𝞰' => 'η', - '𝞱' => 'θ', - '𝞲' => 'ι', - '𝞳' => 'κ', - '𝞴' => 'λ', - '𝞵' => 'μ', - '𝞶' => 'ν', - '𝞷' => 'ξ', - '𝞸' => 'ο', - '𝞹' => 'π', - '𝞺' => 'ρ', - '𝞻' => 'ς', - '𝞼' => 'σ', - '𝞽' => 'τ', - '𝞾' => 'υ', - '𝞿' => 'φ', - '𝟀' => 'χ', - '𝟁' => 'ψ', - '𝟂' => 'ω', - '𝟃' => '∂', - '𝟄' => 'ε', - '𝟅' => 'θ', - '𝟆' => 'κ', - '𝟇' => 'φ', - '𝟈' => 'ρ', - '𝟉' => 'π', - '𝟊' => 'Ϝ', - '𝟋' => 'ϝ', - '𝟎' => '0', - '𝟏' => '1', - '𝟐' => '2', - '𝟑' => '3', - '𝟒' => '4', - '𝟓' => '5', - '𝟔' => '6', - '𝟕' => '7', - '𝟖' => '8', - '𝟗' => '9', - '𝟘' => '0', - '𝟙' => '1', - '𝟚' => '2', - '𝟛' => '3', - '𝟜' => '4', - '𝟝' => '5', - '𝟞' => '6', - '𝟟' => '7', - '𝟠' => '8', - '𝟡' => '9', - '𝟢' => '0', - '𝟣' => '1', - '𝟤' => '2', - '𝟥' => '3', - '𝟦' => '4', - '𝟧' => '5', - '𝟨' => '6', - '𝟩' => '7', - '𝟪' => '8', - '𝟫' => '9', - '𝟬' => '0', - '𝟭' => '1', - '𝟮' => '2', - '𝟯' => '3', - '𝟰' => '4', - '𝟱' => '5', - '𝟲' => '6', - '𝟳' => '7', - '𝟴' => '8', - '𝟵' => '9', - '𝟶' => '0', - '𝟷' => '1', - '𝟸' => '2', - '𝟹' => '3', - '𝟺' => '4', - '𝟻' => '5', - '𝟼' => '6', - '𝟽' => '7', - '𝟾' => '8', - '𝟿' => '9', - '𞸀' => 'ا', - '𞸁' => 'ب', - '𞸂' => 'ج', - '𞸃' => 'د', - '𞸅' => 'و', - '𞸆' => 'ز', - '𞸇' => 'ح', - '𞸈' => 'ط', - '𞸉' => 'ي', - '𞸊' => 'ك', - '𞸋' => 'ل', - '𞸌' => 'م', - '𞸍' => 'ن', - '𞸎' => 'س', - '𞸏' => 'ع', - '𞸐' => 'ف', - '𞸑' => 'ص', - '𞸒' => 'ق', - '𞸓' => 'ر', - '𞸔' => 'ش', - '𞸕' => 'ت', - '𞸖' => 'ث', - '𞸗' => 'خ', - '𞸘' => 'ذ', - '𞸙' => 'ض', - '𞸚' => 'ظ', - '𞸛' => 'غ', - '𞸜' => 'ٮ', - '𞸝' => 'ں', - '𞸞' => 'ڡ', - '𞸟' => 'ٯ', - '𞸡' => 'ب', - '𞸢' => 'ج', - '𞸤' => 'ه', - '𞸧' => 'ح', - '𞸩' => 'ي', - '𞸪' => 'ك', - '𞸫' => 'ل', - '𞸬' => 'م', - '𞸭' => 'ن', - '𞸮' => 'س', - '𞸯' => 'ع', - '𞸰' => 'ف', - '𞸱' => 'ص', - '𞸲' => 'ق', - '𞸴' => 'ش', - '𞸵' => 'ت', - '𞸶' => 'ث', - '𞸷' => 'خ', - '𞸹' => 'ض', - '𞸻' => 'غ', - '𞹂' => 'ج', - '𞹇' => 'ح', - '𞹉' => 'ي', - '𞹋' => 'ل', - '𞹍' => 'ن', - '𞹎' => 'س', - '𞹏' => 'ع', - '𞹑' => 'ص', - '𞹒' => 'ق', - '𞹔' => 'ش', - '𞹗' => 'خ', - '𞹙' => 'ض', - '𞹛' => 'غ', - '𞹝' => 'ں', - '𞹟' => 'ٯ', - '𞹡' => 'ب', - '𞹢' => 'ج', - '𞹤' => 'ه', - '𞹧' => 'ح', - '𞹨' => 'ط', - '𞹩' => 'ي', - '𞹪' => 'ك', - '𞹬' => 'م', - '𞹭' => 'ن', - '𞹮' => 'س', - '𞹯' => 'ع', - '𞹰' => 'ف', - '𞹱' => 'ص', - '𞹲' => 'ق', - '𞹴' => 'ش', - '𞹵' => 'ت', - '𞹶' => 'ث', - '𞹷' => 'خ', - '𞹹' => 'ض', - '𞹺' => 'ظ', - '𞹻' => 'غ', - '𞹼' => 'ٮ', - '𞹾' => 'ڡ', - '𞺀' => 'ا', - '𞺁' => 'ب', - '𞺂' => 'ج', - '𞺃' => 'د', - '𞺄' => 'ه', - '𞺅' => 'و', - '𞺆' => 'ز', - '𞺇' => 'ح', - '𞺈' => 'ط', - '𞺉' => 'ي', - '𞺋' => 'ل', - '𞺌' => 'م', - '𞺍' => 'ن', - '𞺎' => 'س', - '𞺏' => 'ع', - '𞺐' => 'ف', - '𞺑' => 'ص', - '𞺒' => 'ق', - '𞺓' => 'ر', - '𞺔' => 'ش', - '𞺕' => 'ت', - '𞺖' => 'ث', - '𞺗' => 'خ', - '𞺘' => 'ذ', - '𞺙' => 'ض', - '𞺚' => 'ظ', - '𞺛' => 'غ', - '𞺡' => 'ب', - '𞺢' => 'ج', - '𞺣' => 'د', - '𞺥' => 'و', - '𞺦' => 'ز', - '𞺧' => 'ح', - '𞺨' => 'ط', - '𞺩' => 'ي', - '𞺫' => 'ل', - '𞺬' => 'م', - '𞺭' => 'ن', - '𞺮' => 'س', - '𞺯' => 'ع', - '𞺰' => 'ف', - '𞺱' => 'ص', - '𞺲' => 'ق', - '𞺳' => 'ر', - '𞺴' => 'ش', - '𞺵' => 'ت', - '𞺶' => 'ث', - '𞺷' => 'خ', - '𞺸' => 'ذ', - '𞺹' => 'ض', - '𞺺' => 'ظ', - '𞺻' => 'غ', - '🄀' => '0.', - '🄁' => '0,', - '🄂' => '1,', - '🄃' => '2,', - '🄄' => '3,', - '🄅' => '4,', - '🄆' => '5,', - '🄇' => '6,', - '🄈' => '7,', - '🄉' => '8,', - '🄊' => '9,', - '🄐' => '(A)', - '🄑' => '(B)', - '🄒' => '(C)', - '🄓' => '(D)', - '🄔' => '(E)', - '🄕' => '(F)', - '🄖' => '(G)', - '🄗' => '(H)', - '🄘' => '(I)', - '🄙' => '(J)', - '🄚' => '(K)', - '🄛' => '(L)', - '🄜' => '(M)', - '🄝' => '(N)', - '🄞' => '(O)', - '🄟' => '(P)', - '🄠' => '(Q)', - '🄡' => '(R)', - '🄢' => '(S)', - '🄣' => '(T)', - '🄤' => '(U)', - '🄥' => '(V)', - '🄦' => '(W)', - '🄧' => '(X)', - '🄨' => '(Y)', - '🄩' => '(Z)', - '🄪' => '〔S〕', - '🄫' => 'C', - '🄬' => 'R', - '🄭' => 'CD', - '🄮' => 'WZ', - '🄰' => 'A', - '🄱' => 'B', - '🄲' => 'C', - '🄳' => 'D', - '🄴' => 'E', - '🄵' => 'F', - '🄶' => 'G', - '🄷' => 'H', - '🄸' => 'I', - '🄹' => 'J', - '🄺' => 'K', - '🄻' => 'L', - '🄼' => 'M', - '🄽' => 'N', - '🄾' => 'O', - '🄿' => 'P', - '🅀' => 'Q', - '🅁' => 'R', - '🅂' => 'S', - '🅃' => 'T', - '🅄' => 'U', - '🅅' => 'V', - '🅆' => 'W', - '🅇' => 'X', - '🅈' => 'Y', - '🅉' => 'Z', - '🅊' => 'HV', - '🅋' => 'MV', - '🅌' => 'SD', - '🅍' => 'SS', - '🅎' => 'PPV', - '🅏' => 'WC', - '🅪' => 'MC', - '🅫' => 'MD', - '🅬' => 'MR', - '🆐' => 'DJ', - '🈀' => 'ほか', - '🈁' => 'ココ', - '🈂' => 'サ', - '🈐' => '手', - '🈑' => '字', - '🈒' => '双', - '🈓' => 'デ', - '🈔' => '二', - '🈕' => '多', - '🈖' => '解', - '🈗' => '天', - '🈘' => '交', - '🈙' => '映', - '🈚' => '無', - '🈛' => '料', - '🈜' => '前', - '🈝' => '後', - '🈞' => '再', - '🈟' => '新', - '🈠' => '初', - '🈡' => '終', - '🈢' => '生', - '🈣' => '販', - '🈤' => '声', - '🈥' => '吹', - '🈦' => '演', - '🈧' => '投', - '🈨' => '捕', - '🈩' => '一', - '🈪' => '三', - '🈫' => '遊', - '🈬' => '左', - '🈭' => '中', - '🈮' => '右', - '🈯' => '指', - '🈰' => '走', - '🈱' => '打', - '🈲' => '禁', - '🈳' => '空', - '🈴' => '合', - '🈵' => '満', - '🈶' => '有', - '🈷' => '月', - '🈸' => '申', - '🈹' => '割', - '🈺' => '営', - '🈻' => '配', - '🉀' => '〔本〕', - '🉁' => '〔三〕', - '🉂' => '〔二〕', - '🉃' => '〔安〕', - '🉄' => '〔点〕', - '🉅' => '〔打〕', - '🉆' => '〔盗〕', - '🉇' => '〔勝〕', - '🉈' => '〔敗〕', - '🉐' => '得', - '🉑' => '可', - '🯰' => '0', - '🯱' => '1', - '🯲' => '2', - '🯳' => '3', - '🯴' => '4', - '🯵' => '5', - '🯶' => '6', - '🯷' => '7', - '🯸' => '8', - '🯹' => '9', -); diff --git a/vendor/symfony/polyfill-intl-normalizer/bootstrap.php b/vendor/symfony/polyfill-intl-normalizer/bootstrap.php deleted file mode 100644 index 3608e5c05..000000000 --- a/vendor/symfony/polyfill-intl-normalizer/bootstrap.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Intl\Normalizer as p; - -if (\PHP_VERSION_ID >= 80000) { - return require __DIR__.'/bootstrap80.php'; -} - -if (!function_exists('normalizer_is_normalized')) { - function normalizer_is_normalized($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::isNormalized($string, $form); } -} -if (!function_exists('normalizer_normalize')) { - function normalizer_normalize($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::normalize($string, $form); } -} diff --git a/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php b/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php deleted file mode 100644 index e36d1a947..000000000 --- a/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Intl\Normalizer as p; - -if (!function_exists('normalizer_is_normalized')) { - function normalizer_is_normalized(?string $string, ?int $form = p\Normalizer::FORM_C): bool { return p\Normalizer::isNormalized((string) $string, (int) $form); } -} -if (!function_exists('normalizer_normalize')) { - function normalizer_normalize(?string $string, ?int $form = p\Normalizer::FORM_C): string|false { return p\Normalizer::normalize((string) $string, (int) $form); } -} diff --git a/vendor/symfony/polyfill-mbstring/Mbstring.php b/vendor/symfony/polyfill-mbstring/Mbstring.php deleted file mode 100644 index b65c54a6b..000000000 --- a/vendor/symfony/polyfill-mbstring/Mbstring.php +++ /dev/null @@ -1,873 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Mbstring; - -/** - * Partial mbstring implementation in PHP, iconv based, UTF-8 centric. - * - * Implemented: - * - mb_chr - Returns a specific character from its Unicode code point - * - mb_convert_encoding - Convert character encoding - * - mb_convert_variables - Convert character code in variable(s) - * - mb_decode_mimeheader - Decode string in MIME header field - * - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED - * - mb_decode_numericentity - Decode HTML numeric string reference to character - * - mb_encode_numericentity - Encode character to HTML numeric string reference - * - mb_convert_case - Perform case folding on a string - * - mb_detect_encoding - Detect character encoding - * - mb_get_info - Get internal settings of mbstring - * - mb_http_input - Detect HTTP input character encoding - * - mb_http_output - Set/Get HTTP output character encoding - * - mb_internal_encoding - Set/Get internal character encoding - * - mb_list_encodings - Returns an array of all supported encodings - * - mb_ord - Returns the Unicode code point of a character - * - mb_output_handler - Callback function converts character encoding in output buffer - * - mb_scrub - Replaces ill-formed byte sequences with substitute characters - * - mb_strlen - Get string length - * - mb_strpos - Find position of first occurrence of string in a string - * - mb_strrpos - Find position of last occurrence of a string in a string - * - mb_str_split - Convert a string to an array - * - mb_strtolower - Make a string lowercase - * - mb_strtoupper - Make a string uppercase - * - mb_substitute_character - Set/Get substitution character - * - mb_substr - Get part of string - * - mb_stripos - Finds position of first occurrence of a string within another, case insensitive - * - mb_stristr - Finds first occurrence of a string within another, case insensitive - * - mb_strrchr - Finds the last occurrence of a character in a string within another - * - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive - * - mb_strripos - Finds position of last occurrence of a string within another, case insensitive - * - mb_strstr - Finds first occurrence of a string within another - * - mb_strwidth - Return width of string - * - mb_substr_count - Count the number of substring occurrences - * - * Not implemented: - * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more) - * - mb_ereg_* - Regular expression with multibyte support - * - mb_parse_str - Parse GET/POST/COOKIE data and set global variable - * - mb_preferred_mime_name - Get MIME charset string - * - mb_regex_encoding - Returns current encoding for multibyte regex as string - * - mb_regex_set_options - Set/Get the default options for mbregex functions - * - mb_send_mail - Send encoded mail - * - mb_split - Split multibyte string using regular expression - * - mb_strcut - Get part of string - * - mb_strimwidth - Get truncated string with specified width - * - * @author Nicolas Grekas - * - * @internal - */ -final class Mbstring -{ - public const MB_CASE_FOLD = \PHP_INT_MAX; - - private const CASE_FOLD = [ - ['µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"], - ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'], - ]; - - 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($fromEncoding) || ($fromEncoding !== null && 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) { - $s = str_replace(self::CASE_FOLD[0], self::CASE_FOLD[1], $s); - } - - 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; - } - - return self::mb_detect_encoding($var, [$encoding]) || false !== @\iconv($encoding, $encoding, $var); - } - - public static function mb_detect_encoding($str, $encodingList = null, $strict = false) - { - if (null === $encodingList) { - $encodingList = self::$encodingList; - } else { - if (!\is_array($encodingList)) { - $encodingList = array_map('trim', explode(',', $encodingList)); - } - $encodingList = array_map('strtoupper', $encodingList); - } - - foreach ($encodingList as $enc) { - switch ($enc) { - case 'ASCII': - if (!preg_match('/[\x80-\xFF]/', $str)) { - return $enc; - } - break; - - case 'UTF8': - case 'UTF-8': - if (preg_match('//u', $str)) { - return 'UTF-8'; - } - break; - - default: - if (0 === strncmp($enc, 'ISO-8859-', 9)) { - return $enc; - } - } - } - - return false; - } - - public static function mb_detect_order($encodingList = null) - { - if (null === $encodingList) { - return self::$encodingList; - } - - if (!\is_array($encodingList)) { - $encodingList = array_map('trim', explode(',', $encodingList)); - } - $encodingList = array_map('strtoupper', $encodingList); - - foreach ($encodingList as $enc) { - switch ($enc) { - default: - if (strncmp($enc, 'ISO-8859-', 9)) { - return false; - } - // no break - case 'ASCII': - case 'UTF8': - case 'UTF-8': - } - } - - self::$encodingList = $encodingList; - - return true; - } - - public static function mb_strlen($s, $encoding = null) - { - $encoding = self::getEncoding($encoding); - if ('CP850' === $encoding || 'ASCII' === $encoding) { - return \strlen($s); - } - - return @\iconv_strlen($s, $encoding); - } - - public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) - { - $encoding = self::getEncoding($encoding); - if ('CP850' === $encoding || 'ASCII' === $encoding) { - return strpos($haystack, $needle, $offset); - } - - $needle = (string) $needle; - if ('' === $needle) { - 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, null, \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 = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding); - $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding); - - return self::mb_strpos($haystack, $needle, $offset, $encoding); - } - - public static function mb_stristr($haystack, $needle, $part = false, $encoding = null) - { - $pos = self::mb_stripos($haystack, $needle, 0, $encoding); - - return self::getSubpart($pos, $part, $haystack, $encoding); - } - - public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null) - { - $encoding = self::getEncoding($encoding); - if ('CP850' === $encoding || 'ASCII' === $encoding) { - $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, self::MB_CASE_FOLD, $encoding); - $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding); - - return self::mb_strrpos($haystack, $needle, $offset, $encoding); - } - - public static function mb_strstr($haystack, $needle, $part = false, $encoding = null) - { - $pos = strpos($haystack, $needle); - if (false === $pos) { - return false; - } - if ($part) { - return substr($haystack, 0, $pos); - } - - return substr($haystack, $pos); - } - - public static function mb_get_info($type = 'all') - { - $info = [ - 'internal_encoding' => self::$internalEncoding, - 'http_output' => 'pass', - 'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)', - 'func_overload' => 0, - 'func_overload_list' => 'no overload', - 'mail_charset' => 'UTF-8', - 'mail_header_encoding' => 'BASE64', - 'mail_body_encoding' => 'BASE64', - 'illegal_chars' => 0, - 'encoding_translation' => 'Off', - 'language' => self::$language, - 'detect_order' => self::$encodingList, - 'substitute_character' => 'none', - 'strict_detection' => 'Off', - ]; - - if ('all' === $type) { - return $info; - } - if (isset($info[$type])) { - return $info[$type]; - } - - return false; - } - - public static function mb_http_input($type = '') - { - return false; - } - - public static function mb_http_output($encoding = null) - { - return null !== $encoding ? 'pass' === $encoding : 'pass'; - } - - public static function mb_strwidth($s, $encoding = null) - { - $encoding = self::getEncoding($encoding); - - if ('UTF-8' !== $encoding) { - $s = \iconv($encoding, 'UTF-8//IGNORE', $s); - } - - $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide); - - return ($wide << 1) + \iconv_strlen($s, 'UTF-8'); - } - - public static function mb_substr_count($haystack, $needle, $encoding = null) - { - return substr_count($haystack, $needle); - } - - public static function mb_output_handler($contents, $status) - { - return $contents; - } - - public static function mb_chr($code, $encoding = null) - { - if (0x80 > $code %= 0x200000) { - $s = \chr($code); - } elseif (0x800 > $code) { - $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F); - } elseif (0x10000 > $code) { - $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); - } else { - $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); - } - - if ('UTF-8' !== $encoding = self::getEncoding($encoding)) { - $s = mb_convert_encoding($s, $encoding, 'UTF-8'); - } - - return $s; - } - - public static function mb_ord($s, $encoding = null) - { - if ('UTF-8' !== $encoding = self::getEncoding($encoding)) { - $s = mb_convert_encoding($s, 'UTF-8', $encoding); - } - - if (1 === \strlen($s)) { - return \ord($s); - } - - $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0; - if (0xF0 <= $code) { - return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80; - } - if (0xE0 <= $code) { - return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80; - } - if (0xC0 <= $code) { - return (($code - 0xC0) << 6) + $s[2] - 0x80; - } - - return $code; - } - - private static function getSubpart($pos, $part, $haystack, $encoding) - { - if (false === $pos) { - return false; - } - if ($part) { - return self::mb_substr($haystack, 0, $pos, $encoding); - } - - return self::mb_substr($haystack, $pos, null, $encoding); - } - - private static function html_encoding_callback(array $m) - { - $i = 1; - $entities = ''; - $m = unpack('C*', htmlentities($m[0], \ENT_COMPAT, 'UTF-8')); - - while (isset($m[$i])) { - if (0x80 > $m[$i]) { - $entities .= \chr($m[$i++]); - continue; - } - if (0xF0 <= $m[$i]) { - $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80; - } elseif (0xE0 <= $m[$i]) { - $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80; - } else { - $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80; - } - - $entities .= '&#'.$c.';'; - } - - return $entities; - } - - private static function title_case(array $s) - { - return self::mb_convert_case($s[1], \MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], \MB_CASE_LOWER, 'UTF-8'); - } - - private static function getData($file) - { - if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) { - return require $file; - } - - return false; - } - - private static function getEncoding($encoding) - { - if (null === $encoding) { - return self::$internalEncoding; - } - - if ('UTF-8' === $encoding) { - return 'UTF-8'; - } - - $encoding = strtoupper($encoding); - - if ('8BIT' === $encoding || 'BINARY' === $encoding) { - return 'CP850'; - } - - if ('UTF8' === $encoding) { - return 'UTF-8'; - } - - return $encoding; - } -} diff --git a/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php b/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php deleted file mode 100644 index fac60b081..000000000 --- a/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php +++ /dev/null @@ -1,1397 +0,0 @@ - 'a', - 'B' => 'b', - 'C' => 'c', - 'D' => 'd', - 'E' => 'e', - 'F' => 'f', - 'G' => 'g', - 'H' => 'h', - 'I' => 'i', - 'J' => 'j', - 'K' => 'k', - 'L' => 'l', - 'M' => 'm', - 'N' => 'n', - 'O' => 'o', - 'P' => 'p', - 'Q' => 'q', - 'R' => 'r', - 'S' => 's', - 'T' => 't', - 'U' => 'u', - 'V' => 'v', - 'W' => 'w', - 'X' => 'x', - 'Y' => 'y', - 'Z' => 'z', - 'À' => 'à', - 'Á' => 'á', - 'Â' => 'â', - 'Ã' => 'ã', - 'Ä' => 'ä', - 'Å' => 'å', - 'Æ' => 'æ', - 'Ç' => 'ç', - 'È' => 'è', - 'É' => 'é', - 'Ê' => 'ê', - 'Ë' => 'ë', - 'Ì' => 'ì', - 'Í' => 'í', - 'Î' => 'î', - 'Ï' => 'ï', - 'Ð' => 'ð', - 'Ñ' => 'ñ', - 'Ò' => 'ò', - 'Ó' => 'ó', - 'Ô' => 'ô', - 'Õ' => 'õ', - 'Ö' => 'ö', - 'Ø' => 'ø', - 'Ù' => 'ù', - 'Ú' => 'ú', - 'Û' => 'û', - 'Ü' => 'ü', - 'Ý' => 'ý', - 'Þ' => 'þ', - 'Ā' => 'ā', - 'Ă' => 'ă', - 'Ą' => 'ą', - 'Ć' => 'ć', - 'Ĉ' => 'ĉ', - 'Ċ' => 'ċ', - 'Č' => 'č', - 'Ď' => 'ď', - 'Đ' => 'đ', - 'Ē' => 'ē', - 'Ĕ' => 'ĕ', - 'Ė' => 'ė', - 'Ę' => 'ę', - 'Ě' => 'ě', - 'Ĝ' => 'ĝ', - 'Ğ' => 'ğ', - 'Ġ' => 'ġ', - 'Ģ' => 'ģ', - 'Ĥ' => 'ĥ', - 'Ħ' => 'ħ', - 'Ĩ' => 'ĩ', - 'Ī' => 'ī', - 'Ĭ' => 'ĭ', - 'Į' => 'į', - 'İ' => 'i̇', - 'IJ' => 'ij', - 'Ĵ' => 'ĵ', - 'Ķ' => 'ķ', - 'Ĺ' => 'ĺ', - 'Ļ' => 'ļ', - 'Ľ' => 'ľ', - 'Ŀ' => 'ŀ', - 'Ł' => 'ł', - 'Ń' => 'ń', - 'Ņ' => 'ņ', - 'Ň' => 'ň', - 'Ŋ' => 'ŋ', - 'Ō' => 'ō', - 'Ŏ' => 'ŏ', - 'Ő' => 'ő', - 'Œ' => 'œ', - 'Ŕ' => 'ŕ', - 'Ŗ' => 'ŗ', - 'Ř' => 'ř', - 'Ś' => 'ś', - 'Ŝ' => 'ŝ', - 'Ş' => 'ş', - 'Š' => 'š', - 'Ţ' => 'ţ', - 'Ť' => 'ť', - 'Ŧ' => 'ŧ', - 'Ũ' => 'ũ', - 'Ū' => 'ū', - 'Ŭ' => 'ŭ', - 'Ů' => 'ů', - 'Ű' => 'ű', - 'Ų' => 'ų', - 'Ŵ' => 'ŵ', - 'Ŷ' => 'ŷ', - 'Ÿ' => 'ÿ', - 'Ź' => 'ź', - 'Ż' => 'ż', - 'Ž' => 'ž', - 'Ɓ' => 'ɓ', - 'Ƃ' => 'ƃ', - 'Ƅ' => 'ƅ', - 'Ɔ' => 'ɔ', - 'Ƈ' => 'ƈ', - 'Ɖ' => 'ɖ', - 'Ɗ' => 'ɗ', - 'Ƌ' => 'ƌ', - 'Ǝ' => 'ǝ', - 'Ə' => 'ə', - 'Ɛ' => 'ɛ', - 'Ƒ' => 'ƒ', - 'Ɠ' => 'ɠ', - 'Ɣ' => 'ɣ', - 'Ɩ' => 'ɩ', - 'Ɨ' => 'ɨ', - 'Ƙ' => 'ƙ', - 'Ɯ' => 'ɯ', - 'Ɲ' => 'ɲ', - 'Ɵ' => 'ɵ', - 'Ơ' => 'ơ', - 'Ƣ' => 'ƣ', - 'Ƥ' => 'ƥ', - 'Ʀ' => 'ʀ', - 'Ƨ' => 'ƨ', - 'Ʃ' => 'ʃ', - 'Ƭ' => 'ƭ', - 'Ʈ' => 'ʈ', - 'Ư' => 'ư', - 'Ʊ' => 'ʊ', - 'Ʋ' => 'ʋ', - 'Ƴ' => 'ƴ', - 'Ƶ' => 'ƶ', - 'Ʒ' => 'ʒ', - 'Ƹ' => 'ƹ', - 'Ƽ' => 'ƽ', - 'DŽ' => 'dž', - 'Dž' => 'dž', - 'LJ' => 'lj', - 'Lj' => 'lj', - 'NJ' => 'nj', - 'Nj' => 'nj', - 'Ǎ' => 'ǎ', - 'Ǐ' => 'ǐ', - 'Ǒ' => 'ǒ', - 'Ǔ' => 'ǔ', - 'Ǖ' => 'ǖ', - 'Ǘ' => 'ǘ', - 'Ǚ' => 'ǚ', - 'Ǜ' => 'ǜ', - 'Ǟ' => 'ǟ', - 'Ǡ' => 'ǡ', - 'Ǣ' => 'ǣ', - 'Ǥ' => 'ǥ', - 'Ǧ' => 'ǧ', - 'Ǩ' => 'ǩ', - 'Ǫ' => 'ǫ', - 'Ǭ' => 'ǭ', - 'Ǯ' => 'ǯ', - 'DZ' => 'dz', - 'Dz' => 'dz', - 'Ǵ' => 'ǵ', - 'Ƕ' => 'ƕ', - 'Ƿ' => 'ƿ', - 'Ǹ' => 'ǹ', - 'Ǻ' => 'ǻ', - 'Ǽ' => 'ǽ', - 'Ǿ' => 'ǿ', - 'Ȁ' => 'ȁ', - 'Ȃ' => 'ȃ', - 'Ȅ' => 'ȅ', - 'Ȇ' => 'ȇ', - 'Ȉ' => 'ȉ', - 'Ȋ' => 'ȋ', - 'Ȍ' => 'ȍ', - 'Ȏ' => 'ȏ', - 'Ȑ' => 'ȑ', - 'Ȓ' => 'ȓ', - 'Ȕ' => 'ȕ', - 'Ȗ' => 'ȗ', - 'Ș' => 'ș', - 'Ț' => 'ț', - 'Ȝ' => 'ȝ', - 'Ȟ' => 'ȟ', - 'Ƞ' => 'ƞ', - 'Ȣ' => 'ȣ', - 'Ȥ' => 'ȥ', - 'Ȧ' => 'ȧ', - 'Ȩ' => 'ȩ', - 'Ȫ' => 'ȫ', - 'Ȭ' => 'ȭ', - 'Ȯ' => 'ȯ', - 'Ȱ' => 'ȱ', - 'Ȳ' => 'ȳ', - 'Ⱥ' => 'ⱥ', - 'Ȼ' => 'ȼ', - 'Ƚ' => 'ƚ', - 'Ⱦ' => 'ⱦ', - 'Ɂ' => 'ɂ', - 'Ƀ' => 'ƀ', - 'Ʉ' => 'ʉ', - 'Ʌ' => 'ʌ', - 'Ɇ' => 'ɇ', - 'Ɉ' => 'ɉ', - 'Ɋ' => 'ɋ', - 'Ɍ' => 'ɍ', - 'Ɏ' => 'ɏ', - 'Ͱ' => 'ͱ', - 'Ͳ' => 'ͳ', - 'Ͷ' => 'ͷ', - 'Ϳ' => 'ϳ', - 'Ά' => 'ά', - 'Έ' => 'έ', - 'Ή' => 'ή', - 'Ί' => 'ί', - 'Ό' => 'ό', - 'Ύ' => 'ύ', - 'Ώ' => 'ώ', - 'Α' => 'α', - 'Β' => 'β', - 'Γ' => 'γ', - 'Δ' => 'δ', - 'Ε' => 'ε', - 'Ζ' => 'ζ', - 'Η' => 'η', - 'Θ' => 'θ', - 'Ι' => 'ι', - 'Κ' => 'κ', - 'Λ' => 'λ', - 'Μ' => 'μ', - 'Ν' => 'ν', - 'Ξ' => 'ξ', - 'Ο' => 'ο', - 'Π' => 'π', - 'Ρ' => 'ρ', - 'Σ' => 'σ', - 'Τ' => 'τ', - 'Υ' => 'υ', - 'Φ' => 'φ', - 'Χ' => 'χ', - 'Ψ' => 'ψ', - 'Ω' => 'ω', - 'Ϊ' => 'ϊ', - 'Ϋ' => 'ϋ', - 'Ϗ' => 'ϗ', - 'Ϙ' => 'ϙ', - 'Ϛ' => 'ϛ', - 'Ϝ' => 'ϝ', - 'Ϟ' => 'ϟ', - 'Ϡ' => 'ϡ', - 'Ϣ' => 'ϣ', - 'Ϥ' => 'ϥ', - 'Ϧ' => 'ϧ', - 'Ϩ' => 'ϩ', - 'Ϫ' => 'ϫ', - 'Ϭ' => 'ϭ', - 'Ϯ' => 'ϯ', - 'ϴ' => 'θ', - 'Ϸ' => 'ϸ', - 'Ϲ' => 'ϲ', - 'Ϻ' => 'ϻ', - 'Ͻ' => 'ͻ', - 'Ͼ' => 'ͼ', - 'Ͽ' => 'ͽ', - 'Ѐ' => 'ѐ', - 'Ё' => 'ё', - 'Ђ' => 'ђ', - 'Ѓ' => 'ѓ', - 'Є' => 'є', - 'Ѕ' => 'ѕ', - 'І' => 'і', - 'Ї' => 'ї', - 'Ј' => 'ј', - 'Љ' => 'љ', - 'Њ' => 'њ', - 'Ћ' => 'ћ', - 'Ќ' => 'ќ', - 'Ѝ' => 'ѝ', - 'Ў' => 'ў', - 'Џ' => 'џ', - 'А' => 'а', - 'Б' => 'б', - 'В' => 'в', - 'Г' => 'г', - 'Д' => 'д', - 'Е' => 'е', - 'Ж' => 'ж', - 'З' => 'з', - 'И' => 'и', - 'Й' => 'й', - 'К' => 'к', - 'Л' => 'л', - 'М' => 'м', - 'Н' => 'н', - 'О' => 'о', - 'П' => 'п', - 'Р' => 'р', - 'С' => 'с', - 'Т' => 'т', - 'У' => 'у', - 'Ф' => 'ф', - 'Х' => 'х', - 'Ц' => 'ц', - 'Ч' => 'ч', - 'Ш' => 'ш', - 'Щ' => 'щ', - 'Ъ' => 'ъ', - 'Ы' => 'ы', - 'Ь' => 'ь', - 'Э' => 'э', - 'Ю' => 'ю', - 'Я' => 'я', - 'Ѡ' => 'ѡ', - 'Ѣ' => 'ѣ', - 'Ѥ' => 'ѥ', - 'Ѧ' => 'ѧ', - 'Ѩ' => 'ѩ', - 'Ѫ' => 'ѫ', - 'Ѭ' => 'ѭ', - 'Ѯ' => 'ѯ', - 'Ѱ' => 'ѱ', - 'Ѳ' => 'ѳ', - 'Ѵ' => 'ѵ', - 'Ѷ' => 'ѷ', - 'Ѹ' => 'ѹ', - 'Ѻ' => 'ѻ', - 'Ѽ' => 'ѽ', - 'Ѿ' => 'ѿ', - 'Ҁ' => 'ҁ', - 'Ҋ' => 'ҋ', - 'Ҍ' => 'ҍ', - 'Ҏ' => 'ҏ', - 'Ґ' => 'ґ', - 'Ғ' => 'ғ', - 'Ҕ' => 'ҕ', - 'Җ' => 'җ', - 'Ҙ' => 'ҙ', - 'Қ' => 'қ', - 'Ҝ' => 'ҝ', - 'Ҟ' => 'ҟ', - 'Ҡ' => 'ҡ', - 'Ң' => 'ң', - 'Ҥ' => 'ҥ', - 'Ҧ' => 'ҧ', - 'Ҩ' => 'ҩ', - 'Ҫ' => 'ҫ', - 'Ҭ' => 'ҭ', - 'Ү' => 'ү', - 'Ұ' => 'ұ', - 'Ҳ' => 'ҳ', - 'Ҵ' => 'ҵ', - 'Ҷ' => 'ҷ', - 'Ҹ' => 'ҹ', - 'Һ' => 'һ', - 'Ҽ' => 'ҽ', - 'Ҿ' => 'ҿ', - 'Ӏ' => 'ӏ', - 'Ӂ' => 'ӂ', - 'Ӄ' => 'ӄ', - 'Ӆ' => 'ӆ', - 'Ӈ' => 'ӈ', - 'Ӊ' => 'ӊ', - 'Ӌ' => 'ӌ', - 'Ӎ' => 'ӎ', - 'Ӑ' => 'ӑ', - 'Ӓ' => 'ӓ', - 'Ӕ' => 'ӕ', - 'Ӗ' => 'ӗ', - 'Ә' => 'ә', - 'Ӛ' => 'ӛ', - 'Ӝ' => 'ӝ', - 'Ӟ' => 'ӟ', - 'Ӡ' => 'ӡ', - 'Ӣ' => 'ӣ', - 'Ӥ' => 'ӥ', - 'Ӧ' => 'ӧ', - 'Ө' => 'ө', - 'Ӫ' => 'ӫ', - 'Ӭ' => 'ӭ', - 'Ӯ' => 'ӯ', - 'Ӱ' => 'ӱ', - 'Ӳ' => 'ӳ', - 'Ӵ' => 'ӵ', - 'Ӷ' => 'ӷ', - 'Ӹ' => 'ӹ', - 'Ӻ' => 'ӻ', - 'Ӽ' => 'ӽ', - 'Ӿ' => 'ӿ', - 'Ԁ' => 'ԁ', - 'Ԃ' => 'ԃ', - 'Ԅ' => 'ԅ', - 'Ԇ' => 'ԇ', - 'Ԉ' => 'ԉ', - 'Ԋ' => 'ԋ', - 'Ԍ' => 'ԍ', - 'Ԏ' => 'ԏ', - 'Ԑ' => 'ԑ', - 'Ԓ' => 'ԓ', - 'Ԕ' => 'ԕ', - 'Ԗ' => 'ԗ', - 'Ԙ' => 'ԙ', - 'Ԛ' => 'ԛ', - 'Ԝ' => 'ԝ', - 'Ԟ' => 'ԟ', - 'Ԡ' => 'ԡ', - 'Ԣ' => 'ԣ', - 'Ԥ' => 'ԥ', - 'Ԧ' => 'ԧ', - 'Ԩ' => 'ԩ', - 'Ԫ' => 'ԫ', - 'Ԭ' => 'ԭ', - 'Ԯ' => 'ԯ', - 'Ա' => 'ա', - 'Բ' => 'բ', - 'Գ' => 'գ', - 'Դ' => 'դ', - 'Ե' => 'ե', - 'Զ' => 'զ', - 'Է' => 'է', - 'Ը' => 'ը', - 'Թ' => 'թ', - 'Ժ' => 'ժ', - 'Ի' => 'ի', - 'Լ' => 'լ', - 'Խ' => 'խ', - 'Ծ' => 'ծ', - 'Կ' => 'կ', - 'Հ' => 'հ', - 'Ձ' => 'ձ', - 'Ղ' => 'ղ', - 'Ճ' => 'ճ', - 'Մ' => 'մ', - 'Յ' => 'յ', - 'Ն' => 'ն', - 'Շ' => 'շ', - 'Ո' => 'ո', - 'Չ' => 'չ', - 'Պ' => 'պ', - 'Ջ' => 'ջ', - 'Ռ' => 'ռ', - 'Ս' => 'ս', - 'Վ' => 'վ', - 'Տ' => 'տ', - 'Ր' => 'ր', - 'Ց' => 'ց', - 'Ւ' => 'ւ', - 'Փ' => 'փ', - 'Ք' => 'ք', - 'Օ' => 'օ', - 'Ֆ' => 'ֆ', - 'Ⴀ' => 'ⴀ', - 'Ⴁ' => 'ⴁ', - 'Ⴂ' => 'ⴂ', - 'Ⴃ' => 'ⴃ', - 'Ⴄ' => 'ⴄ', - 'Ⴅ' => 'ⴅ', - 'Ⴆ' => 'ⴆ', - 'Ⴇ' => 'ⴇ', - 'Ⴈ' => 'ⴈ', - 'Ⴉ' => 'ⴉ', - 'Ⴊ' => 'ⴊ', - 'Ⴋ' => 'ⴋ', - 'Ⴌ' => 'ⴌ', - 'Ⴍ' => 'ⴍ', - 'Ⴎ' => 'ⴎ', - 'Ⴏ' => 'ⴏ', - 'Ⴐ' => 'ⴐ', - 'Ⴑ' => 'ⴑ', - 'Ⴒ' => 'ⴒ', - 'Ⴓ' => 'ⴓ', - 'Ⴔ' => 'ⴔ', - 'Ⴕ' => 'ⴕ', - 'Ⴖ' => 'ⴖ', - 'Ⴗ' => 'ⴗ', - 'Ⴘ' => 'ⴘ', - 'Ⴙ' => 'ⴙ', - 'Ⴚ' => 'ⴚ', - 'Ⴛ' => 'ⴛ', - 'Ⴜ' => 'ⴜ', - 'Ⴝ' => 'ⴝ', - 'Ⴞ' => 'ⴞ', - 'Ⴟ' => 'ⴟ', - 'Ⴠ' => 'ⴠ', - 'Ⴡ' => 'ⴡ', - 'Ⴢ' => 'ⴢ', - 'Ⴣ' => 'ⴣ', - 'Ⴤ' => 'ⴤ', - 'Ⴥ' => 'ⴥ', - 'Ⴧ' => 'ⴧ', - 'Ⴭ' => 'ⴭ', - 'Ꭰ' => 'ꭰ', - 'Ꭱ' => 'ꭱ', - 'Ꭲ' => 'ꭲ', - 'Ꭳ' => 'ꭳ', - 'Ꭴ' => 'ꭴ', - 'Ꭵ' => 'ꭵ', - 'Ꭶ' => 'ꭶ', - 'Ꭷ' => 'ꭷ', - 'Ꭸ' => 'ꭸ', - 'Ꭹ' => 'ꭹ', - 'Ꭺ' => 'ꭺ', - 'Ꭻ' => 'ꭻ', - 'Ꭼ' => 'ꭼ', - 'Ꭽ' => 'ꭽ', - 'Ꭾ' => 'ꭾ', - 'Ꭿ' => 'ꭿ', - 'Ꮀ' => 'ꮀ', - 'Ꮁ' => 'ꮁ', - 'Ꮂ' => 'ꮂ', - 'Ꮃ' => 'ꮃ', - 'Ꮄ' => 'ꮄ', - 'Ꮅ' => 'ꮅ', - 'Ꮆ' => 'ꮆ', - 'Ꮇ' => 'ꮇ', - 'Ꮈ' => 'ꮈ', - 'Ꮉ' => 'ꮉ', - 'Ꮊ' => 'ꮊ', - 'Ꮋ' => 'ꮋ', - 'Ꮌ' => 'ꮌ', - 'Ꮍ' => 'ꮍ', - 'Ꮎ' => 'ꮎ', - 'Ꮏ' => 'ꮏ', - 'Ꮐ' => 'ꮐ', - 'Ꮑ' => 'ꮑ', - 'Ꮒ' => 'ꮒ', - 'Ꮓ' => 'ꮓ', - 'Ꮔ' => 'ꮔ', - 'Ꮕ' => 'ꮕ', - 'Ꮖ' => 'ꮖ', - 'Ꮗ' => 'ꮗ', - 'Ꮘ' => 'ꮘ', - 'Ꮙ' => 'ꮙ', - 'Ꮚ' => 'ꮚ', - 'Ꮛ' => 'ꮛ', - 'Ꮜ' => 'ꮜ', - 'Ꮝ' => 'ꮝ', - 'Ꮞ' => 'ꮞ', - 'Ꮟ' => 'ꮟ', - 'Ꮠ' => 'ꮠ', - 'Ꮡ' => 'ꮡ', - 'Ꮢ' => 'ꮢ', - 'Ꮣ' => 'ꮣ', - 'Ꮤ' => 'ꮤ', - 'Ꮥ' => 'ꮥ', - 'Ꮦ' => 'ꮦ', - 'Ꮧ' => 'ꮧ', - 'Ꮨ' => 'ꮨ', - 'Ꮩ' => 'ꮩ', - 'Ꮪ' => 'ꮪ', - 'Ꮫ' => 'ꮫ', - 'Ꮬ' => 'ꮬ', - 'Ꮭ' => 'ꮭ', - 'Ꮮ' => 'ꮮ', - 'Ꮯ' => 'ꮯ', - 'Ꮰ' => 'ꮰ', - 'Ꮱ' => 'ꮱ', - 'Ꮲ' => 'ꮲ', - 'Ꮳ' => 'ꮳ', - 'Ꮴ' => 'ꮴ', - 'Ꮵ' => 'ꮵ', - 'Ꮶ' => 'ꮶ', - 'Ꮷ' => 'ꮷ', - 'Ꮸ' => 'ꮸ', - 'Ꮹ' => 'ꮹ', - 'Ꮺ' => 'ꮺ', - 'Ꮻ' => 'ꮻ', - 'Ꮼ' => 'ꮼ', - 'Ꮽ' => 'ꮽ', - 'Ꮾ' => 'ꮾ', - 'Ꮿ' => 'ꮿ', - 'Ᏸ' => 'ᏸ', - 'Ᏹ' => 'ᏹ', - 'Ᏺ' => 'ᏺ', - 'Ᏻ' => 'ᏻ', - 'Ᏼ' => 'ᏼ', - 'Ᏽ' => 'ᏽ', - 'Ა' => 'ა', - 'Ბ' => 'ბ', - 'Გ' => 'გ', - 'Დ' => 'დ', - 'Ე' => 'ე', - 'Ვ' => 'ვ', - 'Ზ' => 'ზ', - 'Თ' => 'თ', - 'Ი' => 'ი', - 'Კ' => 'კ', - 'Ლ' => 'ლ', - 'Მ' => 'მ', - 'Ნ' => 'ნ', - 'Ო' => 'ო', - 'Პ' => 'პ', - 'Ჟ' => 'ჟ', - 'Რ' => 'რ', - 'Ს' => 'ს', - 'Ტ' => 'ტ', - 'Უ' => 'უ', - 'Ფ' => 'ფ', - 'Ქ' => 'ქ', - 'Ღ' => 'ღ', - 'Ყ' => 'ყ', - 'Შ' => 'შ', - 'Ჩ' => 'ჩ', - 'Ც' => 'ც', - 'Ძ' => 'ძ', - 'Წ' => 'წ', - 'Ჭ' => 'ჭ', - 'Ხ' => 'ხ', - 'Ჯ' => 'ჯ', - 'Ჰ' => 'ჰ', - 'Ჱ' => 'ჱ', - 'Ჲ' => 'ჲ', - 'Ჳ' => 'ჳ', - 'Ჴ' => 'ჴ', - 'Ჵ' => 'ჵ', - 'Ჶ' => 'ჶ', - 'Ჷ' => 'ჷ', - 'Ჸ' => 'ჸ', - 'Ჹ' => 'ჹ', - 'Ჺ' => 'ჺ', - 'Ჽ' => 'ჽ', - 'Ჾ' => 'ჾ', - 'Ჿ' => 'ჿ', - 'Ḁ' => 'ḁ', - 'Ḃ' => 'ḃ', - 'Ḅ' => 'ḅ', - 'Ḇ' => 'ḇ', - 'Ḉ' => 'ḉ', - 'Ḋ' => 'ḋ', - 'Ḍ' => 'ḍ', - 'Ḏ' => 'ḏ', - 'Ḑ' => 'ḑ', - 'Ḓ' => 'ḓ', - 'Ḕ' => 'ḕ', - 'Ḗ' => 'ḗ', - 'Ḙ' => 'ḙ', - 'Ḛ' => 'ḛ', - 'Ḝ' => 'ḝ', - 'Ḟ' => 'ḟ', - 'Ḡ' => 'ḡ', - 'Ḣ' => 'ḣ', - 'Ḥ' => 'ḥ', - 'Ḧ' => 'ḧ', - 'Ḩ' => 'ḩ', - 'Ḫ' => 'ḫ', - 'Ḭ' => 'ḭ', - 'Ḯ' => 'ḯ', - 'Ḱ' => 'ḱ', - 'Ḳ' => 'ḳ', - 'Ḵ' => 'ḵ', - 'Ḷ' => 'ḷ', - 'Ḹ' => 'ḹ', - 'Ḻ' => 'ḻ', - 'Ḽ' => 'ḽ', - 'Ḿ' => 'ḿ', - 'Ṁ' => 'ṁ', - 'Ṃ' => 'ṃ', - 'Ṅ' => 'ṅ', - 'Ṇ' => 'ṇ', - 'Ṉ' => 'ṉ', - 'Ṋ' => 'ṋ', - 'Ṍ' => 'ṍ', - 'Ṏ' => 'ṏ', - 'Ṑ' => 'ṑ', - 'Ṓ' => 'ṓ', - 'Ṕ' => 'ṕ', - 'Ṗ' => 'ṗ', - 'Ṙ' => 'ṙ', - 'Ṛ' => 'ṛ', - 'Ṝ' => 'ṝ', - 'Ṟ' => 'ṟ', - 'Ṡ' => 'ṡ', - 'Ṣ' => 'ṣ', - 'Ṥ' => 'ṥ', - 'Ṧ' => 'ṧ', - 'Ṩ' => 'ṩ', - 'Ṫ' => 'ṫ', - 'Ṭ' => 'ṭ', - 'Ṯ' => 'ṯ', - 'Ṱ' => 'ṱ', - 'Ṳ' => 'ṳ', - 'Ṵ' => 'ṵ', - 'Ṷ' => 'ṷ', - 'Ṹ' => 'ṹ', - 'Ṻ' => 'ṻ', - 'Ṽ' => 'ṽ', - 'Ṿ' => 'ṿ', - 'Ẁ' => 'ẁ', - 'Ẃ' => 'ẃ', - 'Ẅ' => 'ẅ', - 'Ẇ' => 'ẇ', - 'Ẉ' => 'ẉ', - 'Ẋ' => 'ẋ', - 'Ẍ' => 'ẍ', - 'Ẏ' => 'ẏ', - 'Ẑ' => 'ẑ', - 'Ẓ' => 'ẓ', - 'Ẕ' => 'ẕ', - 'ẞ' => 'ß', - 'Ạ' => 'ạ', - 'Ả' => 'ả', - 'Ấ' => 'ấ', - 'Ầ' => 'ầ', - 'Ẩ' => 'ẩ', - 'Ẫ' => 'ẫ', - 'Ậ' => 'ậ', - 'Ắ' => 'ắ', - 'Ằ' => 'ằ', - 'Ẳ' => 'ẳ', - 'Ẵ' => 'ẵ', - 'Ặ' => 'ặ', - 'Ẹ' => 'ẹ', - 'Ẻ' => 'ẻ', - 'Ẽ' => 'ẽ', - 'Ế' => 'ế', - 'Ề' => 'ề', - 'Ể' => 'ể', - 'Ễ' => 'ễ', - 'Ệ' => 'ệ', - 'Ỉ' => 'ỉ', - 'Ị' => 'ị', - 'Ọ' => 'ọ', - 'Ỏ' => 'ỏ', - 'Ố' => 'ố', - 'Ồ' => 'ồ', - 'Ổ' => 'ổ', - 'Ỗ' => 'ỗ', - 'Ộ' => 'ộ', - 'Ớ' => 'ớ', - 'Ờ' => 'ờ', - 'Ở' => 'ở', - 'Ỡ' => 'ỡ', - 'Ợ' => 'ợ', - 'Ụ' => 'ụ', - 'Ủ' => 'ủ', - 'Ứ' => 'ứ', - 'Ừ' => 'ừ', - 'Ử' => 'ử', - 'Ữ' => 'ữ', - 'Ự' => 'ự', - 'Ỳ' => 'ỳ', - 'Ỵ' => 'ỵ', - 'Ỷ' => 'ỷ', - 'Ỹ' => 'ỹ', - 'Ỻ' => 'ỻ', - 'Ỽ' => 'ỽ', - 'Ỿ' => 'ỿ', - 'Ἀ' => 'ἀ', - 'Ἁ' => 'ἁ', - 'Ἂ' => 'ἂ', - 'Ἃ' => 'ἃ', - 'Ἄ' => 'ἄ', - 'Ἅ' => 'ἅ', - 'Ἆ' => 'ἆ', - 'Ἇ' => 'ἇ', - 'Ἐ' => 'ἐ', - 'Ἑ' => 'ἑ', - 'Ἒ' => 'ἒ', - 'Ἓ' => 'ἓ', - 'Ἔ' => 'ἔ', - 'Ἕ' => 'ἕ', - 'Ἠ' => 'ἠ', - 'Ἡ' => 'ἡ', - 'Ἢ' => 'ἢ', - 'Ἣ' => 'ἣ', - 'Ἤ' => 'ἤ', - 'Ἥ' => 'ἥ', - 'Ἦ' => 'ἦ', - 'Ἧ' => 'ἧ', - 'Ἰ' => 'ἰ', - 'Ἱ' => 'ἱ', - 'Ἲ' => 'ἲ', - 'Ἳ' => 'ἳ', - 'Ἴ' => 'ἴ', - 'Ἵ' => 'ἵ', - 'Ἶ' => 'ἶ', - 'Ἷ' => 'ἷ', - 'Ὀ' => 'ὀ', - 'Ὁ' => 'ὁ', - 'Ὂ' => 'ὂ', - 'Ὃ' => 'ὃ', - 'Ὄ' => 'ὄ', - 'Ὅ' => 'ὅ', - 'Ὑ' => 'ὑ', - 'Ὓ' => 'ὓ', - 'Ὕ' => 'ὕ', - 'Ὗ' => 'ὗ', - 'Ὠ' => 'ὠ', - 'Ὡ' => 'ὡ', - 'Ὢ' => 'ὢ', - 'Ὣ' => 'ὣ', - 'Ὤ' => 'ὤ', - 'Ὥ' => 'ὥ', - 'Ὦ' => 'ὦ', - 'Ὧ' => 'ὧ', - 'ᾈ' => 'ᾀ', - 'ᾉ' => 'ᾁ', - 'ᾊ' => 'ᾂ', - 'ᾋ' => 'ᾃ', - 'ᾌ' => 'ᾄ', - 'ᾍ' => 'ᾅ', - 'ᾎ' => 'ᾆ', - 'ᾏ' => 'ᾇ', - 'ᾘ' => 'ᾐ', - 'ᾙ' => 'ᾑ', - 'ᾚ' => 'ᾒ', - 'ᾛ' => 'ᾓ', - 'ᾜ' => 'ᾔ', - 'ᾝ' => 'ᾕ', - 'ᾞ' => 'ᾖ', - 'ᾟ' => 'ᾗ', - 'ᾨ' => 'ᾠ', - 'ᾩ' => 'ᾡ', - 'ᾪ' => 'ᾢ', - 'ᾫ' => 'ᾣ', - 'ᾬ' => 'ᾤ', - 'ᾭ' => 'ᾥ', - 'ᾮ' => 'ᾦ', - 'ᾯ' => 'ᾧ', - 'Ᾰ' => 'ᾰ', - 'Ᾱ' => 'ᾱ', - 'Ὰ' => 'ὰ', - 'Ά' => 'ά', - 'ᾼ' => 'ᾳ', - 'Ὲ' => 'ὲ', - 'Έ' => 'έ', - 'Ὴ' => 'ὴ', - 'Ή' => 'ή', - 'ῌ' => 'ῃ', - 'Ῐ' => 'ῐ', - 'Ῑ' => 'ῑ', - 'Ὶ' => 'ὶ', - 'Ί' => 'ί', - 'Ῠ' => 'ῠ', - 'Ῡ' => 'ῡ', - 'Ὺ' => 'ὺ', - 'Ύ' => 'ύ', - 'Ῥ' => 'ῥ', - 'Ὸ' => 'ὸ', - 'Ό' => 'ό', - 'Ὼ' => 'ὼ', - 'Ώ' => 'ώ', - 'ῼ' => 'ῳ', - 'Ω' => 'ω', - 'K' => 'k', - 'Å' => 'å', - 'Ⅎ' => 'ⅎ', - 'Ⅰ' => 'ⅰ', - 'Ⅱ' => 'ⅱ', - 'Ⅲ' => 'ⅲ', - 'Ⅳ' => 'ⅳ', - 'Ⅴ' => 'ⅴ', - 'Ⅵ' => 'ⅵ', - 'Ⅶ' => 'ⅶ', - 'Ⅷ' => 'ⅷ', - 'Ⅸ' => 'ⅸ', - 'Ⅹ' => 'ⅹ', - 'Ⅺ' => 'ⅺ', - 'Ⅻ' => 'ⅻ', - 'Ⅼ' => 'ⅼ', - 'Ⅽ' => 'ⅽ', - 'Ⅾ' => 'ⅾ', - 'Ⅿ' => 'ⅿ', - 'Ↄ' => 'ↄ', - 'Ⓐ' => 'ⓐ', - 'Ⓑ' => 'ⓑ', - 'Ⓒ' => 'ⓒ', - 'Ⓓ' => 'ⓓ', - 'Ⓔ' => 'ⓔ', - 'Ⓕ' => 'ⓕ', - 'Ⓖ' => 'ⓖ', - 'Ⓗ' => 'ⓗ', - 'Ⓘ' => 'ⓘ', - 'Ⓙ' => 'ⓙ', - 'Ⓚ' => 'ⓚ', - 'Ⓛ' => 'ⓛ', - 'Ⓜ' => 'ⓜ', - 'Ⓝ' => 'ⓝ', - 'Ⓞ' => 'ⓞ', - 'Ⓟ' => 'ⓟ', - 'Ⓠ' => 'ⓠ', - 'Ⓡ' => 'ⓡ', - 'Ⓢ' => 'ⓢ', - 'Ⓣ' => 'ⓣ', - 'Ⓤ' => 'ⓤ', - 'Ⓥ' => 'ⓥ', - 'Ⓦ' => 'ⓦ', - 'Ⓧ' => 'ⓧ', - 'Ⓨ' => 'ⓨ', - 'Ⓩ' => 'ⓩ', - 'Ⰰ' => 'ⰰ', - 'Ⰱ' => 'ⰱ', - 'Ⰲ' => 'ⰲ', - 'Ⰳ' => 'ⰳ', - 'Ⰴ' => 'ⰴ', - 'Ⰵ' => 'ⰵ', - 'Ⰶ' => 'ⰶ', - 'Ⰷ' => 'ⰷ', - 'Ⰸ' => 'ⰸ', - 'Ⰹ' => 'ⰹ', - 'Ⰺ' => 'ⰺ', - 'Ⰻ' => 'ⰻ', - 'Ⰼ' => 'ⰼ', - 'Ⰽ' => 'ⰽ', - 'Ⰾ' => 'ⰾ', - 'Ⰿ' => 'ⰿ', - 'Ⱀ' => 'ⱀ', - 'Ⱁ' => 'ⱁ', - 'Ⱂ' => 'ⱂ', - 'Ⱃ' => 'ⱃ', - 'Ⱄ' => 'ⱄ', - 'Ⱅ' => 'ⱅ', - 'Ⱆ' => 'ⱆ', - 'Ⱇ' => 'ⱇ', - 'Ⱈ' => 'ⱈ', - 'Ⱉ' => 'ⱉ', - 'Ⱊ' => 'ⱊ', - 'Ⱋ' => 'ⱋ', - 'Ⱌ' => 'ⱌ', - 'Ⱍ' => 'ⱍ', - 'Ⱎ' => 'ⱎ', - 'Ⱏ' => 'ⱏ', - 'Ⱐ' => 'ⱐ', - 'Ⱑ' => 'ⱑ', - 'Ⱒ' => 'ⱒ', - 'Ⱓ' => 'ⱓ', - 'Ⱔ' => 'ⱔ', - 'Ⱕ' => 'ⱕ', - 'Ⱖ' => 'ⱖ', - 'Ⱗ' => 'ⱗ', - 'Ⱘ' => 'ⱘ', - 'Ⱙ' => 'ⱙ', - 'Ⱚ' => 'ⱚ', - 'Ⱛ' => 'ⱛ', - 'Ⱜ' => 'ⱜ', - 'Ⱝ' => 'ⱝ', - 'Ⱞ' => 'ⱞ', - 'Ⱡ' => 'ⱡ', - 'Ɫ' => 'ɫ', - 'Ᵽ' => 'ᵽ', - 'Ɽ' => 'ɽ', - 'Ⱨ' => 'ⱨ', - 'Ⱪ' => 'ⱪ', - 'Ⱬ' => 'ⱬ', - 'Ɑ' => 'ɑ', - 'Ɱ' => 'ɱ', - 'Ɐ' => 'ɐ', - 'Ɒ' => 'ɒ', - 'Ⱳ' => 'ⱳ', - 'Ⱶ' => 'ⱶ', - 'Ȿ' => 'ȿ', - 'Ɀ' => 'ɀ', - 'Ⲁ' => 'ⲁ', - 'Ⲃ' => 'ⲃ', - 'Ⲅ' => 'ⲅ', - 'Ⲇ' => 'ⲇ', - 'Ⲉ' => 'ⲉ', - 'Ⲋ' => 'ⲋ', - 'Ⲍ' => 'ⲍ', - 'Ⲏ' => 'ⲏ', - 'Ⲑ' => 'ⲑ', - 'Ⲓ' => 'ⲓ', - 'Ⲕ' => 'ⲕ', - 'Ⲗ' => 'ⲗ', - 'Ⲙ' => 'ⲙ', - 'Ⲛ' => 'ⲛ', - 'Ⲝ' => 'ⲝ', - 'Ⲟ' => 'ⲟ', - 'Ⲡ' => 'ⲡ', - 'Ⲣ' => 'ⲣ', - 'Ⲥ' => 'ⲥ', - 'Ⲧ' => 'ⲧ', - 'Ⲩ' => 'ⲩ', - 'Ⲫ' => 'ⲫ', - 'Ⲭ' => 'ⲭ', - 'Ⲯ' => 'ⲯ', - 'Ⲱ' => 'ⲱ', - 'Ⲳ' => 'ⲳ', - 'Ⲵ' => 'ⲵ', - 'Ⲷ' => 'ⲷ', - 'Ⲹ' => 'ⲹ', - 'Ⲻ' => 'ⲻ', - 'Ⲽ' => 'ⲽ', - 'Ⲿ' => 'ⲿ', - 'Ⳁ' => 'ⳁ', - 'Ⳃ' => 'ⳃ', - 'Ⳅ' => 'ⳅ', - 'Ⳇ' => 'ⳇ', - 'Ⳉ' => 'ⳉ', - 'Ⳋ' => 'ⳋ', - 'Ⳍ' => 'ⳍ', - 'Ⳏ' => 'ⳏ', - 'Ⳑ' => 'ⳑ', - 'Ⳓ' => 'ⳓ', - 'Ⳕ' => 'ⳕ', - 'Ⳗ' => 'ⳗ', - 'Ⳙ' => 'ⳙ', - 'Ⳛ' => 'ⳛ', - 'Ⳝ' => 'ⳝ', - 'Ⳟ' => 'ⳟ', - 'Ⳡ' => 'ⳡ', - 'Ⳣ' => 'ⳣ', - 'Ⳬ' => 'ⳬ', - 'Ⳮ' => 'ⳮ', - 'Ⳳ' => 'ⳳ', - 'Ꙁ' => 'ꙁ', - 'Ꙃ' => 'ꙃ', - 'Ꙅ' => 'ꙅ', - 'Ꙇ' => 'ꙇ', - 'Ꙉ' => 'ꙉ', - 'Ꙋ' => 'ꙋ', - 'Ꙍ' => 'ꙍ', - 'Ꙏ' => 'ꙏ', - 'Ꙑ' => 'ꙑ', - 'Ꙓ' => 'ꙓ', - 'Ꙕ' => 'ꙕ', - 'Ꙗ' => 'ꙗ', - 'Ꙙ' => 'ꙙ', - 'Ꙛ' => 'ꙛ', - 'Ꙝ' => 'ꙝ', - 'Ꙟ' => 'ꙟ', - 'Ꙡ' => 'ꙡ', - 'Ꙣ' => 'ꙣ', - 'Ꙥ' => 'ꙥ', - 'Ꙧ' => 'ꙧ', - 'Ꙩ' => 'ꙩ', - 'Ꙫ' => 'ꙫ', - 'Ꙭ' => 'ꙭ', - 'Ꚁ' => 'ꚁ', - 'Ꚃ' => 'ꚃ', - 'Ꚅ' => 'ꚅ', - 'Ꚇ' => 'ꚇ', - 'Ꚉ' => 'ꚉ', - 'Ꚋ' => 'ꚋ', - 'Ꚍ' => 'ꚍ', - 'Ꚏ' => 'ꚏ', - 'Ꚑ' => 'ꚑ', - 'Ꚓ' => 'ꚓ', - 'Ꚕ' => 'ꚕ', - 'Ꚗ' => 'ꚗ', - 'Ꚙ' => 'ꚙ', - 'Ꚛ' => 'ꚛ', - 'Ꜣ' => 'ꜣ', - 'Ꜥ' => 'ꜥ', - 'Ꜧ' => 'ꜧ', - 'Ꜩ' => 'ꜩ', - 'Ꜫ' => 'ꜫ', - 'Ꜭ' => 'ꜭ', - 'Ꜯ' => 'ꜯ', - 'Ꜳ' => 'ꜳ', - 'Ꜵ' => 'ꜵ', - 'Ꜷ' => 'ꜷ', - 'Ꜹ' => 'ꜹ', - 'Ꜻ' => 'ꜻ', - 'Ꜽ' => 'ꜽ', - 'Ꜿ' => 'ꜿ', - 'Ꝁ' => 'ꝁ', - 'Ꝃ' => 'ꝃ', - 'Ꝅ' => 'ꝅ', - 'Ꝇ' => 'ꝇ', - 'Ꝉ' => 'ꝉ', - 'Ꝋ' => 'ꝋ', - 'Ꝍ' => 'ꝍ', - 'Ꝏ' => 'ꝏ', - 'Ꝑ' => 'ꝑ', - 'Ꝓ' => 'ꝓ', - 'Ꝕ' => 'ꝕ', - 'Ꝗ' => 'ꝗ', - 'Ꝙ' => 'ꝙ', - 'Ꝛ' => 'ꝛ', - 'Ꝝ' => 'ꝝ', - 'Ꝟ' => 'ꝟ', - 'Ꝡ' => 'ꝡ', - 'Ꝣ' => 'ꝣ', - 'Ꝥ' => 'ꝥ', - 'Ꝧ' => 'ꝧ', - 'Ꝩ' => 'ꝩ', - 'Ꝫ' => 'ꝫ', - 'Ꝭ' => 'ꝭ', - 'Ꝯ' => 'ꝯ', - 'Ꝺ' => 'ꝺ', - 'Ꝼ' => 'ꝼ', - 'Ᵹ' => 'ᵹ', - 'Ꝿ' => 'ꝿ', - 'Ꞁ' => 'ꞁ', - 'Ꞃ' => 'ꞃ', - 'Ꞅ' => 'ꞅ', - 'Ꞇ' => 'ꞇ', - 'Ꞌ' => 'ꞌ', - 'Ɥ' => 'ɥ', - 'Ꞑ' => 'ꞑ', - 'Ꞓ' => 'ꞓ', - 'Ꞗ' => 'ꞗ', - 'Ꞙ' => 'ꞙ', - 'Ꞛ' => 'ꞛ', - 'Ꞝ' => 'ꞝ', - 'Ꞟ' => 'ꞟ', - 'Ꞡ' => 'ꞡ', - 'Ꞣ' => 'ꞣ', - 'Ꞥ' => 'ꞥ', - 'Ꞧ' => 'ꞧ', - 'Ꞩ' => 'ꞩ', - 'Ɦ' => 'ɦ', - 'Ɜ' => 'ɜ', - 'Ɡ' => 'ɡ', - 'Ɬ' => 'ɬ', - 'Ɪ' => 'ɪ', - 'Ʞ' => 'ʞ', - 'Ʇ' => 'ʇ', - 'Ʝ' => 'ʝ', - 'Ꭓ' => 'ꭓ', - 'Ꞵ' => 'ꞵ', - 'Ꞷ' => 'ꞷ', - 'Ꞹ' => 'ꞹ', - 'Ꞻ' => 'ꞻ', - 'Ꞽ' => 'ꞽ', - 'Ꞿ' => 'ꞿ', - 'Ꟃ' => 'ꟃ', - 'Ꞔ' => 'ꞔ', - 'Ʂ' => 'ʂ', - 'Ᶎ' => 'ᶎ', - 'Ꟈ' => 'ꟈ', - 'Ꟊ' => 'ꟊ', - 'Ꟶ' => 'ꟶ', - 'A' => 'a', - 'B' => 'b', - 'C' => 'c', - 'D' => 'd', - 'E' => 'e', - 'F' => 'f', - 'G' => 'g', - 'H' => 'h', - 'I' => 'i', - 'J' => 'j', - 'K' => 'k', - 'L' => 'l', - 'M' => 'm', - 'N' => 'n', - 'O' => 'o', - 'P' => 'p', - 'Q' => 'q', - 'R' => 'r', - 'S' => 's', - 'T' => 't', - 'U' => 'u', - 'V' => 'v', - 'W' => 'w', - 'X' => 'x', - 'Y' => 'y', - 'Z' => 'z', - '𐐀' => '𐐨', - '𐐁' => '𐐩', - '𐐂' => '𐐪', - '𐐃' => '𐐫', - '𐐄' => '𐐬', - '𐐅' => '𐐭', - '𐐆' => '𐐮', - '𐐇' => '𐐯', - '𐐈' => '𐐰', - '𐐉' => '𐐱', - '𐐊' => '𐐲', - '𐐋' => '𐐳', - '𐐌' => '𐐴', - '𐐍' => '𐐵', - '𐐎' => '𐐶', - '𐐏' => '𐐷', - '𐐐' => '𐐸', - '𐐑' => '𐐹', - '𐐒' => '𐐺', - '𐐓' => '𐐻', - '𐐔' => '𐐼', - '𐐕' => '𐐽', - '𐐖' => '𐐾', - '𐐗' => '𐐿', - '𐐘' => '𐑀', - '𐐙' => '𐑁', - '𐐚' => '𐑂', - '𐐛' => '𐑃', - '𐐜' => '𐑄', - '𐐝' => '𐑅', - '𐐞' => '𐑆', - '𐐟' => '𐑇', - '𐐠' => '𐑈', - '𐐡' => '𐑉', - '𐐢' => '𐑊', - '𐐣' => '𐑋', - '𐐤' => '𐑌', - '𐐥' => '𐑍', - '𐐦' => '𐑎', - '𐐧' => '𐑏', - '𐒰' => '𐓘', - '𐒱' => '𐓙', - '𐒲' => '𐓚', - '𐒳' => '𐓛', - '𐒴' => '𐓜', - '𐒵' => '𐓝', - '𐒶' => '𐓞', - '𐒷' => '𐓟', - '𐒸' => '𐓠', - '𐒹' => '𐓡', - '𐒺' => '𐓢', - '𐒻' => '𐓣', - '𐒼' => '𐓤', - '𐒽' => '𐓥', - '𐒾' => '𐓦', - '𐒿' => '𐓧', - '𐓀' => '𐓨', - '𐓁' => '𐓩', - '𐓂' => '𐓪', - '𐓃' => '𐓫', - '𐓄' => '𐓬', - '𐓅' => '𐓭', - '𐓆' => '𐓮', - '𐓇' => '𐓯', - '𐓈' => '𐓰', - '𐓉' => '𐓱', - '𐓊' => '𐓲', - '𐓋' => '𐓳', - '𐓌' => '𐓴', - '𐓍' => '𐓵', - '𐓎' => '𐓶', - '𐓏' => '𐓷', - '𐓐' => '𐓸', - '𐓑' => '𐓹', - '𐓒' => '𐓺', - '𐓓' => '𐓻', - '𐲀' => '𐳀', - '𐲁' => '𐳁', - '𐲂' => '𐳂', - '𐲃' => '𐳃', - '𐲄' => '𐳄', - '𐲅' => '𐳅', - '𐲆' => '𐳆', - '𐲇' => '𐳇', - '𐲈' => '𐳈', - '𐲉' => '𐳉', - '𐲊' => '𐳊', - '𐲋' => '𐳋', - '𐲌' => '𐳌', - '𐲍' => '𐳍', - '𐲎' => '𐳎', - '𐲏' => '𐳏', - '𐲐' => '𐳐', - '𐲑' => '𐳑', - '𐲒' => '𐳒', - '𐲓' => '𐳓', - '𐲔' => '𐳔', - '𐲕' => '𐳕', - '𐲖' => '𐳖', - '𐲗' => '𐳗', - '𐲘' => '𐳘', - '𐲙' => '𐳙', - '𐲚' => '𐳚', - '𐲛' => '𐳛', - '𐲜' => '𐳜', - '𐲝' => '𐳝', - '𐲞' => '𐳞', - '𐲟' => '𐳟', - '𐲠' => '𐳠', - '𐲡' => '𐳡', - '𐲢' => '𐳢', - '𐲣' => '𐳣', - '𐲤' => '𐳤', - '𐲥' => '𐳥', - '𐲦' => '𐳦', - '𐲧' => '𐳧', - '𐲨' => '𐳨', - '𐲩' => '𐳩', - '𐲪' => '𐳪', - '𐲫' => '𐳫', - '𐲬' => '𐳬', - '𐲭' => '𐳭', - '𐲮' => '𐳮', - '𐲯' => '𐳯', - '𐲰' => '𐳰', - '𐲱' => '𐳱', - '𐲲' => '𐳲', - '𑢠' => '𑣀', - '𑢡' => '𑣁', - '𑢢' => '𑣂', - '𑢣' => '𑣃', - '𑢤' => '𑣄', - '𑢥' => '𑣅', - '𑢦' => '𑣆', - '𑢧' => '𑣇', - '𑢨' => '𑣈', - '𑢩' => '𑣉', - '𑢪' => '𑣊', - '𑢫' => '𑣋', - '𑢬' => '𑣌', - '𑢭' => '𑣍', - '𑢮' => '𑣎', - '𑢯' => '𑣏', - '𑢰' => '𑣐', - '𑢱' => '𑣑', - '𑢲' => '𑣒', - '𑢳' => '𑣓', - '𑢴' => '𑣔', - '𑢵' => '𑣕', - '𑢶' => '𑣖', - '𑢷' => '𑣗', - '𑢸' => '𑣘', - '𑢹' => '𑣙', - '𑢺' => '𑣚', - '𑢻' => '𑣛', - '𑢼' => '𑣜', - '𑢽' => '𑣝', - '𑢾' => '𑣞', - '𑢿' => '𑣟', - '𖹀' => '𖹠', - '𖹁' => '𖹡', - '𖹂' => '𖹢', - '𖹃' => '𖹣', - '𖹄' => '𖹤', - '𖹅' => '𖹥', - '𖹆' => '𖹦', - '𖹇' => '𖹧', - '𖹈' => '𖹨', - '𖹉' => '𖹩', - '𖹊' => '𖹪', - '𖹋' => '𖹫', - '𖹌' => '𖹬', - '𖹍' => '𖹭', - '𖹎' => '𖹮', - '𖹏' => '𖹯', - '𖹐' => '𖹰', - '𖹑' => '𖹱', - '𖹒' => '𖹲', - '𖹓' => '𖹳', - '𖹔' => '𖹴', - '𖹕' => '𖹵', - '𖹖' => '𖹶', - '𖹗' => '𖹷', - '𖹘' => '𖹸', - '𖹙' => '𖹹', - '𖹚' => '𖹺', - '𖹛' => '𖹻', - '𖹜' => '𖹼', - '𖹝' => '𖹽', - '𖹞' => '𖹾', - '𖹟' => '𖹿', - '𞤀' => '𞤢', - '𞤁' => '𞤣', - '𞤂' => '𞤤', - '𞤃' => '𞤥', - '𞤄' => '𞤦', - '𞤅' => '𞤧', - '𞤆' => '𞤨', - '𞤇' => '𞤩', - '𞤈' => '𞤪', - '𞤉' => '𞤫', - '𞤊' => '𞤬', - '𞤋' => '𞤭', - '𞤌' => '𞤮', - '𞤍' => '𞤯', - '𞤎' => '𞤰', - '𞤏' => '𞤱', - '𞤐' => '𞤲', - '𞤑' => '𞤳', - '𞤒' => '𞤴', - '𞤓' => '𞤵', - '𞤔' => '𞤶', - '𞤕' => '𞤷', - '𞤖' => '𞤸', - '𞤗' => '𞤹', - '𞤘' => '𞤺', - '𞤙' => '𞤻', - '𞤚' => '𞤼', - '𞤛' => '𞤽', - '𞤜' => '𞤾', - '𞤝' => '𞤿', - '𞤞' => '𞥀', - '𞤟' => '𞥁', - '𞤠' => '𞥂', - '𞤡' => '𞥃', -); diff --git a/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php b/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php deleted file mode 100644 index 2a8f6e73b..000000000 --- a/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php +++ /dev/null @@ -1,5 +0,0 @@ - 'A', - 'b' => 'B', - 'c' => 'C', - 'd' => 'D', - 'e' => 'E', - 'f' => 'F', - 'g' => 'G', - 'h' => 'H', - 'i' => 'I', - 'j' => 'J', - 'k' => 'K', - 'l' => 'L', - 'm' => 'M', - 'n' => 'N', - 'o' => 'O', - 'p' => 'P', - 'q' => 'Q', - 'r' => 'R', - 's' => 'S', - 't' => 'T', - 'u' => 'U', - 'v' => 'V', - 'w' => 'W', - 'x' => 'X', - 'y' => 'Y', - 'z' => 'Z', - 'µ' => 'Μ', - 'à' => 'À', - 'á' => 'Á', - 'â' => 'Â', - 'ã' => 'Ã', - 'ä' => 'Ä', - 'å' => 'Å', - 'æ' => 'Æ', - 'ç' => 'Ç', - 'è' => 'È', - 'é' => 'É', - 'ê' => 'Ê', - 'ë' => 'Ë', - 'ì' => 'Ì', - 'í' => 'Í', - 'î' => 'Î', - 'ï' => 'Ï', - 'ð' => 'Ð', - 'ñ' => 'Ñ', - 'ò' => 'Ò', - 'ó' => 'Ó', - 'ô' => 'Ô', - 'õ' => 'Õ', - 'ö' => 'Ö', - 'ø' => 'Ø', - 'ù' => 'Ù', - 'ú' => 'Ú', - 'û' => 'Û', - 'ü' => 'Ü', - 'ý' => 'Ý', - 'þ' => 'Þ', - 'ÿ' => 'Ÿ', - 'ā' => 'Ā', - 'ă' => 'Ă', - 'ą' => 'Ą', - 'ć' => 'Ć', - 'ĉ' => 'Ĉ', - 'ċ' => 'Ċ', - 'č' => 'Č', - 'ď' => 'Ď', - 'đ' => 'Đ', - 'ē' => 'Ē', - 'ĕ' => 'Ĕ', - 'ė' => 'Ė', - 'ę' => 'Ę', - 'ě' => 'Ě', - 'ĝ' => 'Ĝ', - 'ğ' => 'Ğ', - 'ġ' => 'Ġ', - 'ģ' => 'Ģ', - 'ĥ' => 'Ĥ', - 'ħ' => 'Ħ', - 'ĩ' => 'Ĩ', - 'ī' => 'Ī', - 'ĭ' => 'Ĭ', - 'į' => 'Į', - 'ı' => 'I', - 'ij' => 'IJ', - 'ĵ' => 'Ĵ', - 'ķ' => 'Ķ', - 'ĺ' => 'Ĺ', - 'ļ' => 'Ļ', - 'ľ' => 'Ľ', - 'ŀ' => 'Ŀ', - 'ł' => 'Ł', - 'ń' => 'Ń', - 'ņ' => 'Ņ', - 'ň' => 'Ň', - 'ŋ' => 'Ŋ', - 'ō' => 'Ō', - 'ŏ' => 'Ŏ', - 'ő' => 'Ő', - 'œ' => 'Œ', - 'ŕ' => 'Ŕ', - 'ŗ' => 'Ŗ', - 'ř' => 'Ř', - 'ś' => 'Ś', - 'ŝ' => 'Ŝ', - 'ş' => 'Ş', - 'š' => 'Š', - 'ţ' => 'Ţ', - 'ť' => 'Ť', - 'ŧ' => 'Ŧ', - 'ũ' => 'Ũ', - 'ū' => 'Ū', - 'ŭ' => 'Ŭ', - 'ů' => 'Ů', - 'ű' => 'Ű', - 'ų' => 'Ų', - 'ŵ' => 'Ŵ', - 'ŷ' => 'Ŷ', - 'ź' => 'Ź', - 'ż' => 'Ż', - 'ž' => 'Ž', - 'ſ' => 'S', - 'ƀ' => 'Ƀ', - 'ƃ' => 'Ƃ', - 'ƅ' => 'Ƅ', - 'ƈ' => 'Ƈ', - 'ƌ' => 'Ƌ', - 'ƒ' => 'Ƒ', - 'ƕ' => 'Ƕ', - 'ƙ' => 'Ƙ', - 'ƚ' => 'Ƚ', - 'ƞ' => 'Ƞ', - 'ơ' => 'Ơ', - 'ƣ' => 'Ƣ', - 'ƥ' => 'Ƥ', - 'ƨ' => 'Ƨ', - 'ƭ' => 'Ƭ', - 'ư' => 'Ư', - 'ƴ' => 'Ƴ', - 'ƶ' => 'Ƶ', - 'ƹ' => 'Ƹ', - 'ƽ' => 'Ƽ', - 'ƿ' => 'Ƿ', - 'Dž' => 'DŽ', - 'dž' => 'DŽ', - 'Lj' => 'LJ', - 'lj' => 'LJ', - 'Nj' => 'NJ', - 'nj' => 'NJ', - 'ǎ' => 'Ǎ', - 'ǐ' => 'Ǐ', - 'ǒ' => 'Ǒ', - 'ǔ' => 'Ǔ', - 'ǖ' => 'Ǖ', - 'ǘ' => 'Ǘ', - 'ǚ' => 'Ǚ', - 'ǜ' => 'Ǜ', - 'ǝ' => 'Ǝ', - 'ǟ' => 'Ǟ', - 'ǡ' => 'Ǡ', - 'ǣ' => 'Ǣ', - 'ǥ' => 'Ǥ', - 'ǧ' => 'Ǧ', - 'ǩ' => 'Ǩ', - 'ǫ' => 'Ǫ', - 'ǭ' => 'Ǭ', - 'ǯ' => 'Ǯ', - 'Dz' => 'DZ', - 'dz' => 'DZ', - 'ǵ' => 'Ǵ', - 'ǹ' => 'Ǹ', - 'ǻ' => 'Ǻ', - 'ǽ' => 'Ǽ', - 'ǿ' => 'Ǿ', - 'ȁ' => 'Ȁ', - 'ȃ' => 'Ȃ', - 'ȅ' => 'Ȅ', - 'ȇ' => 'Ȇ', - 'ȉ' => 'Ȉ', - 'ȋ' => 'Ȋ', - 'ȍ' => 'Ȍ', - 'ȏ' => 'Ȏ', - 'ȑ' => 'Ȑ', - 'ȓ' => 'Ȓ', - 'ȕ' => 'Ȕ', - 'ȗ' => 'Ȗ', - 'ș' => 'Ș', - 'ț' => 'Ț', - 'ȝ' => 'Ȝ', - 'ȟ' => 'Ȟ', - 'ȣ' => 'Ȣ', - 'ȥ' => 'Ȥ', - 'ȧ' => 'Ȧ', - 'ȩ' => 'Ȩ', - 'ȫ' => 'Ȫ', - 'ȭ' => 'Ȭ', - 'ȯ' => 'Ȯ', - 'ȱ' => 'Ȱ', - 'ȳ' => 'Ȳ', - 'ȼ' => 'Ȼ', - 'ȿ' => 'Ȿ', - 'ɀ' => 'Ɀ', - 'ɂ' => 'Ɂ', - 'ɇ' => 'Ɇ', - 'ɉ' => 'Ɉ', - 'ɋ' => 'Ɋ', - 'ɍ' => 'Ɍ', - 'ɏ' => 'Ɏ', - 'ɐ' => 'Ɐ', - 'ɑ' => 'Ɑ', - 'ɒ' => 'Ɒ', - 'ɓ' => 'Ɓ', - 'ɔ' => 'Ɔ', - 'ɖ' => 'Ɖ', - 'ɗ' => 'Ɗ', - 'ə' => 'Ə', - 'ɛ' => 'Ɛ', - 'ɜ' => 'Ɜ', - 'ɠ' => 'Ɠ', - 'ɡ' => 'Ɡ', - 'ɣ' => 'Ɣ', - 'ɥ' => 'Ɥ', - 'ɦ' => 'Ɦ', - 'ɨ' => 'Ɨ', - 'ɩ' => 'Ɩ', - 'ɪ' => 'Ɪ', - 'ɫ' => 'Ɫ', - 'ɬ' => 'Ɬ', - 'ɯ' => 'Ɯ', - 'ɱ' => 'Ɱ', - 'ɲ' => 'Ɲ', - 'ɵ' => 'Ɵ', - 'ɽ' => 'Ɽ', - 'ʀ' => 'Ʀ', - 'ʂ' => 'Ʂ', - 'ʃ' => 'Ʃ', - 'ʇ' => 'Ʇ', - 'ʈ' => 'Ʈ', - 'ʉ' => 'Ʉ', - 'ʊ' => 'Ʊ', - 'ʋ' => 'Ʋ', - 'ʌ' => 'Ʌ', - 'ʒ' => 'Ʒ', - 'ʝ' => 'Ʝ', - 'ʞ' => 'Ʞ', - 'ͅ' => 'Ι', - 'ͱ' => 'Ͱ', - 'ͳ' => 'Ͳ', - 'ͷ' => 'Ͷ', - 'ͻ' => 'Ͻ', - 'ͼ' => 'Ͼ', - 'ͽ' => 'Ͽ', - 'ά' => 'Ά', - 'έ' => 'Έ', - 'ή' => 'Ή', - 'ί' => 'Ί', - 'α' => 'Α', - 'β' => 'Β', - 'γ' => 'Γ', - 'δ' => 'Δ', - 'ε' => 'Ε', - 'ζ' => 'Ζ', - 'η' => 'Η', - 'θ' => 'Θ', - 'ι' => 'Ι', - 'κ' => 'Κ', - 'λ' => 'Λ', - 'μ' => 'Μ', - 'ν' => 'Ν', - 'ξ' => 'Ξ', - 'ο' => 'Ο', - 'π' => 'Π', - 'ρ' => 'Ρ', - 'ς' => 'Σ', - 'σ' => 'Σ', - 'τ' => 'Τ', - 'υ' => 'Υ', - 'φ' => 'Φ', - 'χ' => 'Χ', - 'ψ' => 'Ψ', - 'ω' => 'Ω', - 'ϊ' => 'Ϊ', - 'ϋ' => 'Ϋ', - 'ό' => 'Ό', - 'ύ' => 'Ύ', - 'ώ' => 'Ώ', - 'ϐ' => 'Β', - 'ϑ' => 'Θ', - 'ϕ' => 'Φ', - 'ϖ' => 'Π', - 'ϗ' => 'Ϗ', - 'ϙ' => 'Ϙ', - 'ϛ' => 'Ϛ', - 'ϝ' => 'Ϝ', - 'ϟ' => 'Ϟ', - 'ϡ' => 'Ϡ', - 'ϣ' => 'Ϣ', - 'ϥ' => 'Ϥ', - 'ϧ' => 'Ϧ', - 'ϩ' => 'Ϩ', - 'ϫ' => 'Ϫ', - 'ϭ' => 'Ϭ', - 'ϯ' => 'Ϯ', - 'ϰ' => 'Κ', - 'ϱ' => 'Ρ', - 'ϲ' => 'Ϲ', - 'ϳ' => 'Ϳ', - 'ϵ' => 'Ε', - 'ϸ' => 'Ϸ', - 'ϻ' => 'Ϻ', - 'а' => 'А', - 'б' => 'Б', - 'в' => 'В', - 'г' => 'Г', - 'д' => 'Д', - 'е' => 'Е', - 'ж' => 'Ж', - 'з' => 'З', - 'и' => 'И', - 'й' => 'Й', - 'к' => 'К', - 'л' => 'Л', - 'м' => 'М', - 'н' => 'Н', - 'о' => 'О', - 'п' => 'П', - 'р' => 'Р', - 'с' => 'С', - 'т' => 'Т', - 'у' => 'У', - 'ф' => 'Ф', - 'х' => 'Х', - 'ц' => 'Ц', - 'ч' => 'Ч', - 'ш' => 'Ш', - 'щ' => 'Щ', - 'ъ' => 'Ъ', - 'ы' => 'Ы', - 'ь' => 'Ь', - 'э' => 'Э', - 'ю' => 'Ю', - 'я' => 'Я', - 'ѐ' => 'Ѐ', - 'ё' => 'Ё', - 'ђ' => 'Ђ', - 'ѓ' => 'Ѓ', - 'є' => 'Є', - 'ѕ' => 'Ѕ', - 'і' => 'І', - 'ї' => 'Ї', - 'ј' => 'Ј', - 'љ' => 'Љ', - 'њ' => 'Њ', - 'ћ' => 'Ћ', - 'ќ' => 'Ќ', - 'ѝ' => 'Ѝ', - 'ў' => 'Ў', - 'џ' => 'Џ', - 'ѡ' => 'Ѡ', - 'ѣ' => 'Ѣ', - 'ѥ' => 'Ѥ', - 'ѧ' => 'Ѧ', - 'ѩ' => 'Ѩ', - 'ѫ' => 'Ѫ', - 'ѭ' => 'Ѭ', - 'ѯ' => 'Ѯ', - 'ѱ' => 'Ѱ', - 'ѳ' => 'Ѳ', - 'ѵ' => 'Ѵ', - 'ѷ' => 'Ѷ', - 'ѹ' => 'Ѹ', - 'ѻ' => 'Ѻ', - 'ѽ' => 'Ѽ', - 'ѿ' => 'Ѿ', - 'ҁ' => 'Ҁ', - 'ҋ' => 'Ҋ', - 'ҍ' => 'Ҍ', - 'ҏ' => 'Ҏ', - 'ґ' => 'Ґ', - 'ғ' => 'Ғ', - 'ҕ' => 'Ҕ', - 'җ' => 'Җ', - 'ҙ' => 'Ҙ', - 'қ' => 'Қ', - 'ҝ' => 'Ҝ', - 'ҟ' => 'Ҟ', - 'ҡ' => 'Ҡ', - 'ң' => 'Ң', - 'ҥ' => 'Ҥ', - 'ҧ' => 'Ҧ', - 'ҩ' => 'Ҩ', - 'ҫ' => 'Ҫ', - 'ҭ' => 'Ҭ', - 'ү' => 'Ү', - 'ұ' => 'Ұ', - 'ҳ' => 'Ҳ', - 'ҵ' => 'Ҵ', - 'ҷ' => 'Ҷ', - 'ҹ' => 'Ҹ', - 'һ' => 'Һ', - 'ҽ' => 'Ҽ', - 'ҿ' => 'Ҿ', - 'ӂ' => 'Ӂ', - 'ӄ' => 'Ӄ', - 'ӆ' => 'Ӆ', - 'ӈ' => 'Ӈ', - 'ӊ' => 'Ӊ', - 'ӌ' => 'Ӌ', - 'ӎ' => 'Ӎ', - 'ӏ' => 'Ӏ', - 'ӑ' => 'Ӑ', - 'ӓ' => 'Ӓ', - 'ӕ' => 'Ӕ', - 'ӗ' => 'Ӗ', - 'ә' => 'Ә', - 'ӛ' => 'Ӛ', - 'ӝ' => 'Ӝ', - 'ӟ' => 'Ӟ', - 'ӡ' => 'Ӡ', - 'ӣ' => 'Ӣ', - 'ӥ' => 'Ӥ', - 'ӧ' => 'Ӧ', - 'ө' => 'Ө', - 'ӫ' => 'Ӫ', - 'ӭ' => 'Ӭ', - 'ӯ' => 'Ӯ', - 'ӱ' => 'Ӱ', - 'ӳ' => 'Ӳ', - 'ӵ' => 'Ӵ', - 'ӷ' => 'Ӷ', - 'ӹ' => 'Ӹ', - 'ӻ' => 'Ӻ', - 'ӽ' => 'Ӽ', - 'ӿ' => 'Ӿ', - 'ԁ' => 'Ԁ', - 'ԃ' => 'Ԃ', - 'ԅ' => 'Ԅ', - 'ԇ' => 'Ԇ', - 'ԉ' => 'Ԉ', - 'ԋ' => 'Ԋ', - 'ԍ' => 'Ԍ', - 'ԏ' => 'Ԏ', - 'ԑ' => 'Ԑ', - 'ԓ' => 'Ԓ', - 'ԕ' => 'Ԕ', - 'ԗ' => 'Ԗ', - 'ԙ' => 'Ԙ', - 'ԛ' => 'Ԛ', - 'ԝ' => 'Ԝ', - 'ԟ' => 'Ԟ', - 'ԡ' => 'Ԡ', - 'ԣ' => 'Ԣ', - 'ԥ' => 'Ԥ', - 'ԧ' => 'Ԧ', - 'ԩ' => 'Ԩ', - 'ԫ' => 'Ԫ', - 'ԭ' => 'Ԭ', - 'ԯ' => 'Ԯ', - 'ա' => 'Ա', - 'բ' => 'Բ', - 'գ' => 'Գ', - 'դ' => 'Դ', - 'ե' => 'Ե', - 'զ' => 'Զ', - 'է' => 'Է', - 'ը' => 'Ը', - 'թ' => 'Թ', - 'ժ' => 'Ժ', - 'ի' => 'Ի', - 'լ' => 'Լ', - 'խ' => 'Խ', - 'ծ' => 'Ծ', - 'կ' => 'Կ', - 'հ' => 'Հ', - 'ձ' => 'Ձ', - 'ղ' => 'Ղ', - 'ճ' => 'Ճ', - 'մ' => 'Մ', - 'յ' => 'Յ', - 'ն' => 'Ն', - 'շ' => 'Շ', - 'ո' => 'Ո', - 'չ' => 'Չ', - 'պ' => 'Պ', - 'ջ' => 'Ջ', - 'ռ' => 'Ռ', - 'ս' => 'Ս', - 'վ' => 'Վ', - 'տ' => 'Տ', - 'ր' => 'Ր', - 'ց' => 'Ց', - 'ւ' => 'Ւ', - 'փ' => 'Փ', - 'ք' => 'Ք', - 'օ' => 'Օ', - 'ֆ' => 'Ֆ', - 'ა' => 'Ა', - 'ბ' => 'Ბ', - 'გ' => 'Გ', - 'დ' => 'Დ', - 'ე' => 'Ე', - 'ვ' => 'Ვ', - 'ზ' => 'Ზ', - 'თ' => 'Თ', - 'ი' => 'Ი', - 'კ' => 'Კ', - 'ლ' => 'Ლ', - 'მ' => 'Მ', - 'ნ' => 'Ნ', - 'ო' => 'Ო', - 'პ' => 'Პ', - 'ჟ' => 'Ჟ', - 'რ' => 'Რ', - 'ს' => 'Ს', - 'ტ' => 'Ტ', - 'უ' => 'Უ', - 'ფ' => 'Ფ', - 'ქ' => 'Ქ', - 'ღ' => 'Ღ', - 'ყ' => 'Ყ', - 'შ' => 'Შ', - 'ჩ' => 'Ჩ', - 'ც' => 'Ც', - 'ძ' => 'Ძ', - 'წ' => 'Წ', - 'ჭ' => 'Ჭ', - 'ხ' => 'Ხ', - 'ჯ' => 'Ჯ', - 'ჰ' => 'Ჰ', - 'ჱ' => 'Ჱ', - 'ჲ' => 'Ჲ', - 'ჳ' => 'Ჳ', - 'ჴ' => 'Ჴ', - 'ჵ' => 'Ჵ', - 'ჶ' => 'Ჶ', - 'ჷ' => 'Ჷ', - 'ჸ' => 'Ჸ', - 'ჹ' => 'Ჹ', - 'ჺ' => 'Ჺ', - 'ჽ' => 'Ჽ', - 'ჾ' => 'Ჾ', - 'ჿ' => 'Ჿ', - 'ᏸ' => 'Ᏸ', - 'ᏹ' => 'Ᏹ', - 'ᏺ' => 'Ᏺ', - 'ᏻ' => 'Ᏻ', - 'ᏼ' => 'Ᏼ', - 'ᏽ' => 'Ᏽ', - 'ᲀ' => 'В', - 'ᲁ' => 'Д', - 'ᲂ' => 'О', - 'ᲃ' => 'С', - 'ᲄ' => 'Т', - 'ᲅ' => 'Т', - 'ᲆ' => 'Ъ', - 'ᲇ' => 'Ѣ', - 'ᲈ' => 'Ꙋ', - 'ᵹ' => 'Ᵹ', - 'ᵽ' => 'Ᵽ', - 'ᶎ' => 'Ᶎ', - 'ḁ' => 'Ḁ', - 'ḃ' => 'Ḃ', - 'ḅ' => 'Ḅ', - 'ḇ' => 'Ḇ', - 'ḉ' => 'Ḉ', - 'ḋ' => 'Ḋ', - 'ḍ' => 'Ḍ', - 'ḏ' => 'Ḏ', - 'ḑ' => 'Ḑ', - 'ḓ' => 'Ḓ', - 'ḕ' => 'Ḕ', - 'ḗ' => 'Ḗ', - 'ḙ' => 'Ḙ', - 'ḛ' => 'Ḛ', - 'ḝ' => 'Ḝ', - 'ḟ' => 'Ḟ', - 'ḡ' => 'Ḡ', - 'ḣ' => 'Ḣ', - 'ḥ' => 'Ḥ', - 'ḧ' => 'Ḧ', - 'ḩ' => 'Ḩ', - 'ḫ' => 'Ḫ', - 'ḭ' => 'Ḭ', - 'ḯ' => 'Ḯ', - 'ḱ' => 'Ḱ', - 'ḳ' => 'Ḳ', - 'ḵ' => 'Ḵ', - 'ḷ' => 'Ḷ', - 'ḹ' => 'Ḹ', - 'ḻ' => 'Ḻ', - 'ḽ' => 'Ḽ', - 'ḿ' => 'Ḿ', - 'ṁ' => 'Ṁ', - 'ṃ' => 'Ṃ', - 'ṅ' => 'Ṅ', - 'ṇ' => 'Ṇ', - 'ṉ' => 'Ṉ', - 'ṋ' => 'Ṋ', - 'ṍ' => 'Ṍ', - 'ṏ' => 'Ṏ', - 'ṑ' => 'Ṑ', - 'ṓ' => 'Ṓ', - 'ṕ' => 'Ṕ', - 'ṗ' => 'Ṗ', - 'ṙ' => 'Ṙ', - 'ṛ' => 'Ṛ', - 'ṝ' => 'Ṝ', - 'ṟ' => 'Ṟ', - 'ṡ' => 'Ṡ', - 'ṣ' => 'Ṣ', - 'ṥ' => 'Ṥ', - 'ṧ' => 'Ṧ', - 'ṩ' => 'Ṩ', - 'ṫ' => 'Ṫ', - 'ṭ' => 'Ṭ', - 'ṯ' => 'Ṯ', - 'ṱ' => 'Ṱ', - 'ṳ' => 'Ṳ', - 'ṵ' => 'Ṵ', - 'ṷ' => 'Ṷ', - 'ṹ' => 'Ṹ', - 'ṻ' => 'Ṻ', - 'ṽ' => 'Ṽ', - 'ṿ' => 'Ṿ', - 'ẁ' => 'Ẁ', - 'ẃ' => 'Ẃ', - 'ẅ' => 'Ẅ', - 'ẇ' => 'Ẇ', - 'ẉ' => 'Ẉ', - 'ẋ' => 'Ẋ', - 'ẍ' => 'Ẍ', - 'ẏ' => 'Ẏ', - 'ẑ' => 'Ẑ', - 'ẓ' => 'Ẓ', - 'ẕ' => 'Ẕ', - 'ẛ' => 'Ṡ', - 'ạ' => 'Ạ', - 'ả' => 'Ả', - 'ấ' => 'Ấ', - 'ầ' => 'Ầ', - 'ẩ' => 'Ẩ', - 'ẫ' => 'Ẫ', - 'ậ' => 'Ậ', - 'ắ' => 'Ắ', - 'ằ' => 'Ằ', - 'ẳ' => 'Ẳ', - 'ẵ' => 'Ẵ', - 'ặ' => 'Ặ', - 'ẹ' => 'Ẹ', - 'ẻ' => 'Ẻ', - 'ẽ' => 'Ẽ', - 'ế' => 'Ế', - 'ề' => 'Ề', - 'ể' => 'Ể', - 'ễ' => 'Ễ', - 'ệ' => 'Ệ', - 'ỉ' => 'Ỉ', - 'ị' => 'Ị', - 'ọ' => 'Ọ', - 'ỏ' => 'Ỏ', - 'ố' => 'Ố', - 'ồ' => 'Ồ', - 'ổ' => 'Ổ', - 'ỗ' => 'Ỗ', - 'ộ' => 'Ộ', - 'ớ' => 'Ớ', - 'ờ' => 'Ờ', - 'ở' => 'Ở', - 'ỡ' => 'Ỡ', - 'ợ' => 'Ợ', - 'ụ' => 'Ụ', - 'ủ' => 'Ủ', - 'ứ' => 'Ứ', - 'ừ' => 'Ừ', - 'ử' => 'Ử', - 'ữ' => 'Ữ', - 'ự' => 'Ự', - 'ỳ' => 'Ỳ', - 'ỵ' => 'Ỵ', - 'ỷ' => 'Ỷ', - 'ỹ' => 'Ỹ', - 'ỻ' => 'Ỻ', - 'ỽ' => 'Ỽ', - 'ỿ' => 'Ỿ', - 'ἀ' => 'Ἀ', - 'ἁ' => 'Ἁ', - 'ἂ' => 'Ἂ', - 'ἃ' => 'Ἃ', - 'ἄ' => 'Ἄ', - 'ἅ' => 'Ἅ', - 'ἆ' => 'Ἆ', - 'ἇ' => 'Ἇ', - 'ἐ' => 'Ἐ', - 'ἑ' => 'Ἑ', - 'ἒ' => 'Ἒ', - 'ἓ' => 'Ἓ', - 'ἔ' => 'Ἔ', - 'ἕ' => 'Ἕ', - 'ἠ' => 'Ἠ', - 'ἡ' => 'Ἡ', - 'ἢ' => 'Ἢ', - 'ἣ' => 'Ἣ', - 'ἤ' => 'Ἤ', - 'ἥ' => 'Ἥ', - 'ἦ' => 'Ἦ', - 'ἧ' => 'Ἧ', - 'ἰ' => 'Ἰ', - 'ἱ' => 'Ἱ', - 'ἲ' => 'Ἲ', - 'ἳ' => 'Ἳ', - 'ἴ' => 'Ἴ', - 'ἵ' => 'Ἵ', - 'ἶ' => 'Ἶ', - 'ἷ' => 'Ἷ', - 'ὀ' => 'Ὀ', - 'ὁ' => 'Ὁ', - 'ὂ' => 'Ὂ', - 'ὃ' => 'Ὃ', - 'ὄ' => 'Ὄ', - 'ὅ' => 'Ὅ', - 'ὑ' => 'Ὑ', - 'ὓ' => 'Ὓ', - 'ὕ' => 'Ὕ', - 'ὗ' => 'Ὗ', - 'ὠ' => 'Ὠ', - 'ὡ' => 'Ὡ', - 'ὢ' => 'Ὢ', - 'ὣ' => 'Ὣ', - 'ὤ' => 'Ὤ', - 'ὥ' => 'Ὥ', - 'ὦ' => 'Ὦ', - 'ὧ' => 'Ὧ', - 'ὰ' => 'Ὰ', - 'ά' => 'Ά', - 'ὲ' => 'Ὲ', - 'έ' => 'Έ', - 'ὴ' => 'Ὴ', - 'ή' => 'Ή', - 'ὶ' => 'Ὶ', - 'ί' => 'Ί', - 'ὸ' => 'Ὸ', - 'ό' => 'Ό', - 'ὺ' => 'Ὺ', - 'ύ' => 'Ύ', - 'ὼ' => 'Ὼ', - 'ώ' => 'Ώ', - 'ᾀ' => 'ἈΙ', - 'ᾁ' => 'ἉΙ', - 'ᾂ' => 'ἊΙ', - 'ᾃ' => 'ἋΙ', - 'ᾄ' => 'ἌΙ', - 'ᾅ' => 'ἍΙ', - 'ᾆ' => 'ἎΙ', - 'ᾇ' => 'ἏΙ', - 'ᾐ' => 'ἨΙ', - 'ᾑ' => 'ἩΙ', - 'ᾒ' => 'ἪΙ', - 'ᾓ' => 'ἫΙ', - 'ᾔ' => 'ἬΙ', - 'ᾕ' => 'ἭΙ', - 'ᾖ' => 'ἮΙ', - 'ᾗ' => 'ἯΙ', - 'ᾠ' => 'ὨΙ', - 'ᾡ' => 'ὩΙ', - 'ᾢ' => 'ὪΙ', - 'ᾣ' => 'ὫΙ', - 'ᾤ' => 'ὬΙ', - 'ᾥ' => 'ὭΙ', - 'ᾦ' => 'ὮΙ', - 'ᾧ' => 'ὯΙ', - 'ᾰ' => 'Ᾰ', - 'ᾱ' => 'Ᾱ', - 'ᾳ' => 'ΑΙ', - 'ι' => 'Ι', - 'ῃ' => 'ΗΙ', - 'ῐ' => 'Ῐ', - 'ῑ' => 'Ῑ', - 'ῠ' => 'Ῠ', - 'ῡ' => 'Ῡ', - 'ῥ' => 'Ῥ', - 'ῳ' => 'ΩΙ', - 'ⅎ' => 'Ⅎ', - 'ⅰ' => 'Ⅰ', - 'ⅱ' => 'Ⅱ', - 'ⅲ' => 'Ⅲ', - 'ⅳ' => 'Ⅳ', - 'ⅴ' => 'Ⅴ', - 'ⅵ' => 'Ⅵ', - 'ⅶ' => 'Ⅶ', - 'ⅷ' => 'Ⅷ', - 'ⅸ' => 'Ⅸ', - 'ⅹ' => 'Ⅹ', - 'ⅺ' => 'Ⅺ', - 'ⅻ' => 'Ⅻ', - 'ⅼ' => 'Ⅼ', - 'ⅽ' => 'Ⅽ', - 'ⅾ' => 'Ⅾ', - 'ⅿ' => 'Ⅿ', - 'ↄ' => 'Ↄ', - 'ⓐ' => 'Ⓐ', - 'ⓑ' => 'Ⓑ', - 'ⓒ' => 'Ⓒ', - 'ⓓ' => 'Ⓓ', - 'ⓔ' => 'Ⓔ', - 'ⓕ' => 'Ⓕ', - 'ⓖ' => 'Ⓖ', - 'ⓗ' => 'Ⓗ', - 'ⓘ' => 'Ⓘ', - 'ⓙ' => 'Ⓙ', - 'ⓚ' => 'Ⓚ', - 'ⓛ' => 'Ⓛ', - 'ⓜ' => 'Ⓜ', - 'ⓝ' => 'Ⓝ', - 'ⓞ' => 'Ⓞ', - 'ⓟ' => 'Ⓟ', - 'ⓠ' => 'Ⓠ', - 'ⓡ' => 'Ⓡ', - 'ⓢ' => 'Ⓢ', - 'ⓣ' => 'Ⓣ', - 'ⓤ' => 'Ⓤ', - 'ⓥ' => 'Ⓥ', - 'ⓦ' => 'Ⓦ', - 'ⓧ' => 'Ⓧ', - 'ⓨ' => 'Ⓨ', - 'ⓩ' => 'Ⓩ', - 'ⰰ' => 'Ⰰ', - 'ⰱ' => 'Ⰱ', - 'ⰲ' => 'Ⰲ', - 'ⰳ' => 'Ⰳ', - 'ⰴ' => 'Ⰴ', - 'ⰵ' => 'Ⰵ', - 'ⰶ' => 'Ⰶ', - 'ⰷ' => 'Ⰷ', - 'ⰸ' => 'Ⰸ', - 'ⰹ' => 'Ⰹ', - 'ⰺ' => 'Ⰺ', - 'ⰻ' => 'Ⰻ', - 'ⰼ' => 'Ⰼ', - 'ⰽ' => 'Ⰽ', - 'ⰾ' => 'Ⰾ', - 'ⰿ' => 'Ⰿ', - 'ⱀ' => 'Ⱀ', - 'ⱁ' => 'Ⱁ', - 'ⱂ' => 'Ⱂ', - 'ⱃ' => 'Ⱃ', - 'ⱄ' => 'Ⱄ', - 'ⱅ' => 'Ⱅ', - 'ⱆ' => 'Ⱆ', - 'ⱇ' => 'Ⱇ', - 'ⱈ' => 'Ⱈ', - 'ⱉ' => 'Ⱉ', - 'ⱊ' => 'Ⱊ', - 'ⱋ' => 'Ⱋ', - 'ⱌ' => 'Ⱌ', - 'ⱍ' => 'Ⱍ', - 'ⱎ' => 'Ⱎ', - 'ⱏ' => 'Ⱏ', - 'ⱐ' => 'Ⱐ', - 'ⱑ' => 'Ⱑ', - 'ⱒ' => 'Ⱒ', - 'ⱓ' => 'Ⱓ', - 'ⱔ' => 'Ⱔ', - 'ⱕ' => 'Ⱕ', - 'ⱖ' => 'Ⱖ', - 'ⱗ' => 'Ⱗ', - 'ⱘ' => 'Ⱘ', - 'ⱙ' => 'Ⱙ', - 'ⱚ' => 'Ⱚ', - 'ⱛ' => 'Ⱛ', - 'ⱜ' => 'Ⱜ', - 'ⱝ' => 'Ⱝ', - 'ⱞ' => 'Ⱞ', - 'ⱡ' => 'Ⱡ', - 'ⱥ' => 'Ⱥ', - 'ⱦ' => 'Ⱦ', - 'ⱨ' => 'Ⱨ', - 'ⱪ' => 'Ⱪ', - 'ⱬ' => 'Ⱬ', - 'ⱳ' => 'Ⱳ', - 'ⱶ' => 'Ⱶ', - 'ⲁ' => 'Ⲁ', - 'ⲃ' => 'Ⲃ', - 'ⲅ' => 'Ⲅ', - 'ⲇ' => 'Ⲇ', - 'ⲉ' => 'Ⲉ', - 'ⲋ' => 'Ⲋ', - 'ⲍ' => 'Ⲍ', - 'ⲏ' => 'Ⲏ', - 'ⲑ' => 'Ⲑ', - 'ⲓ' => 'Ⲓ', - 'ⲕ' => 'Ⲕ', - 'ⲗ' => 'Ⲗ', - 'ⲙ' => 'Ⲙ', - 'ⲛ' => 'Ⲛ', - 'ⲝ' => 'Ⲝ', - 'ⲟ' => 'Ⲟ', - 'ⲡ' => 'Ⲡ', - 'ⲣ' => 'Ⲣ', - 'ⲥ' => 'Ⲥ', - 'ⲧ' => 'Ⲧ', - 'ⲩ' => 'Ⲩ', - 'ⲫ' => 'Ⲫ', - 'ⲭ' => 'Ⲭ', - 'ⲯ' => 'Ⲯ', - 'ⲱ' => 'Ⲱ', - 'ⲳ' => 'Ⲳ', - 'ⲵ' => 'Ⲵ', - 'ⲷ' => 'Ⲷ', - 'ⲹ' => 'Ⲹ', - 'ⲻ' => 'Ⲻ', - 'ⲽ' => 'Ⲽ', - 'ⲿ' => 'Ⲿ', - 'ⳁ' => 'Ⳁ', - 'ⳃ' => 'Ⳃ', - 'ⳅ' => 'Ⳅ', - 'ⳇ' => 'Ⳇ', - 'ⳉ' => 'Ⳉ', - 'ⳋ' => 'Ⳋ', - 'ⳍ' => 'Ⳍ', - 'ⳏ' => 'Ⳏ', - 'ⳑ' => 'Ⳑ', - 'ⳓ' => 'Ⳓ', - 'ⳕ' => 'Ⳕ', - 'ⳗ' => 'Ⳗ', - 'ⳙ' => 'Ⳙ', - 'ⳛ' => 'Ⳛ', - 'ⳝ' => 'Ⳝ', - 'ⳟ' => 'Ⳟ', - 'ⳡ' => 'Ⳡ', - 'ⳣ' => 'Ⳣ', - 'ⳬ' => 'Ⳬ', - 'ⳮ' => 'Ⳮ', - 'ⳳ' => 'Ⳳ', - 'ⴀ' => 'Ⴀ', - 'ⴁ' => 'Ⴁ', - 'ⴂ' => 'Ⴂ', - 'ⴃ' => 'Ⴃ', - 'ⴄ' => 'Ⴄ', - 'ⴅ' => 'Ⴅ', - 'ⴆ' => 'Ⴆ', - 'ⴇ' => 'Ⴇ', - 'ⴈ' => 'Ⴈ', - 'ⴉ' => 'Ⴉ', - 'ⴊ' => 'Ⴊ', - 'ⴋ' => 'Ⴋ', - 'ⴌ' => 'Ⴌ', - 'ⴍ' => 'Ⴍ', - 'ⴎ' => 'Ⴎ', - 'ⴏ' => 'Ⴏ', - 'ⴐ' => 'Ⴐ', - 'ⴑ' => 'Ⴑ', - 'ⴒ' => 'Ⴒ', - 'ⴓ' => 'Ⴓ', - 'ⴔ' => 'Ⴔ', - 'ⴕ' => 'Ⴕ', - 'ⴖ' => 'Ⴖ', - 'ⴗ' => 'Ⴗ', - 'ⴘ' => 'Ⴘ', - 'ⴙ' => 'Ⴙ', - 'ⴚ' => 'Ⴚ', - 'ⴛ' => 'Ⴛ', - 'ⴜ' => 'Ⴜ', - 'ⴝ' => 'Ⴝ', - 'ⴞ' => 'Ⴞ', - 'ⴟ' => 'Ⴟ', - 'ⴠ' => 'Ⴠ', - 'ⴡ' => 'Ⴡ', - 'ⴢ' => 'Ⴢ', - 'ⴣ' => 'Ⴣ', - 'ⴤ' => 'Ⴤ', - 'ⴥ' => 'Ⴥ', - 'ⴧ' => 'Ⴧ', - 'ⴭ' => 'Ⴭ', - 'ꙁ' => 'Ꙁ', - 'ꙃ' => 'Ꙃ', - 'ꙅ' => 'Ꙅ', - 'ꙇ' => 'Ꙇ', - 'ꙉ' => 'Ꙉ', - 'ꙋ' => 'Ꙋ', - 'ꙍ' => 'Ꙍ', - 'ꙏ' => 'Ꙏ', - 'ꙑ' => 'Ꙑ', - 'ꙓ' => 'Ꙓ', - 'ꙕ' => 'Ꙕ', - 'ꙗ' => 'Ꙗ', - 'ꙙ' => 'Ꙙ', - 'ꙛ' => 'Ꙛ', - 'ꙝ' => 'Ꙝ', - 'ꙟ' => 'Ꙟ', - 'ꙡ' => 'Ꙡ', - 'ꙣ' => 'Ꙣ', - 'ꙥ' => 'Ꙥ', - 'ꙧ' => 'Ꙧ', - 'ꙩ' => 'Ꙩ', - 'ꙫ' => 'Ꙫ', - 'ꙭ' => 'Ꙭ', - 'ꚁ' => 'Ꚁ', - 'ꚃ' => 'Ꚃ', - 'ꚅ' => 'Ꚅ', - 'ꚇ' => 'Ꚇ', - 'ꚉ' => 'Ꚉ', - 'ꚋ' => 'Ꚋ', - 'ꚍ' => 'Ꚍ', - 'ꚏ' => 'Ꚏ', - 'ꚑ' => 'Ꚑ', - 'ꚓ' => 'Ꚓ', - 'ꚕ' => 'Ꚕ', - 'ꚗ' => 'Ꚗ', - 'ꚙ' => 'Ꚙ', - 'ꚛ' => 'Ꚛ', - 'ꜣ' => 'Ꜣ', - 'ꜥ' => 'Ꜥ', - 'ꜧ' => 'Ꜧ', - 'ꜩ' => 'Ꜩ', - 'ꜫ' => 'Ꜫ', - 'ꜭ' => 'Ꜭ', - 'ꜯ' => 'Ꜯ', - 'ꜳ' => 'Ꜳ', - 'ꜵ' => 'Ꜵ', - 'ꜷ' => 'Ꜷ', - 'ꜹ' => 'Ꜹ', - 'ꜻ' => 'Ꜻ', - 'ꜽ' => 'Ꜽ', - 'ꜿ' => 'Ꜿ', - 'ꝁ' => 'Ꝁ', - 'ꝃ' => 'Ꝃ', - 'ꝅ' => 'Ꝅ', - 'ꝇ' => 'Ꝇ', - 'ꝉ' => 'Ꝉ', - 'ꝋ' => 'Ꝋ', - 'ꝍ' => 'Ꝍ', - 'ꝏ' => 'Ꝏ', - 'ꝑ' => 'Ꝑ', - 'ꝓ' => 'Ꝓ', - 'ꝕ' => 'Ꝕ', - 'ꝗ' => 'Ꝗ', - 'ꝙ' => 'Ꝙ', - 'ꝛ' => 'Ꝛ', - 'ꝝ' => 'Ꝝ', - 'ꝟ' => 'Ꝟ', - 'ꝡ' => 'Ꝡ', - 'ꝣ' => 'Ꝣ', - 'ꝥ' => 'Ꝥ', - 'ꝧ' => 'Ꝧ', - 'ꝩ' => 'Ꝩ', - 'ꝫ' => 'Ꝫ', - 'ꝭ' => 'Ꝭ', - 'ꝯ' => 'Ꝯ', - 'ꝺ' => 'Ꝺ', - 'ꝼ' => 'Ꝼ', - 'ꝿ' => 'Ꝿ', - 'ꞁ' => 'Ꞁ', - 'ꞃ' => 'Ꞃ', - 'ꞅ' => 'Ꞅ', - 'ꞇ' => 'Ꞇ', - 'ꞌ' => 'Ꞌ', - 'ꞑ' => 'Ꞑ', - 'ꞓ' => 'Ꞓ', - 'ꞔ' => 'Ꞔ', - 'ꞗ' => 'Ꞗ', - 'ꞙ' => 'Ꞙ', - 'ꞛ' => 'Ꞛ', - 'ꞝ' => 'Ꞝ', - 'ꞟ' => 'Ꞟ', - 'ꞡ' => 'Ꞡ', - 'ꞣ' => 'Ꞣ', - 'ꞥ' => 'Ꞥ', - 'ꞧ' => 'Ꞧ', - 'ꞩ' => 'Ꞩ', - 'ꞵ' => 'Ꞵ', - 'ꞷ' => 'Ꞷ', - 'ꞹ' => 'Ꞹ', - 'ꞻ' => 'Ꞻ', - 'ꞽ' => 'Ꞽ', - 'ꞿ' => 'Ꞿ', - 'ꟃ' => 'Ꟃ', - 'ꟈ' => 'Ꟈ', - 'ꟊ' => 'Ꟊ', - 'ꟶ' => 'Ꟶ', - 'ꭓ' => 'Ꭓ', - 'ꭰ' => 'Ꭰ', - 'ꭱ' => 'Ꭱ', - 'ꭲ' => 'Ꭲ', - 'ꭳ' => 'Ꭳ', - 'ꭴ' => 'Ꭴ', - 'ꭵ' => 'Ꭵ', - 'ꭶ' => 'Ꭶ', - 'ꭷ' => 'Ꭷ', - 'ꭸ' => 'Ꭸ', - 'ꭹ' => 'Ꭹ', - 'ꭺ' => 'Ꭺ', - 'ꭻ' => 'Ꭻ', - 'ꭼ' => 'Ꭼ', - 'ꭽ' => 'Ꭽ', - 'ꭾ' => 'Ꭾ', - 'ꭿ' => 'Ꭿ', - 'ꮀ' => 'Ꮀ', - 'ꮁ' => 'Ꮁ', - 'ꮂ' => 'Ꮂ', - 'ꮃ' => 'Ꮃ', - 'ꮄ' => 'Ꮄ', - 'ꮅ' => 'Ꮅ', - 'ꮆ' => 'Ꮆ', - 'ꮇ' => 'Ꮇ', - 'ꮈ' => 'Ꮈ', - 'ꮉ' => 'Ꮉ', - 'ꮊ' => 'Ꮊ', - 'ꮋ' => 'Ꮋ', - 'ꮌ' => 'Ꮌ', - 'ꮍ' => 'Ꮍ', - 'ꮎ' => 'Ꮎ', - 'ꮏ' => 'Ꮏ', - 'ꮐ' => 'Ꮐ', - 'ꮑ' => 'Ꮑ', - 'ꮒ' => 'Ꮒ', - 'ꮓ' => 'Ꮓ', - 'ꮔ' => 'Ꮔ', - 'ꮕ' => 'Ꮕ', - 'ꮖ' => 'Ꮖ', - 'ꮗ' => 'Ꮗ', - 'ꮘ' => 'Ꮘ', - 'ꮙ' => 'Ꮙ', - 'ꮚ' => 'Ꮚ', - 'ꮛ' => 'Ꮛ', - 'ꮜ' => 'Ꮜ', - 'ꮝ' => 'Ꮝ', - 'ꮞ' => 'Ꮞ', - 'ꮟ' => 'Ꮟ', - 'ꮠ' => 'Ꮠ', - 'ꮡ' => 'Ꮡ', - 'ꮢ' => 'Ꮢ', - 'ꮣ' => 'Ꮣ', - 'ꮤ' => 'Ꮤ', - 'ꮥ' => 'Ꮥ', - 'ꮦ' => 'Ꮦ', - 'ꮧ' => 'Ꮧ', - 'ꮨ' => 'Ꮨ', - 'ꮩ' => 'Ꮩ', - 'ꮪ' => 'Ꮪ', - 'ꮫ' => 'Ꮫ', - 'ꮬ' => 'Ꮬ', - 'ꮭ' => 'Ꮭ', - 'ꮮ' => 'Ꮮ', - 'ꮯ' => 'Ꮯ', - 'ꮰ' => 'Ꮰ', - 'ꮱ' => 'Ꮱ', - 'ꮲ' => 'Ꮲ', - 'ꮳ' => 'Ꮳ', - 'ꮴ' => 'Ꮴ', - 'ꮵ' => 'Ꮵ', - 'ꮶ' => 'Ꮶ', - 'ꮷ' => 'Ꮷ', - 'ꮸ' => 'Ꮸ', - 'ꮹ' => 'Ꮹ', - 'ꮺ' => 'Ꮺ', - 'ꮻ' => 'Ꮻ', - 'ꮼ' => 'Ꮼ', - 'ꮽ' => 'Ꮽ', - 'ꮾ' => 'Ꮾ', - 'ꮿ' => 'Ꮿ', - 'a' => 'A', - 'b' => 'B', - 'c' => 'C', - 'd' => 'D', - 'e' => 'E', - 'f' => 'F', - 'g' => 'G', - 'h' => 'H', - 'i' => 'I', - 'j' => 'J', - 'k' => 'K', - 'l' => 'L', - 'm' => 'M', - 'n' => 'N', - 'o' => 'O', - 'p' => 'P', - 'q' => 'Q', - 'r' => 'R', - 's' => 'S', - 't' => 'T', - 'u' => 'U', - 'v' => 'V', - 'w' => 'W', - 'x' => 'X', - 'y' => 'Y', - 'z' => 'Z', - '𐐨' => '𐐀', - '𐐩' => '𐐁', - '𐐪' => '𐐂', - '𐐫' => '𐐃', - '𐐬' => '𐐄', - '𐐭' => '𐐅', - '𐐮' => '𐐆', - '𐐯' => '𐐇', - '𐐰' => '𐐈', - '𐐱' => '𐐉', - '𐐲' => '𐐊', - '𐐳' => '𐐋', - '𐐴' => '𐐌', - '𐐵' => '𐐍', - '𐐶' => '𐐎', - '𐐷' => '𐐏', - '𐐸' => '𐐐', - '𐐹' => '𐐑', - '𐐺' => '𐐒', - '𐐻' => '𐐓', - '𐐼' => '𐐔', - '𐐽' => '𐐕', - '𐐾' => '𐐖', - '𐐿' => '𐐗', - '𐑀' => '𐐘', - '𐑁' => '𐐙', - '𐑂' => '𐐚', - '𐑃' => '𐐛', - '𐑄' => '𐐜', - '𐑅' => '𐐝', - '𐑆' => '𐐞', - '𐑇' => '𐐟', - '𐑈' => '𐐠', - '𐑉' => '𐐡', - '𐑊' => '𐐢', - '𐑋' => '𐐣', - '𐑌' => '𐐤', - '𐑍' => '𐐥', - '𐑎' => '𐐦', - '𐑏' => '𐐧', - '𐓘' => '𐒰', - '𐓙' => '𐒱', - '𐓚' => '𐒲', - '𐓛' => '𐒳', - '𐓜' => '𐒴', - '𐓝' => '𐒵', - '𐓞' => '𐒶', - '𐓟' => '𐒷', - '𐓠' => '𐒸', - '𐓡' => '𐒹', - '𐓢' => '𐒺', - '𐓣' => '𐒻', - '𐓤' => '𐒼', - '𐓥' => '𐒽', - '𐓦' => '𐒾', - '𐓧' => '𐒿', - '𐓨' => '𐓀', - '𐓩' => '𐓁', - '𐓪' => '𐓂', - '𐓫' => '𐓃', - '𐓬' => '𐓄', - '𐓭' => '𐓅', - '𐓮' => '𐓆', - '𐓯' => '𐓇', - '𐓰' => '𐓈', - '𐓱' => '𐓉', - '𐓲' => '𐓊', - '𐓳' => '𐓋', - '𐓴' => '𐓌', - '𐓵' => '𐓍', - '𐓶' => '𐓎', - '𐓷' => '𐓏', - '𐓸' => '𐓐', - '𐓹' => '𐓑', - '𐓺' => '𐓒', - '𐓻' => '𐓓', - '𐳀' => '𐲀', - '𐳁' => '𐲁', - '𐳂' => '𐲂', - '𐳃' => '𐲃', - '𐳄' => '𐲄', - '𐳅' => '𐲅', - '𐳆' => '𐲆', - '𐳇' => '𐲇', - '𐳈' => '𐲈', - '𐳉' => '𐲉', - '𐳊' => '𐲊', - '𐳋' => '𐲋', - '𐳌' => '𐲌', - '𐳍' => '𐲍', - '𐳎' => '𐲎', - '𐳏' => '𐲏', - '𐳐' => '𐲐', - '𐳑' => '𐲑', - '𐳒' => '𐲒', - '𐳓' => '𐲓', - '𐳔' => '𐲔', - '𐳕' => '𐲕', - '𐳖' => '𐲖', - '𐳗' => '𐲗', - '𐳘' => '𐲘', - '𐳙' => '𐲙', - '𐳚' => '𐲚', - '𐳛' => '𐲛', - '𐳜' => '𐲜', - '𐳝' => '𐲝', - '𐳞' => '𐲞', - '𐳟' => '𐲟', - '𐳠' => '𐲠', - '𐳡' => '𐲡', - '𐳢' => '𐲢', - '𐳣' => '𐲣', - '𐳤' => '𐲤', - '𐳥' => '𐲥', - '𐳦' => '𐲦', - '𐳧' => '𐲧', - '𐳨' => '𐲨', - '𐳩' => '𐲩', - '𐳪' => '𐲪', - '𐳫' => '𐲫', - '𐳬' => '𐲬', - '𐳭' => '𐲭', - '𐳮' => '𐲮', - '𐳯' => '𐲯', - '𐳰' => '𐲰', - '𐳱' => '𐲱', - '𐳲' => '𐲲', - '𑣀' => '𑢠', - '𑣁' => '𑢡', - '𑣂' => '𑢢', - '𑣃' => '𑢣', - '𑣄' => '𑢤', - '𑣅' => '𑢥', - '𑣆' => '𑢦', - '𑣇' => '𑢧', - '𑣈' => '𑢨', - '𑣉' => '𑢩', - '𑣊' => '𑢪', - '𑣋' => '𑢫', - '𑣌' => '𑢬', - '𑣍' => '𑢭', - '𑣎' => '𑢮', - '𑣏' => '𑢯', - '𑣐' => '𑢰', - '𑣑' => '𑢱', - '𑣒' => '𑢲', - '𑣓' => '𑢳', - '𑣔' => '𑢴', - '𑣕' => '𑢵', - '𑣖' => '𑢶', - '𑣗' => '𑢷', - '𑣘' => '𑢸', - '𑣙' => '𑢹', - '𑣚' => '𑢺', - '𑣛' => '𑢻', - '𑣜' => '𑢼', - '𑣝' => '𑢽', - '𑣞' => '𑢾', - '𑣟' => '𑢿', - '𖹠' => '𖹀', - '𖹡' => '𖹁', - '𖹢' => '𖹂', - '𖹣' => '𖹃', - '𖹤' => '𖹄', - '𖹥' => '𖹅', - '𖹦' => '𖹆', - '𖹧' => '𖹇', - '𖹨' => '𖹈', - '𖹩' => '𖹉', - '𖹪' => '𖹊', - '𖹫' => '𖹋', - '𖹬' => '𖹌', - '𖹭' => '𖹍', - '𖹮' => '𖹎', - '𖹯' => '𖹏', - '𖹰' => '𖹐', - '𖹱' => '𖹑', - '𖹲' => '𖹒', - '𖹳' => '𖹓', - '𖹴' => '𖹔', - '𖹵' => '𖹕', - '𖹶' => '𖹖', - '𖹷' => '𖹗', - '𖹸' => '𖹘', - '𖹹' => '𖹙', - '𖹺' => '𖹚', - '𖹻' => '𖹛', - '𖹼' => '𖹜', - '𖹽' => '𖹝', - '𖹾' => '𖹞', - '𖹿' => '𖹟', - '𞤢' => '𞤀', - '𞤣' => '𞤁', - '𞤤' => '𞤂', - '𞤥' => '𞤃', - '𞤦' => '𞤄', - '𞤧' => '𞤅', - '𞤨' => '𞤆', - '𞤩' => '𞤇', - '𞤪' => '𞤈', - '𞤫' => '𞤉', - '𞤬' => '𞤊', - '𞤭' => '𞤋', - '𞤮' => '𞤌', - '𞤯' => '𞤍', - '𞤰' => '𞤎', - '𞤱' => '𞤏', - '𞤲' => '𞤐', - '𞤳' => '𞤑', - '𞤴' => '𞤒', - '𞤵' => '𞤓', - '𞤶' => '𞤔', - '𞤷' => '𞤕', - '𞤸' => '𞤖', - '𞤹' => '𞤗', - '𞤺' => '𞤘', - '𞤻' => '𞤙', - '𞤼' => '𞤚', - '𞤽' => '𞤛', - '𞤾' => '𞤜', - '𞤿' => '𞤝', - '𞥀' => '𞤞', - '𞥁' => '𞤟', - '𞥂' => '𞤠', - '𞥃' => '𞤡', - 'ß' => '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/vendor/symfony/polyfill-mbstring/bootstrap.php b/vendor/symfony/polyfill-mbstring/bootstrap.php deleted file mode 100644 index 1fedd1f7c..000000000 --- a/vendor/symfony/polyfill-mbstring/bootstrap.php +++ /dev/null @@ -1,147 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Mbstring as p; - -if (\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 (extension_loaded('mbstring')) { - return; -} - -if (!defined('MB_CASE_UPPER')) { - define('MB_CASE_UPPER', 0); -} -if (!defined('MB_CASE_LOWER')) { - define('MB_CASE_LOWER', 1); -} -if (!defined('MB_CASE_TITLE')) { - define('MB_CASE_TITLE', 2); -} diff --git a/vendor/symfony/polyfill-mbstring/bootstrap80.php b/vendor/symfony/polyfill-mbstring/bootstrap80.php deleted file mode 100644 index 82f5ac4d0..000000000 --- a/vendor/symfony/polyfill-mbstring/bootstrap80.php +++ /dev/null @@ -1,143 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Mbstring as p; - -if (!function_exists('mb_convert_encoding')) { - function mb_convert_encoding(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 { 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 (extension_loaded('mbstring')) { - return; -} - -if (!defined('MB_CASE_UPPER')) { - define('MB_CASE_UPPER', 0); -} -if (!defined('MB_CASE_LOWER')) { - define('MB_CASE_LOWER', 1); -} -if (!defined('MB_CASE_TITLE')) { - define('MB_CASE_TITLE', 2); -} diff --git a/vendor/symfony/polyfill-php73/Php73.php b/vendor/symfony/polyfill-php73/Php73.php deleted file mode 100644 index 65c35a6a1..000000000 --- a/vendor/symfony/polyfill-php73/Php73.php +++ /dev/null @@ -1,43 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Php73; - -/** - * @author Gabriel Caruso - * @author Ion Bazan - * - * @internal - */ -final class Php73 -{ - public static $startAt = 1533462603; - - /** - * @param bool $asNum - * - * @return array|float|int - */ - public static function hrtime($asNum = false) - { - $ns = microtime(false); - $s = substr($ns, 11) - self::$startAt; - $ns = 1E9 * (float) $ns; - - if ($asNum) { - $ns += $s * 1E9; - - return \PHP_INT_SIZE === 4 ? $ns : (int) $ns; - } - - return [$s, (int) $ns]; - } -} diff --git a/vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php b/vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php deleted file mode 100644 index f06d6c269..000000000 --- a/vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php +++ /dev/null @@ -1,16 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -if (\PHP_VERSION_ID < 70300) { - class JsonException extends Exception - { - } -} diff --git a/vendor/symfony/polyfill-php73/bootstrap.php b/vendor/symfony/polyfill-php73/bootstrap.php deleted file mode 100644 index d6b215382..000000000 --- a/vendor/symfony/polyfill-php73/bootstrap.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Php73 as p; - -if (\PHP_VERSION_ID >= 70300) { - return; -} - -if (!function_exists('is_countable')) { - function is_countable($value) { return is_array($value) || $value instanceof Countable || $value instanceof ResourceBundle || $value instanceof SimpleXmlElement; } -} -if (!function_exists('hrtime')) { - require_once __DIR__.'/Php73.php'; - p\Php73::$startAt = (int) microtime(true); - function hrtime($as_number = false) { return p\Php73::hrtime($as_number); } -} -if (!function_exists('array_key_first')) { - function array_key_first(array $array) { foreach ($array as $key => $value) { return $key; } } -} -if (!function_exists('array_key_last')) { - function array_key_last(array $array) { return key(array_slice($array, -1, 1, true)); } -} diff --git a/vendor/symfony/polyfill-php80/Php80.php b/vendor/symfony/polyfill-php80/Php80.php deleted file mode 100644 index 362dd1a95..000000000 --- a/vendor/symfony/polyfill-php80/Php80.php +++ /dev/null @@ -1,115 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Php80; - -/** - * @author Ion Bazan - * @author Nico Oelgart - * @author Nicolas Grekas - * - * @internal - */ -final class Php80 -{ - public static function fdiv(float $dividend, float $divisor): float - { - return @($dividend / $divisor); - } - - public static function get_debug_type($value): string - { - switch (true) { - case null === $value: return 'null'; - case \is_bool($value): return 'bool'; - case \is_string($value): return 'string'; - case \is_array($value): return 'array'; - case \is_int($value): return 'int'; - case \is_float($value): return 'float'; - case \is_object($value): break; - case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class'; - default: - if (null === $type = @get_resource_type($value)) { - return 'unknown'; - } - - if ('Unknown' === $type) { - $type = 'closed'; - } - - return "resource ($type)"; - } - - $class = \get_class($value); - - if (false === strpos($class, '@')) { - return $class; - } - - return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous'; - } - - public static function get_resource_id($res): int - { - if (!\is_resource($res) && null === @get_resource_type($res)) { - throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res))); - } - - return (int) $res; - } - - public static function preg_last_error_msg(): string - { - switch (preg_last_error()) { - case \PREG_INTERNAL_ERROR: - return 'Internal error'; - case \PREG_BAD_UTF8_ERROR: - return 'Malformed UTF-8 characters, possibly incorrectly encoded'; - case \PREG_BAD_UTF8_OFFSET_ERROR: - return 'The offset did not correspond to the beginning of a valid UTF-8 code point'; - case \PREG_BACKTRACK_LIMIT_ERROR: - return 'Backtrack limit exhausted'; - case \PREG_RECURSION_LIMIT_ERROR: - return 'Recursion limit exhausted'; - case \PREG_JIT_STACKLIMIT_ERROR: - return 'JIT stack limit exhausted'; - case \PREG_NO_ERROR: - return 'No error'; - default: - return 'Unknown error'; - } - } - - public static function str_contains(string $haystack, string $needle): bool - { - return '' === $needle || false !== strpos($haystack, $needle); - } - - public static function str_starts_with(string $haystack, string $needle): bool - { - return 0 === strncmp($haystack, $needle, \strlen($needle)); - } - - public static function str_ends_with(string $haystack, string $needle): bool - { - if ('' === $needle || $needle === $haystack) { - return true; - } - - if ('' === $haystack) { - return false; - } - - $needleLength = \strlen($needle); - - return $needleLength <= \strlen($haystack) && 0 === substr_compare($haystack, $needle, -$needleLength); - } -} diff --git a/vendor/symfony/polyfill-php80/PhpToken.php b/vendor/symfony/polyfill-php80/PhpToken.php deleted file mode 100644 index fe6e69105..000000000 --- a/vendor/symfony/polyfill-php80/PhpToken.php +++ /dev/null @@ -1,103 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Php80; - -/** - * @author Fedonyuk Anton - * - * @internal - */ -class PhpToken implements \Stringable -{ - /** - * @var int - */ - public $id; - - /** - * @var string - */ - public $text; - - /** - * @var int - */ - public $line; - - /** - * @var int - */ - public $pos; - - public function __construct(int $id, string $text, int $line = -1, int $position = -1) - { - $this->id = $id; - $this->text = $text; - $this->line = $line; - $this->pos = $position; - } - - public function getTokenName(): ?string - { - if ('UNKNOWN' === $name = token_name($this->id)) { - $name = \strlen($this->text) > 1 || \ord($this->text) < 32 ? null : $this->text; - } - - return $name; - } - - /** - * @param int|string|array $kind - */ - public function is($kind): bool - { - foreach ((array) $kind as $value) { - if (\in_array($value, [$this->id, $this->text], true)) { - return true; - } - } - - return false; - } - - public function isIgnorable(): bool - { - return \in_array($this->id, [\T_WHITESPACE, \T_COMMENT, \T_DOC_COMMENT, \T_OPEN_TAG], true); - } - - public function __toString(): string - { - return (string) $this->text; - } - - /** - * @return static[] - */ - public static function tokenize(string $code, int $flags = 0): array - { - $line = 1; - $position = 0; - $tokens = token_get_all($code, $flags); - foreach ($tokens as $index => $token) { - if (\is_string($token)) { - $id = \ord($token); - $text = $token; - } else { - [$id, $text, $line] = $token; - } - $tokens[$index] = new static($id, $text, $line, $position); - $position += \strlen($text); - } - - return $tokens; - } -} diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php b/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php deleted file mode 100644 index 7ea6d2772..000000000 --- a/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php +++ /dev/null @@ -1,22 +0,0 @@ -flags = $flags; - } -} diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php b/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php deleted file mode 100644 index 72f10812b..000000000 --- a/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php +++ /dev/null @@ -1,7 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Php80 as p; - -if (\PHP_VERSION_ID >= 80000) { - return; -} - -if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) { - define('FILTER_VALIDATE_BOOL', \FILTER_VALIDATE_BOOLEAN); -} - -if (!function_exists('fdiv')) { - function fdiv(float $num1, float $num2): float { return p\Php80::fdiv($num1, $num2); } -} -if (!function_exists('preg_last_error_msg')) { - function preg_last_error_msg(): string { return p\Php80::preg_last_error_msg(); } -} -if (!function_exists('str_contains')) { - function str_contains(?string $haystack, ?string $needle): bool { return p\Php80::str_contains($haystack ?? '', $needle ?? ''); } -} -if (!function_exists('str_starts_with')) { - function str_starts_with(?string $haystack, ?string $needle): bool { return p\Php80::str_starts_with($haystack ?? '', $needle ?? ''); } -} -if (!function_exists('str_ends_with')) { - function str_ends_with(?string $haystack, ?string $needle): bool { return p\Php80::str_ends_with($haystack ?? '', $needle ?? ''); } -} -if (!function_exists('get_debug_type')) { - function get_debug_type($value): string { return p\Php80::get_debug_type($value); } -} -if (!function_exists('get_resource_id')) { - function get_resource_id($resource): int { return p\Php80::get_resource_id($resource); } -} diff --git a/vendor/symfony/process/Exception/ExceptionInterface.php b/vendor/symfony/process/Exception/ExceptionInterface.php deleted file mode 100644 index bd4a60403..000000000 --- a/vendor/symfony/process/Exception/ExceptionInterface.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Exception; - -/** - * Marker Interface for the Process Component. - * - * @author Johannes M. Schmitt - */ -interface ExceptionInterface extends \Throwable -{ -} diff --git a/vendor/symfony/process/Exception/InvalidArgumentException.php b/vendor/symfony/process/Exception/InvalidArgumentException.php deleted file mode 100644 index 926ee2118..000000000 --- a/vendor/symfony/process/Exception/InvalidArgumentException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Exception; - -/** - * InvalidArgumentException for the Process Component. - * - * @author Romain Neutron - */ -class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface -{ -} diff --git a/vendor/symfony/process/Exception/LogicException.php b/vendor/symfony/process/Exception/LogicException.php deleted file mode 100644 index be3d490dd..000000000 --- a/vendor/symfony/process/Exception/LogicException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Exception; - -/** - * LogicException for the Process Component. - * - * @author Romain Neutron - */ -class LogicException extends \LogicException implements ExceptionInterface -{ -} diff --git a/vendor/symfony/process/Exception/ProcessFailedException.php b/vendor/symfony/process/Exception/ProcessFailedException.php deleted file mode 100644 index 328acfde5..000000000 --- a/vendor/symfony/process/Exception/ProcessFailedException.php +++ /dev/null @@ -1,54 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Exception; - -use Symfony\Component\Process\Process; - -/** - * Exception for failed processes. - * - * @author Johannes M. Schmitt - */ -class ProcessFailedException extends RuntimeException -{ - private $process; - - public function __construct(Process $process) - { - if ($process->isSuccessful()) { - throw new InvalidArgumentException('Expected a failed process, but the given process was successful.'); - } - - $error = sprintf('The command "%s" failed.'."\n\nExit Code: %s(%s)\n\nWorking directory: %s", - $process->getCommandLine(), - $process->getExitCode(), - $process->getExitCodeText(), - $process->getWorkingDirectory() - ); - - if (!$process->isOutputDisabled()) { - $error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s", - $process->getOutput(), - $process->getErrorOutput() - ); - } - - parent::__construct($error); - - $this->process = $process; - } - - public function getProcess() - { - return $this->process; - } -} diff --git a/vendor/symfony/process/Exception/ProcessSignaledException.php b/vendor/symfony/process/Exception/ProcessSignaledException.php deleted file mode 100644 index d4d322756..000000000 --- a/vendor/symfony/process/Exception/ProcessSignaledException.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Exception; - -use Symfony\Component\Process\Process; - -/** - * Exception that is thrown when a process has been signaled. - * - * @author Sullivan Senechal - */ -final class ProcessSignaledException extends RuntimeException -{ - private $process; - - public function __construct(Process $process) - { - $this->process = $process; - - parent::__construct(sprintf('The process has been signaled with signal "%s".', $process->getTermSignal())); - } - - public function getProcess(): Process - { - return $this->process; - } - - public function getSignal(): int - { - return $this->getProcess()->getTermSignal(); - } -} diff --git a/vendor/symfony/process/Exception/ProcessTimedOutException.php b/vendor/symfony/process/Exception/ProcessTimedOutException.php deleted file mode 100644 index 94391a459..000000000 --- a/vendor/symfony/process/Exception/ProcessTimedOutException.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Exception; - -use Symfony\Component\Process\Process; - -/** - * Exception that is thrown when a process times out. - * - * @author Johannes M. Schmitt - */ -class ProcessTimedOutException extends RuntimeException -{ - public const TYPE_GENERAL = 1; - public const TYPE_IDLE = 2; - - private $process; - private $timeoutType; - - public function __construct(Process $process, int $timeoutType) - { - $this->process = $process; - $this->timeoutType = $timeoutType; - - parent::__construct(sprintf( - 'The process "%s" exceeded the timeout of %s seconds.', - $process->getCommandLine(), - $this->getExceededTimeout() - )); - } - - public function getProcess() - { - return $this->process; - } - - public function isGeneralTimeout() - { - return self::TYPE_GENERAL === $this->timeoutType; - } - - public function isIdleTimeout() - { - return self::TYPE_IDLE === $this->timeoutType; - } - - public function getExceededTimeout() - { - switch ($this->timeoutType) { - case self::TYPE_GENERAL: - return $this->process->getTimeout(); - - case self::TYPE_IDLE: - return $this->process->getIdleTimeout(); - - default: - throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType)); - } - } -} diff --git a/vendor/symfony/process/Exception/RuntimeException.php b/vendor/symfony/process/Exception/RuntimeException.php deleted file mode 100644 index adead2536..000000000 --- a/vendor/symfony/process/Exception/RuntimeException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Exception; - -/** - * RuntimeException for the Process Component. - * - * @author Johannes M. Schmitt - */ -class RuntimeException extends \RuntimeException implements ExceptionInterface -{ -} diff --git a/vendor/symfony/process/ExecutableFinder.php b/vendor/symfony/process/ExecutableFinder.php deleted file mode 100644 index 5914b4cd2..000000000 --- a/vendor/symfony/process/ExecutableFinder.php +++ /dev/null @@ -1,86 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process; - -/** - * Generic executable finder. - * - * @author Fabien Potencier - * @author Johannes M. Schmitt - */ -class ExecutableFinder -{ - private $suffixes = ['.exe', '.bat', '.cmd', '.com']; - - /** - * Replaces default suffixes of executable. - */ - public function setSuffixes(array $suffixes) - { - $this->suffixes = $suffixes; - } - - /** - * Adds new possible suffix to check for executable. - */ - public function addSuffix(string $suffix) - { - $this->suffixes[] = $suffix; - } - - /** - * Finds an executable by name. - * - * @param string $name The executable name (without the extension) - * @param string|null $default The default to return if no executable is found - * @param array $extraDirs Additional dirs to check into - * - * @return string|null - */ - public function find(string $name, string $default = null, array $extraDirs = []) - { - if (ini_get('open_basedir')) { - $searchPath = array_merge(explode(\PATH_SEPARATOR, ini_get('open_basedir')), $extraDirs); - $dirs = []; - foreach ($searchPath as $path) { - // Silencing against https://bugs.php.net/69240 - if (@is_dir($path)) { - $dirs[] = $path; - } else { - if (basename($path) == $name && @is_executable($path)) { - return $path; - } - } - } - } else { - $dirs = array_merge( - explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')), - $extraDirs - ); - } - - $suffixes = ['']; - if ('\\' === \DIRECTORY_SEPARATOR) { - $pathExt = getenv('PATHEXT'); - $suffixes = array_merge($pathExt ? explode(\PATH_SEPARATOR, $pathExt) : $this->suffixes, $suffixes); - } - foreach ($suffixes as $suffix) { - foreach ($dirs as $dir) { - if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) { - return $file; - } - } - } - - return $default; - } -} diff --git a/vendor/symfony/process/InputStream.php b/vendor/symfony/process/InputStream.php deleted file mode 100644 index 240665f32..000000000 --- a/vendor/symfony/process/InputStream.php +++ /dev/null @@ -1,96 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process; - -use Symfony\Component\Process\Exception\RuntimeException; - -/** - * Provides a way to continuously write to the input of a Process until the InputStream is closed. - * - * @author Nicolas Grekas - * - * @implements \IteratorAggregate - */ -class InputStream implements \IteratorAggregate -{ - /** @var callable|null */ - private $onEmpty = null; - private $input = []; - private $open = true; - - /** - * Sets a callback that is called when the write buffer becomes empty. - */ - public function onEmpty(callable $onEmpty = null) - { - $this->onEmpty = $onEmpty; - } - - /** - * Appends an input to the write buffer. - * - * @param resource|string|int|float|bool|\Traversable|null $input The input to append as scalar, - * stream resource or \Traversable - */ - public function write($input) - { - if (null === $input) { - return; - } - if ($this->isClosed()) { - throw new RuntimeException(sprintf('"%s" is closed.', static::class)); - } - $this->input[] = ProcessUtils::validateInput(__METHOD__, $input); - } - - /** - * Closes the write buffer. - */ - public function close() - { - $this->open = false; - } - - /** - * Tells whether the write buffer is closed or not. - */ - public function isClosed() - { - return !$this->open; - } - - /** - * @return \Traversable - */ - #[\ReturnTypeWillChange] - public function getIterator() - { - $this->open = true; - - while ($this->open || $this->input) { - if (!$this->input) { - yield ''; - continue; - } - $current = array_shift($this->input); - - if ($current instanceof \Iterator) { - yield from $current; - } else { - yield $current; - } - if (!$this->input && $this->open && null !== $onEmpty = $this->onEmpty) { - $this->write($onEmpty($this)); - } - } - } -} diff --git a/vendor/symfony/process/PhpExecutableFinder.php b/vendor/symfony/process/PhpExecutableFinder.php deleted file mode 100644 index ec24f911b..000000000 --- a/vendor/symfony/process/PhpExecutableFinder.php +++ /dev/null @@ -1,99 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process; - -/** - * An executable finder specifically designed for the PHP executable. - * - * @author Fabien Potencier - * @author Johannes M. Schmitt - */ -class PhpExecutableFinder -{ - private $executableFinder; - - public function __construct() - { - $this->executableFinder = new ExecutableFinder(); - } - - /** - * Finds The PHP executable. - * - * @return string|false - */ - public function find(bool $includeArgs = true) - { - if ($php = getenv('PHP_BINARY')) { - if (!is_executable($php)) { - $command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v'; - if ($php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) { - if (!is_executable($php)) { - return false; - } - } else { - return false; - } - } - - return $php; - } - - $args = $this->findArguments(); - $args = $includeArgs && $args ? ' '.implode(' ', $args) : ''; - - // PHP_BINARY return the current sapi executable - if (\PHP_BINARY && \in_array(\PHP_SAPI, ['cgi-fcgi', 'cli', 'cli-server', 'phpdbg'], true)) { - return \PHP_BINARY.$args; - } - - if ($php = getenv('PHP_PATH')) { - if (!@is_executable($php)) { - return false; - } - - return $php; - } - - if ($php = getenv('PHP_PEAR_PHP_BIN')) { - if (@is_executable($php)) { - return $php; - } - } - - if (@is_executable($php = \PHP_BINDIR.('\\' === \DIRECTORY_SEPARATOR ? '\\php.exe' : '/php'))) { - return $php; - } - - $dirs = [\PHP_BINDIR]; - if ('\\' === \DIRECTORY_SEPARATOR) { - $dirs[] = 'C:\xampp\php\\'; - } - - return $this->executableFinder->find('php', false, $dirs); - } - - /** - * Finds the PHP executable arguments. - * - * @return array - */ - public function findArguments() - { - $arguments = []; - if ('phpdbg' === \PHP_SAPI) { - $arguments[] = '-qrr'; - } - - return $arguments; - } -} diff --git a/vendor/symfony/process/PhpProcess.php b/vendor/symfony/process/PhpProcess.php deleted file mode 100644 index 2bc338e5e..000000000 --- a/vendor/symfony/process/PhpProcess.php +++ /dev/null @@ -1,72 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process; - -use Symfony\Component\Process\Exception\LogicException; -use Symfony\Component\Process\Exception\RuntimeException; - -/** - * PhpProcess runs a PHP script in an independent process. - * - * $p = new PhpProcess(''); - * $p->run(); - * print $p->getOutput()."\n"; - * - * @author Fabien Potencier - */ -class PhpProcess extends Process -{ - /** - * @param string $script The PHP script to run (as a string) - * @param string|null $cwd The working directory or null to use the working dir of the current PHP process - * @param array|null $env The environment variables or null to use the same environment as the current PHP process - * @param int $timeout The timeout in seconds - * @param array|null $php Path to the PHP binary to use with any additional arguments - */ - public function __construct(string $script, string $cwd = null, array $env = null, int $timeout = 60, array $php = null) - { - if (null === $php) { - $executableFinder = new PhpExecutableFinder(); - $php = $executableFinder->find(false); - $php = false === $php ? null : array_merge([$php], $executableFinder->findArguments()); - } - if ('phpdbg' === \PHP_SAPI) { - $file = tempnam(sys_get_temp_dir(), 'dbg'); - file_put_contents($file, $script); - register_shutdown_function('unlink', $file); - $php[] = $file; - $script = null; - } - - parent::__construct($php, $cwd, $env, $script, $timeout); - } - - /** - * {@inheritdoc} - */ - public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) - { - throw new LogicException(sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class)); - } - - /** - * {@inheritdoc} - */ - public function start(callable $callback = null, array $env = []) - { - if (null === $this->getCommandLine()) { - throw new RuntimeException('Unable to find the PHP executable.'); - } - - parent::start($callback, $env); - } -} diff --git a/vendor/symfony/process/Pipes/AbstractPipes.php b/vendor/symfony/process/Pipes/AbstractPipes.php deleted file mode 100644 index 010510056..000000000 --- a/vendor/symfony/process/Pipes/AbstractPipes.php +++ /dev/null @@ -1,180 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Pipes; - -use Symfony\Component\Process\Exception\InvalidArgumentException; - -/** - * @author Romain Neutron - * - * @internal - */ -abstract class AbstractPipes implements PipesInterface -{ - public $pipes = []; - - private $inputBuffer = ''; - private $input; - private $blocked = true; - private $lastError; - - /** - * @param resource|string|int|float|bool|\Iterator|null $input - */ - public function __construct($input) - { - if (\is_resource($input) || $input instanceof \Iterator) { - $this->input = $input; - } elseif (\is_string($input)) { - $this->inputBuffer = $input; - } else { - $this->inputBuffer = (string) $input; - } - } - - /** - * {@inheritdoc} - */ - public function close() - { - foreach ($this->pipes as $pipe) { - if (\is_resource($pipe)) { - fclose($pipe); - } - } - $this->pipes = []; - } - - /** - * Returns true if a system call has been interrupted. - */ - protected function hasSystemCallBeenInterrupted(): bool - { - $lastError = $this->lastError; - $this->lastError = null; - - // stream_select returns false when the `select` system call is interrupted by an incoming signal - return null !== $lastError && false !== stripos($lastError, 'interrupted system call'); - } - - /** - * Unblocks streams. - */ - protected function unblock() - { - if (!$this->blocked) { - return; - } - - foreach ($this->pipes as $pipe) { - stream_set_blocking($pipe, 0); - } - if (\is_resource($this->input)) { - stream_set_blocking($this->input, 0); - } - - $this->blocked = false; - } - - /** - * Writes input to stdin. - * - * @throws InvalidArgumentException When an input iterator yields a non supported value - */ - protected function write(): ?array - { - if (!isset($this->pipes[0])) { - return null; - } - $input = $this->input; - - if ($input instanceof \Iterator) { - if (!$input->valid()) { - $input = null; - } elseif (\is_resource($input = $input->current())) { - stream_set_blocking($input, 0); - } elseif (!isset($this->inputBuffer[0])) { - if (!\is_string($input)) { - if (!is_scalar($input)) { - throw new InvalidArgumentException(sprintf('"%s" yielded a value of type "%s", but only scalars and stream resources are supported.', get_debug_type($this->input), get_debug_type($input))); - } - $input = (string) $input; - } - $this->inputBuffer = $input; - $this->input->next(); - $input = null; - } else { - $input = null; - } - } - - $r = $e = []; - $w = [$this->pipes[0]]; - - // let's have a look if something changed in streams - if (false === @stream_select($r, $w, $e, 0, 0)) { - return null; - } - - foreach ($w as $stdin) { - if (isset($this->inputBuffer[0])) { - $written = fwrite($stdin, $this->inputBuffer); - $this->inputBuffer = substr($this->inputBuffer, $written); - if (isset($this->inputBuffer[0])) { - return [$this->pipes[0]]; - } - } - - if ($input) { - while (true) { - $data = fread($input, self::CHUNK_SIZE); - if (!isset($data[0])) { - break; - } - $written = fwrite($stdin, $data); - $data = substr($data, $written); - if (isset($data[0])) { - $this->inputBuffer = $data; - - return [$this->pipes[0]]; - } - } - if (feof($input)) { - if ($this->input instanceof \Iterator) { - $this->input->next(); - } else { - $this->input = null; - } - } - } - } - - // no input to read on resource, buffer is empty - if (!isset($this->inputBuffer[0]) && !($this->input instanceof \Iterator ? $this->input->valid() : $this->input)) { - $this->input = null; - fclose($this->pipes[0]); - unset($this->pipes[0]); - } elseif (!$w) { - return [$this->pipes[0]]; - } - - return null; - } - - /** - * @internal - */ - public function handleError(int $type, string $msg) - { - $this->lastError = $msg; - } -} diff --git a/vendor/symfony/process/Pipes/PipesInterface.php b/vendor/symfony/process/Pipes/PipesInterface.php deleted file mode 100644 index 50eb5c47e..000000000 --- a/vendor/symfony/process/Pipes/PipesInterface.php +++ /dev/null @@ -1,61 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Pipes; - -/** - * PipesInterface manages descriptors and pipes for the use of proc_open. - * - * @author Romain Neutron - * - * @internal - */ -interface PipesInterface -{ - public const CHUNK_SIZE = 16384; - - /** - * Returns an array of descriptors for the use of proc_open. - */ - public function getDescriptors(): array; - - /** - * Returns an array of filenames indexed by their related stream in case these pipes use temporary files. - * - * @return string[] - */ - public function getFiles(): array; - - /** - * Reads data in file handles and pipes. - * - * @param bool $blocking Whether to use blocking calls or not - * @param bool $close Whether to close pipes if they've reached EOF - * - * @return string[] An array of read data indexed by their fd - */ - public function readAndWrite(bool $blocking, bool $close = false): array; - - /** - * Returns if the current state has open file handles or pipes. - */ - public function areOpen(): bool; - - /** - * Returns if pipes are able to read output. - */ - public function haveReadSupport(): bool; - - /** - * Closes file handles and pipes. - */ - public function close(); -} diff --git a/vendor/symfony/process/Pipes/UnixPipes.php b/vendor/symfony/process/Pipes/UnixPipes.php deleted file mode 100644 index 5a0e9d47f..000000000 --- a/vendor/symfony/process/Pipes/UnixPipes.php +++ /dev/null @@ -1,163 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Pipes; - -use Symfony\Component\Process\Process; - -/** - * UnixPipes implementation uses unix pipes as handles. - * - * @author Romain Neutron - * - * @internal - */ -class UnixPipes extends AbstractPipes -{ - private $ttyMode; - private $ptyMode; - private $haveReadSupport; - - public function __construct(?bool $ttyMode, bool $ptyMode, $input, bool $haveReadSupport) - { - $this->ttyMode = $ttyMode; - $this->ptyMode = $ptyMode; - $this->haveReadSupport = $haveReadSupport; - - parent::__construct($input); - } - - public function __sleep(): array - { - throw new \BadMethodCallException('Cannot serialize '.__CLASS__); - } - - public function __wakeup() - { - throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); - } - - public function __destruct() - { - $this->close(); - } - - /** - * {@inheritdoc} - */ - public function getDescriptors(): array - { - if (!$this->haveReadSupport) { - $nullstream = fopen('/dev/null', 'c'); - - return [ - ['pipe', 'r'], - $nullstream, - $nullstream, - ]; - } - - if ($this->ttyMode) { - return [ - ['file', '/dev/tty', 'r'], - ['file', '/dev/tty', 'w'], - ['file', '/dev/tty', 'w'], - ]; - } - - if ($this->ptyMode && Process::isPtySupported()) { - return [ - ['pty'], - ['pty'], - ['pty'], - ]; - } - - return [ - ['pipe', 'r'], - ['pipe', 'w'], // stdout - ['pipe', 'w'], // stderr - ]; - } - - /** - * {@inheritdoc} - */ - public function getFiles(): array - { - return []; - } - - /** - * {@inheritdoc} - */ - public function readAndWrite(bool $blocking, bool $close = false): array - { - $this->unblock(); - $w = $this->write(); - - $read = $e = []; - $r = $this->pipes; - unset($r[0]); - - // let's have a look if something changed in streams - set_error_handler([$this, 'handleError']); - if (($r || $w) && false === stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) { - restore_error_handler(); - // if a system call has been interrupted, forget about it, let's try again - // otherwise, an error occurred, let's reset pipes - if (!$this->hasSystemCallBeenInterrupted()) { - $this->pipes = []; - } - - return $read; - } - restore_error_handler(); - - foreach ($r as $pipe) { - // prior PHP 5.4 the array passed to stream_select is modified and - // lose key association, we have to find back the key - $read[$type = array_search($pipe, $this->pipes, true)] = ''; - - do { - $data = @fread($pipe, self::CHUNK_SIZE); - $read[$type] .= $data; - } while (isset($data[0]) && ($close || isset($data[self::CHUNK_SIZE - 1]))); - - if (!isset($read[$type][0])) { - unset($read[$type]); - } - - if ($close && feof($pipe)) { - fclose($pipe); - unset($this->pipes[$type]); - } - } - - return $read; - } - - /** - * {@inheritdoc} - */ - public function haveReadSupport(): bool - { - return $this->haveReadSupport; - } - - /** - * {@inheritdoc} - */ - public function areOpen(): bool - { - return (bool) $this->pipes; - } -} diff --git a/vendor/symfony/process/Pipes/WindowsPipes.php b/vendor/symfony/process/Pipes/WindowsPipes.php deleted file mode 100644 index bca84f574..000000000 --- a/vendor/symfony/process/Pipes/WindowsPipes.php +++ /dev/null @@ -1,204 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Pipes; - -use Symfony\Component\Process\Exception\RuntimeException; -use Symfony\Component\Process\Process; - -/** - * WindowsPipes implementation uses temporary files as handles. - * - * @see https://bugs.php.net/51800 - * @see https://bugs.php.net/65650 - * - * @author Romain Neutron - * - * @internal - */ -class WindowsPipes extends AbstractPipes -{ - private $files = []; - private $fileHandles = []; - private $lockHandles = []; - private $readBytes = [ - Process::STDOUT => 0, - Process::STDERR => 0, - ]; - private $haveReadSupport; - - public function __construct($input, bool $haveReadSupport) - { - $this->haveReadSupport = $haveReadSupport; - - if ($this->haveReadSupport) { - // Fix for PHP bug #51800: reading from STDOUT pipe hangs forever on Windows if the output is too big. - // Workaround for this problem is to use temporary files instead of pipes on Windows platform. - // - // @see https://bugs.php.net/51800 - $pipes = [ - Process::STDOUT => Process::OUT, - Process::STDERR => Process::ERR, - ]; - $tmpDir = sys_get_temp_dir(); - $lastError = 'unknown reason'; - set_error_handler(function ($type, $msg) use (&$lastError) { $lastError = $msg; }); - for ($i = 0;; ++$i) { - foreach ($pipes as $pipe => $name) { - $file = sprintf('%s\\sf_proc_%02X.%s', $tmpDir, $i, $name); - - if (!$h = fopen($file.'.lock', 'w')) { - if (file_exists($file.'.lock')) { - continue 2; - } - restore_error_handler(); - throw new RuntimeException('A temporary file could not be opened to write the process output: '.$lastError); - } - if (!flock($h, \LOCK_EX | \LOCK_NB)) { - continue 2; - } - if (isset($this->lockHandles[$pipe])) { - flock($this->lockHandles[$pipe], \LOCK_UN); - fclose($this->lockHandles[$pipe]); - } - $this->lockHandles[$pipe] = $h; - - if (!($h = fopen($file, 'w')) || !fclose($h) || !$h = fopen($file, 'r')) { - flock($this->lockHandles[$pipe], \LOCK_UN); - fclose($this->lockHandles[$pipe]); - unset($this->lockHandles[$pipe]); - continue 2; - } - $this->fileHandles[$pipe] = $h; - $this->files[$pipe] = $file; - } - break; - } - restore_error_handler(); - } - - parent::__construct($input); - } - - public function __sleep(): array - { - throw new \BadMethodCallException('Cannot serialize '.__CLASS__); - } - - public function __wakeup() - { - throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); - } - - public function __destruct() - { - $this->close(); - } - - /** - * {@inheritdoc} - */ - public function getDescriptors(): array - { - if (!$this->haveReadSupport) { - $nullstream = fopen('NUL', 'c'); - - return [ - ['pipe', 'r'], - $nullstream, - $nullstream, - ]; - } - - // We're not using pipe on Windows platform as it hangs (https://bugs.php.net/51800) - // We're not using file handles as it can produce corrupted output https://bugs.php.net/65650 - // So we redirect output within the commandline and pass the nul device to the process - return [ - ['pipe', 'r'], - ['file', 'NUL', 'w'], - ['file', 'NUL', 'w'], - ]; - } - - /** - * {@inheritdoc} - */ - public function getFiles(): array - { - return $this->files; - } - - /** - * {@inheritdoc} - */ - public function readAndWrite(bool $blocking, bool $close = false): array - { - $this->unblock(); - $w = $this->write(); - $read = $r = $e = []; - - if ($blocking) { - if ($w) { - @stream_select($r, $w, $e, 0, Process::TIMEOUT_PRECISION * 1E6); - } elseif ($this->fileHandles) { - usleep(Process::TIMEOUT_PRECISION * 1E6); - } - } - foreach ($this->fileHandles as $type => $fileHandle) { - $data = stream_get_contents($fileHandle, -1, $this->readBytes[$type]); - - if (isset($data[0])) { - $this->readBytes[$type] += \strlen($data); - $read[$type] = $data; - } - if ($close) { - ftruncate($fileHandle, 0); - fclose($fileHandle); - flock($this->lockHandles[$type], \LOCK_UN); - fclose($this->lockHandles[$type]); - unset($this->fileHandles[$type], $this->lockHandles[$type]); - } - } - - return $read; - } - - /** - * {@inheritdoc} - */ - public function haveReadSupport(): bool - { - return $this->haveReadSupport; - } - - /** - * {@inheritdoc} - */ - public function areOpen(): bool - { - return $this->pipes && $this->fileHandles; - } - - /** - * {@inheritdoc} - */ - public function close() - { - parent::close(); - foreach ($this->fileHandles as $type => $handle) { - ftruncate($handle, 0); - fclose($handle); - flock($this->lockHandles[$type], \LOCK_UN); - fclose($this->lockHandles[$type]); - } - $this->fileHandles = $this->lockHandles = []; - } -} diff --git a/vendor/symfony/process/Process.php b/vendor/symfony/process/Process.php deleted file mode 100644 index 92771594d..000000000 --- a/vendor/symfony/process/Process.php +++ /dev/null @@ -1,1652 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process; - -use Symfony\Component\Process\Exception\InvalidArgumentException; -use Symfony\Component\Process\Exception\LogicException; -use Symfony\Component\Process\Exception\ProcessFailedException; -use Symfony\Component\Process\Exception\ProcessSignaledException; -use Symfony\Component\Process\Exception\ProcessTimedOutException; -use Symfony\Component\Process\Exception\RuntimeException; -use Symfony\Component\Process\Pipes\PipesInterface; -use Symfony\Component\Process\Pipes\UnixPipes; -use Symfony\Component\Process\Pipes\WindowsPipes; - -/** - * Process is a thin wrapper around proc_* functions to easily - * start independent PHP processes. - * - * @author Fabien Potencier - * @author Romain Neutron - * - * @implements \IteratorAggregate - */ -class Process implements \IteratorAggregate -{ - public const ERR = 'err'; - public const OUT = 'out'; - - public const STATUS_READY = 'ready'; - public const STATUS_STARTED = 'started'; - public const STATUS_TERMINATED = 'terminated'; - - public const STDIN = 0; - public const STDOUT = 1; - public const STDERR = 2; - - // Timeout Precision in seconds. - public const TIMEOUT_PRECISION = 0.2; - - public const ITER_NON_BLOCKING = 1; // By default, iterating over outputs is a blocking call, use this flag to make it non-blocking - public const ITER_KEEP_OUTPUT = 2; // By default, outputs are cleared while iterating, use this flag to keep them in memory - public const ITER_SKIP_OUT = 4; // Use this flag to skip STDOUT while iterating - public const ITER_SKIP_ERR = 8; // Use this flag to skip STDERR while iterating - - private $callback; - private $hasCallback = false; - private $commandline; - private $cwd; - private $env; - private $input; - private $starttime; - private $lastOutputTime; - private $timeout; - private $idleTimeout; - private $exitcode; - private $fallbackStatus = []; - private $processInformation; - private $outputDisabled = false; - private $stdout; - private $stderr; - private $process; - private $status = self::STATUS_READY; - private $incrementalOutputOffset = 0; - private $incrementalErrorOutputOffset = 0; - private $tty = false; - private $pty; - private $options = ['suppress_errors' => true, 'bypass_shell' => true]; - - private $useFileHandles = false; - /** @var PipesInterface */ - private $processPipes; - - private $latestSignal; - - private static $sigchild; - - /** - * Exit codes translation table. - * - * User-defined errors must use exit codes in the 64-113 range. - */ - public static $exitCodes = [ - 0 => 'OK', - 1 => 'General error', - 2 => 'Misuse of shell builtins', - - 126 => 'Invoked command cannot execute', - 127 => 'Command not found', - 128 => 'Invalid exit argument', - - // signals - 129 => 'Hangup', - 130 => 'Interrupt', - 131 => 'Quit and dump core', - 132 => 'Illegal instruction', - 133 => 'Trace/breakpoint trap', - 134 => 'Process aborted', - 135 => 'Bus error: "access to undefined portion of memory object"', - 136 => 'Floating point exception: "erroneous arithmetic operation"', - 137 => 'Kill (terminate immediately)', - 138 => 'User-defined 1', - 139 => 'Segmentation violation', - 140 => 'User-defined 2', - 141 => 'Write to pipe with no one reading', - 142 => 'Signal raised by alarm', - 143 => 'Termination (request to terminate)', - // 144 - not defined - 145 => 'Child process terminated, stopped (or continued*)', - 146 => 'Continue if stopped', - 147 => 'Stop executing temporarily', - 148 => 'Terminal stop signal', - 149 => 'Background process attempting to read from tty ("in")', - 150 => 'Background process attempting to write to tty ("out")', - 151 => 'Urgent data available on socket', - 152 => 'CPU time limit exceeded', - 153 => 'File size limit exceeded', - 154 => 'Signal raised by timer counting virtual time: "virtual timer expired"', - 155 => 'Profiling timer expired', - // 156 - not defined - 157 => 'Pollable event', - // 158 - not defined - 159 => 'Bad syscall', - ]; - - /** - * @param array $command The command to run and its arguments listed as separate entries - * @param string|null $cwd The working directory or null to use the working dir of the current PHP process - * @param array|null $env The environment variables or null to use the same environment as the current PHP process - * @param mixed $input The input as stream resource, scalar or \Traversable, or null for no input - * @param int|float|null $timeout The timeout in seconds or null to disable - * - * @throws LogicException When proc_open is not installed - */ - public function __construct(array $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) - { - if (!\function_exists('proc_open')) { - throw new LogicException('The Process class relies on proc_open, which is not available on your PHP installation.'); - } - - $this->commandline = $command; - $this->cwd = $cwd; - - // on Windows, if the cwd changed via chdir(), proc_open defaults to the dir where PHP was started - // on Gnu/Linux, PHP builds with --enable-maintainer-zts are also affected - // @see : https://bugs.php.net/51800 - // @see : https://bugs.php.net/50524 - if (null === $this->cwd && (\defined('ZEND_THREAD_SAFE') || '\\' === \DIRECTORY_SEPARATOR)) { - $this->cwd = getcwd(); - } - if (null !== $env) { - $this->setEnv($env); - } - - $this->setInput($input); - $this->setTimeout($timeout); - $this->useFileHandles = '\\' === \DIRECTORY_SEPARATOR; - $this->pty = false; - } - - /** - * Creates a Process instance as a command-line to be run in a shell wrapper. - * - * Command-lines are parsed by the shell of your OS (/bin/sh on Unix-like, cmd.exe on Windows.) - * This allows using e.g. pipes or conditional execution. In this mode, signals are sent to the - * shell wrapper and not to your commands. - * - * In order to inject dynamic values into command-lines, we strongly recommend using placeholders. - * This will save escaping values, which is not portable nor secure anyway: - * - * $process = Process::fromShellCommandline('my_command "${:MY_VAR}"'); - * $process->run(null, ['MY_VAR' => $theValue]); - * - * @param string $command The command line to pass to the shell of the OS - * @param string|null $cwd The working directory or null to use the working dir of the current PHP process - * @param array|null $env The environment variables or null to use the same environment as the current PHP process - * @param mixed $input The input as stream resource, scalar or \Traversable, or null for no input - * @param int|float|null $timeout The timeout in seconds or null to disable - * - * @return static - * - * @throws LogicException When proc_open is not installed - */ - public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) - { - $process = new static([], $cwd, $env, $input, $timeout); - $process->commandline = $command; - - return $process; - } - - /** - * @return array - */ - public function __sleep() - { - throw new \BadMethodCallException('Cannot serialize '.__CLASS__); - } - - public function __wakeup() - { - throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); - } - - public function __destruct() - { - if ($this->options['create_new_console'] ?? false) { - $this->processPipes->close(); - } else { - $this->stop(0); - } - } - - public function __clone() - { - $this->resetProcessData(); - } - - /** - * Runs the process. - * - * The callback receives the type of output (out or err) and - * some bytes from the output in real-time. It allows to have feedback - * from the independent process during execution. - * - * The STDOUT and STDERR are also available after the process is finished - * via the getOutput() and getErrorOutput() methods. - * - * @param callable|null $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR - * - * @return int The exit status code - * - * @throws RuntimeException When process can't be launched - * @throws RuntimeException When process is already running - * @throws ProcessTimedOutException When process timed out - * @throws ProcessSignaledException When process stopped after receiving signal - * @throws LogicException In case a callback is provided and output has been disabled - * - * @final - */ - public function run(callable $callback = null, array $env = []): int - { - $this->start($callback, $env); - - return $this->wait(); - } - - /** - * Runs the process. - * - * This is identical to run() except that an exception is thrown if the process - * exits with a non-zero exit code. - * - * @return $this - * - * @throws ProcessFailedException if the process didn't terminate successfully - * - * @final - */ - public function mustRun(callable $callback = null, array $env = []): self - { - if (0 !== $this->run($callback, $env)) { - throw new ProcessFailedException($this); - } - - return $this; - } - - /** - * Starts the process and returns after writing the input to STDIN. - * - * This method blocks until all STDIN data is sent to the process then it - * returns while the process runs in the background. - * - * The termination of the process can be awaited with wait(). - * - * The callback receives the type of output (out or err) and some bytes from - * the output in real-time while writing the standard input to the process. - * It allows to have feedback from the independent process during execution. - * - * @param callable|null $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR - * - * @throws RuntimeException When process can't be launched - * @throws RuntimeException When process is already running - * @throws LogicException In case a callback is provided and output has been disabled - */ - public function start(callable $callback = null, array $env = []) - { - if ($this->isRunning()) { - throw new RuntimeException('Process is already running.'); - } - - $this->resetProcessData(); - $this->starttime = $this->lastOutputTime = microtime(true); - $this->callback = $this->buildCallback($callback); - $this->hasCallback = null !== $callback; - $descriptors = $this->getDescriptors(); - - if ($this->env) { - $env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->env, $env, 'strcasecmp') : $this->env; - } - - $env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->getDefaultEnv(), $env, 'strcasecmp') : $this->getDefaultEnv(); - - if (\is_array($commandline = $this->commandline)) { - $commandline = implode(' ', array_map([$this, 'escapeArgument'], $commandline)); - - if ('\\' !== \DIRECTORY_SEPARATOR) { - // exec is mandatory to deal with sending a signal to the process - $commandline = 'exec '.$commandline; - } - } else { - $commandline = $this->replacePlaceholders($commandline, $env); - } - - if ('\\' === \DIRECTORY_SEPARATOR) { - $commandline = $this->prepareWindowsCommandLine($commandline, $env); - } elseif (!$this->useFileHandles && $this->isSigchildEnabled()) { - // last exit code is output on the fourth pipe and caught to work around --enable-sigchild - $descriptors[3] = ['pipe', 'w']; - - // See https://unix.stackexchange.com/questions/71205/background-process-pipe-input - $commandline = '{ ('.$commandline.') <&3 3<&- 3>/dev/null & } 3<&0;'; - $commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code'; - - // Workaround for the bug, when PTS functionality is enabled. - // @see : https://bugs.php.net/69442 - $ptsWorkaround = fopen(__FILE__, 'r'); - } - - $envPairs = []; - foreach ($env as $k => $v) { - if (false !== $v && false === \in_array($k, ['argc', 'argv', 'ARGC', 'ARGV'], true)) { - $envPairs[] = $k.'='.$v; - } - } - - if (!is_dir($this->cwd)) { - throw new RuntimeException(sprintf('The provided cwd "%s" does not exist.', $this->cwd)); - } - - $this->process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options); - - if (!\is_resource($this->process)) { - throw new RuntimeException('Unable to launch a new process.'); - } - $this->status = self::STATUS_STARTED; - - if (isset($descriptors[3])) { - $this->fallbackStatus['pid'] = (int) fgets($this->processPipes->pipes[3]); - } - - if ($this->tty) { - return; - } - - $this->updateStatus(false); - $this->checkTimeout(); - } - - /** - * Restarts the process. - * - * Be warned that the process is cloned before being started. - * - * @param callable|null $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR - * - * @return static - * - * @throws RuntimeException When process can't be launched - * @throws RuntimeException When process is already running - * - * @see start() - * - * @final - */ - public function restart(callable $callback = null, array $env = []): self - { - if ($this->isRunning()) { - throw new RuntimeException('Process is already running.'); - } - - $process = clone $this; - $process->start($callback, $env); - - return $process; - } - - /** - * Waits for the process to terminate. - * - * The callback receives the type of output (out or err) and some bytes - * from the output in real-time while writing the standard input to the process. - * It allows to have feedback from the independent process during execution. - * - * @param callable|null $callback A valid PHP callback - * - * @return int The exitcode of the process - * - * @throws ProcessTimedOutException When process timed out - * @throws ProcessSignaledException When process stopped after receiving signal - * @throws LogicException When process is not yet started - */ - public function wait(callable $callback = null) - { - $this->requireProcessIsStarted(__FUNCTION__); - - $this->updateStatus(false); - - if (null !== $callback) { - if (!$this->processPipes->haveReadSupport()) { - $this->stop(0); - throw new LogicException('Pass the callback to the "Process::start" method or call enableOutput to use a callback with "Process::wait".'); - } - $this->callback = $this->buildCallback($callback); - } - - do { - $this->checkTimeout(); - $running = '\\' === \DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen(); - $this->readPipes($running, '\\' !== \DIRECTORY_SEPARATOR || !$running); - } while ($running); - - while ($this->isRunning()) { - $this->checkTimeout(); - usleep(1000); - } - - if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) { - throw new ProcessSignaledException($this); - } - - return $this->exitcode; - } - - /** - * Waits until the callback returns true. - * - * The callback receives the type of output (out or err) and some bytes - * from the output in real-time while writing the standard input to the process. - * It allows to have feedback from the independent process during execution. - * - * @throws RuntimeException When process timed out - * @throws LogicException When process is not yet started - * @throws ProcessTimedOutException In case the timeout was reached - */ - public function waitUntil(callable $callback): bool - { - $this->requireProcessIsStarted(__FUNCTION__); - $this->updateStatus(false); - - if (!$this->processPipes->haveReadSupport()) { - $this->stop(0); - throw new LogicException('Pass the callback to the "Process::start" method or call enableOutput to use a callback with "Process::waitUntil".'); - } - $callback = $this->buildCallback($callback); - - $ready = false; - while (true) { - $this->checkTimeout(); - $running = '\\' === \DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen(); - $output = $this->processPipes->readAndWrite($running, '\\' !== \DIRECTORY_SEPARATOR || !$running); - - foreach ($output as $type => $data) { - if (3 !== $type) { - $ready = $callback(self::STDOUT === $type ? self::OUT : self::ERR, $data) || $ready; - } elseif (!isset($this->fallbackStatus['signaled'])) { - $this->fallbackStatus['exitcode'] = (int) $data; - } - } - if ($ready) { - return true; - } - if (!$running) { - return false; - } - - usleep(1000); - } - } - - /** - * Returns the Pid (process identifier), if applicable. - * - * @return int|null The process id if running, null otherwise - */ - public function getPid() - { - return $this->isRunning() ? $this->processInformation['pid'] : null; - } - - /** - * Sends a POSIX signal to the process. - * - * @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants) - * - * @return $this - * - * @throws LogicException In case the process is not running - * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed - * @throws RuntimeException In case of failure - */ - public function signal(int $signal) - { - $this->doSignal($signal, true); - - return $this; - } - - /** - * Disables fetching output and error output from the underlying process. - * - * @return $this - * - * @throws RuntimeException In case the process is already running - * @throws LogicException if an idle timeout is set - */ - public function disableOutput() - { - if ($this->isRunning()) { - throw new RuntimeException('Disabling output while the process is running is not possible.'); - } - if (null !== $this->idleTimeout) { - throw new LogicException('Output cannot be disabled while an idle timeout is set.'); - } - - $this->outputDisabled = true; - - return $this; - } - - /** - * Enables fetching output and error output from the underlying process. - * - * @return $this - * - * @throws RuntimeException In case the process is already running - */ - public function enableOutput() - { - if ($this->isRunning()) { - throw new RuntimeException('Enabling output while the process is running is not possible.'); - } - - $this->outputDisabled = false; - - return $this; - } - - /** - * Returns true in case the output is disabled, false otherwise. - * - * @return bool - */ - public function isOutputDisabled() - { - return $this->outputDisabled; - } - - /** - * Returns the current output of the process (STDOUT). - * - * @return string - * - * @throws LogicException in case the output has been disabled - * @throws LogicException In case the process is not started - */ - public function getOutput() - { - $this->readPipesForOutput(__FUNCTION__); - - if (false === $ret = stream_get_contents($this->stdout, -1, 0)) { - return ''; - } - - return $ret; - } - - /** - * Returns the output incrementally. - * - * In comparison with the getOutput method which always return the whole - * output, this one returns the new output since the last call. - * - * @return string - * - * @throws LogicException in case the output has been disabled - * @throws LogicException In case the process is not started - */ - public function getIncrementalOutput() - { - $this->readPipesForOutput(__FUNCTION__); - - $latest = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset); - $this->incrementalOutputOffset = ftell($this->stdout); - - if (false === $latest) { - return ''; - } - - return $latest; - } - - /** - * Returns an iterator to the output of the process, with the output type as keys (Process::OUT/ERR). - * - * @param int $flags A bit field of Process::ITER_* flags - * - * @throws LogicException in case the output has been disabled - * @throws LogicException In case the process is not started - * - * @return \Generator - */ - #[\ReturnTypeWillChange] - public function getIterator(int $flags = 0) - { - $this->readPipesForOutput(__FUNCTION__, false); - - $clearOutput = !(self::ITER_KEEP_OUTPUT & $flags); - $blocking = !(self::ITER_NON_BLOCKING & $flags); - $yieldOut = !(self::ITER_SKIP_OUT & $flags); - $yieldErr = !(self::ITER_SKIP_ERR & $flags); - - while (null !== $this->callback || ($yieldOut && !feof($this->stdout)) || ($yieldErr && !feof($this->stderr))) { - if ($yieldOut) { - $out = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset); - - if (isset($out[0])) { - if ($clearOutput) { - $this->clearOutput(); - } else { - $this->incrementalOutputOffset = ftell($this->stdout); - } - - yield self::OUT => $out; - } - } - - if ($yieldErr) { - $err = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset); - - if (isset($err[0])) { - if ($clearOutput) { - $this->clearErrorOutput(); - } else { - $this->incrementalErrorOutputOffset = ftell($this->stderr); - } - - yield self::ERR => $err; - } - } - - if (!$blocking && !isset($out[0]) && !isset($err[0])) { - yield self::OUT => ''; - } - - $this->checkTimeout(); - $this->readPipesForOutput(__FUNCTION__, $blocking); - } - } - - /** - * Clears the process output. - * - * @return $this - */ - public function clearOutput() - { - ftruncate($this->stdout, 0); - fseek($this->stdout, 0); - $this->incrementalOutputOffset = 0; - - return $this; - } - - /** - * Returns the current error output of the process (STDERR). - * - * @return string - * - * @throws LogicException in case the output has been disabled - * @throws LogicException In case the process is not started - */ - public function getErrorOutput() - { - $this->readPipesForOutput(__FUNCTION__); - - if (false === $ret = stream_get_contents($this->stderr, -1, 0)) { - return ''; - } - - return $ret; - } - - /** - * Returns the errorOutput incrementally. - * - * In comparison with the getErrorOutput method which always return the - * whole error output, this one returns the new error output since the last - * call. - * - * @return string - * - * @throws LogicException in case the output has been disabled - * @throws LogicException In case the process is not started - */ - public function getIncrementalErrorOutput() - { - $this->readPipesForOutput(__FUNCTION__); - - $latest = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset); - $this->incrementalErrorOutputOffset = ftell($this->stderr); - - if (false === $latest) { - return ''; - } - - return $latest; - } - - /** - * Clears the process output. - * - * @return $this - */ - public function clearErrorOutput() - { - ftruncate($this->stderr, 0); - fseek($this->stderr, 0); - $this->incrementalErrorOutputOffset = 0; - - return $this; - } - - /** - * Returns the exit code returned by the process. - * - * @return int|null The exit status code, null if the Process is not terminated - */ - public function getExitCode() - { - $this->updateStatus(false); - - return $this->exitcode; - } - - /** - * Returns a string representation for the exit code returned by the process. - * - * This method relies on the Unix exit code status standardization - * and might not be relevant for other operating systems. - * - * @return string|null A string representation for the exit status code, null if the Process is not terminated - * - * @see http://tldp.org/LDP/abs/html/exitcodes.html - * @see http://en.wikipedia.org/wiki/Unix_signal - */ - public function getExitCodeText() - { - if (null === $exitcode = $this->getExitCode()) { - return null; - } - - return self::$exitCodes[$exitcode] ?? 'Unknown error'; - } - - /** - * Checks if the process ended successfully. - * - * @return bool - */ - public function isSuccessful() - { - return 0 === $this->getExitCode(); - } - - /** - * Returns true if the child process has been terminated by an uncaught signal. - * - * It always returns false on Windows. - * - * @return bool - * - * @throws LogicException In case the process is not terminated - */ - public function hasBeenSignaled() - { - $this->requireProcessIsTerminated(__FUNCTION__); - - return $this->processInformation['signaled']; - } - - /** - * Returns the number of the signal that caused the child process to terminate its execution. - * - * It is only meaningful if hasBeenSignaled() returns true. - * - * @return int - * - * @throws RuntimeException In case --enable-sigchild is activated - * @throws LogicException In case the process is not terminated - */ - public function getTermSignal() - { - $this->requireProcessIsTerminated(__FUNCTION__); - - if ($this->isSigchildEnabled() && -1 === $this->processInformation['termsig']) { - throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal cannot be retrieved.'); - } - - return $this->processInformation['termsig']; - } - - /** - * Returns true if the child process has been stopped by a signal. - * - * It always returns false on Windows. - * - * @return bool - * - * @throws LogicException In case the process is not terminated - */ - public function hasBeenStopped() - { - $this->requireProcessIsTerminated(__FUNCTION__); - - return $this->processInformation['stopped']; - } - - /** - * Returns the number of the signal that caused the child process to stop its execution. - * - * It is only meaningful if hasBeenStopped() returns true. - * - * @return int - * - * @throws LogicException In case the process is not terminated - */ - public function getStopSignal() - { - $this->requireProcessIsTerminated(__FUNCTION__); - - return $this->processInformation['stopsig']; - } - - /** - * Checks if the process is currently running. - * - * @return bool - */ - public function isRunning() - { - if (self::STATUS_STARTED !== $this->status) { - return false; - } - - $this->updateStatus(false); - - return $this->processInformation['running']; - } - - /** - * Checks if the process has been started with no regard to the current state. - * - * @return bool - */ - public function isStarted() - { - return self::STATUS_READY != $this->status; - } - - /** - * Checks if the process is terminated. - * - * @return bool - */ - public function isTerminated() - { - $this->updateStatus(false); - - return self::STATUS_TERMINATED == $this->status; - } - - /** - * Gets the process status. - * - * The status is one of: ready, started, terminated. - * - * @return string - */ - public function getStatus() - { - $this->updateStatus(false); - - return $this->status; - } - - /** - * Stops the process. - * - * @param int|float $timeout The timeout in seconds - * @param int $signal A POSIX signal to send in case the process has not stop at timeout, default is SIGKILL (9) - * - * @return int|null The exit-code of the process or null if it's not running - */ - public function stop(float $timeout = 10, int $signal = null) - { - $timeoutMicro = microtime(true) + $timeout; - if ($this->isRunning()) { - // given SIGTERM may not be defined and that "proc_terminate" uses the constant value and not the constant itself, we use the same here - $this->doSignal(15, false); - do { - usleep(1000); - } while ($this->isRunning() && microtime(true) < $timeoutMicro); - - if ($this->isRunning()) { - // Avoid exception here: process is supposed to be running, but it might have stopped just - // after this line. In any case, let's silently discard the error, we cannot do anything. - $this->doSignal($signal ?: 9, false); - } - } - - if ($this->isRunning()) { - if (isset($this->fallbackStatus['pid'])) { - unset($this->fallbackStatus['pid']); - - return $this->stop(0, $signal); - } - $this->close(); - } - - return $this->exitcode; - } - - /** - * Adds a line to the STDOUT stream. - * - * @internal - */ - public function addOutput(string $line) - { - $this->lastOutputTime = microtime(true); - - fseek($this->stdout, 0, \SEEK_END); - fwrite($this->stdout, $line); - fseek($this->stdout, $this->incrementalOutputOffset); - } - - /** - * Adds a line to the STDERR stream. - * - * @internal - */ - public function addErrorOutput(string $line) - { - $this->lastOutputTime = microtime(true); - - fseek($this->stderr, 0, \SEEK_END); - fwrite($this->stderr, $line); - fseek($this->stderr, $this->incrementalErrorOutputOffset); - } - - /** - * Gets the last output time in seconds. - */ - public function getLastOutputTime(): ?float - { - return $this->lastOutputTime; - } - - /** - * Gets the command line to be executed. - * - * @return string - */ - public function getCommandLine() - { - return \is_array($this->commandline) ? implode(' ', array_map([$this, 'escapeArgument'], $this->commandline)) : $this->commandline; - } - - /** - * Gets the process timeout in seconds (max. runtime). - * - * @return float|null - */ - public function getTimeout() - { - return $this->timeout; - } - - /** - * Gets the process idle timeout in seconds (max. time since last output). - * - * @return float|null - */ - public function getIdleTimeout() - { - return $this->idleTimeout; - } - - /** - * Sets the process timeout (max. runtime) in seconds. - * - * To disable the timeout, set this value to null. - * - * @return $this - * - * @throws InvalidArgumentException if the timeout is negative - */ - public function setTimeout(?float $timeout) - { - $this->timeout = $this->validateTimeout($timeout); - - return $this; - } - - /** - * Sets the process idle timeout (max. time since last output) in seconds. - * - * To disable the timeout, set this value to null. - * - * @return $this - * - * @throws LogicException if the output is disabled - * @throws InvalidArgumentException if the timeout is negative - */ - public function setIdleTimeout(?float $timeout) - { - if (null !== $timeout && $this->outputDisabled) { - throw new LogicException('Idle timeout cannot be set while the output is disabled.'); - } - - $this->idleTimeout = $this->validateTimeout($timeout); - - return $this; - } - - /** - * Enables or disables the TTY mode. - * - * @return $this - * - * @throws RuntimeException In case the TTY mode is not supported - */ - public function setTty(bool $tty) - { - if ('\\' === \DIRECTORY_SEPARATOR && $tty) { - throw new RuntimeException('TTY mode is not supported on Windows platform.'); - } - - if ($tty && !self::isTtySupported()) { - throw new RuntimeException('TTY mode requires /dev/tty to be read/writable.'); - } - - $this->tty = $tty; - - return $this; - } - - /** - * Checks if the TTY mode is enabled. - * - * @return bool - */ - public function isTty() - { - return $this->tty; - } - - /** - * Sets PTY mode. - * - * @return $this - */ - public function setPty(bool $bool) - { - $this->pty = $bool; - - return $this; - } - - /** - * Returns PTY state. - * - * @return bool - */ - public function isPty() - { - return $this->pty; - } - - /** - * Gets the working directory. - * - * @return string|null - */ - public function getWorkingDirectory() - { - if (null === $this->cwd) { - // getcwd() will return false if any one of the parent directories does not have - // the readable or search mode set, even if the current directory does - return getcwd() ?: null; - } - - return $this->cwd; - } - - /** - * Sets the current working directory. - * - * @return $this - */ - public function setWorkingDirectory(string $cwd) - { - $this->cwd = $cwd; - - return $this; - } - - /** - * Gets the environment variables. - * - * @return array - */ - public function getEnv() - { - return $this->env; - } - - /** - * Sets the environment variables. - * - * @param array $env The new environment variables - * - * @return $this - */ - public function setEnv(array $env) - { - $this->env = $env; - - return $this; - } - - /** - * Gets the Process input. - * - * @return resource|string|\Iterator|null - */ - public function getInput() - { - return $this->input; - } - - /** - * Sets the input. - * - * This content will be passed to the underlying process standard input. - * - * @param string|int|float|bool|resource|\Traversable|null $input The content - * - * @return $this - * - * @throws LogicException In case the process is running - */ - public function setInput($input) - { - if ($this->isRunning()) { - throw new LogicException('Input cannot be set while the process is running.'); - } - - $this->input = ProcessUtils::validateInput(__METHOD__, $input); - - return $this; - } - - /** - * Performs a check between the timeout definition and the time the process started. - * - * In case you run a background process (with the start method), you should - * trigger this method regularly to ensure the process timeout - * - * @throws ProcessTimedOutException In case the timeout was reached - */ - public function checkTimeout() - { - if (self::STATUS_STARTED !== $this->status) { - return; - } - - if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) { - $this->stop(0); - - throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_GENERAL); - } - - if (null !== $this->idleTimeout && $this->idleTimeout < microtime(true) - $this->lastOutputTime) { - $this->stop(0); - - throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_IDLE); - } - } - - /** - * @throws LogicException in case process is not started - */ - public function getStartTime(): float - { - if (!$this->isStarted()) { - throw new LogicException('Start time is only available after process start.'); - } - - return $this->starttime; - } - - /** - * Defines options to pass to the underlying proc_open(). - * - * @see https://php.net/proc_open for the options supported by PHP. - * - * Enabling the "create_new_console" option allows a subprocess to continue - * to run after the main process exited, on both Windows and *nix - */ - public function setOptions(array $options) - { - if ($this->isRunning()) { - throw new RuntimeException('Setting options while the process is running is not possible.'); - } - - $defaultOptions = $this->options; - $existingOptions = ['blocking_pipes', 'create_process_group', 'create_new_console']; - - foreach ($options as $key => $value) { - if (!\in_array($key, $existingOptions)) { - $this->options = $defaultOptions; - throw new LogicException(sprintf('Invalid option "%s" passed to "%s()". Supported options are "%s".', $key, __METHOD__, implode('", "', $existingOptions))); - } - $this->options[$key] = $value; - } - } - - /** - * Returns whether TTY is supported on the current operating system. - */ - public static function isTtySupported(): bool - { - static $isTtySupported; - - if (null === $isTtySupported) { - $isTtySupported = (bool) @proc_open('echo 1 >/dev/null', [['file', '/dev/tty', 'r'], ['file', '/dev/tty', 'w'], ['file', '/dev/tty', 'w']], $pipes); - } - - return $isTtySupported; - } - - /** - * Returns whether PTY is supported on the current operating system. - * - * @return bool - */ - public static function isPtySupported() - { - static $result; - - if (null !== $result) { - return $result; - } - - if ('\\' === \DIRECTORY_SEPARATOR) { - return $result = false; - } - - return $result = (bool) @proc_open('echo 1 >/dev/null', [['pty'], ['pty'], ['pty']], $pipes); - } - - /** - * Creates the descriptors needed by the proc_open. - */ - private function getDescriptors(): array - { - if ($this->input instanceof \Iterator) { - $this->input->rewind(); - } - if ('\\' === \DIRECTORY_SEPARATOR) { - $this->processPipes = new WindowsPipes($this->input, !$this->outputDisabled || $this->hasCallback); - } else { - $this->processPipes = new UnixPipes($this->isTty(), $this->isPty(), $this->input, !$this->outputDisabled || $this->hasCallback); - } - - return $this->processPipes->getDescriptors(); - } - - /** - * Builds up the callback used by wait(). - * - * The callbacks adds all occurred output to the specific buffer and calls - * the user callback (if present) with the received output. - * - * @param callable|null $callback The user defined PHP callback - * - * @return \Closure - */ - protected function buildCallback(callable $callback = null) - { - if ($this->outputDisabled) { - return function ($type, $data) use ($callback): bool { - return null !== $callback && $callback($type, $data); - }; - } - - $out = self::OUT; - - return function ($type, $data) use ($callback, $out): bool { - if ($out == $type) { - $this->addOutput($data); - } else { - $this->addErrorOutput($data); - } - - return null !== $callback && $callback($type, $data); - }; - } - - /** - * Updates the status of the process, reads pipes. - * - * @param bool $blocking Whether to use a blocking read call - */ - protected function updateStatus(bool $blocking) - { - if (self::STATUS_STARTED !== $this->status) { - return; - } - - $this->processInformation = proc_get_status($this->process); - $running = $this->processInformation['running']; - - $this->readPipes($running && $blocking, '\\' !== \DIRECTORY_SEPARATOR || !$running); - - if ($this->fallbackStatus && $this->isSigchildEnabled()) { - $this->processInformation = $this->fallbackStatus + $this->processInformation; - } - - if (!$running) { - $this->close(); - } - } - - /** - * Returns whether PHP has been compiled with the '--enable-sigchild' option or not. - * - * @return bool - */ - protected function isSigchildEnabled() - { - if (null !== self::$sigchild) { - return self::$sigchild; - } - - if (!\function_exists('phpinfo')) { - return self::$sigchild = false; - } - - ob_start(); - phpinfo(\INFO_GENERAL); - - return self::$sigchild = str_contains(ob_get_clean(), '--enable-sigchild'); - } - - /** - * Reads pipes for the freshest output. - * - * @param string $caller The name of the method that needs fresh outputs - * @param bool $blocking Whether to use blocking calls or not - * - * @throws LogicException in case output has been disabled or process is not started - */ - private function readPipesForOutput(string $caller, bool $blocking = false) - { - if ($this->outputDisabled) { - throw new LogicException('Output has been disabled.'); - } - - $this->requireProcessIsStarted($caller); - - $this->updateStatus($blocking); - } - - /** - * Validates and returns the filtered timeout. - * - * @throws InvalidArgumentException if the given timeout is a negative number - */ - private function validateTimeout(?float $timeout): ?float - { - $timeout = (float) $timeout; - - if (0.0 === $timeout) { - $timeout = null; - } elseif ($timeout < 0) { - throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.'); - } - - return $timeout; - } - - /** - * Reads pipes, executes callback. - * - * @param bool $blocking Whether to use blocking calls or not - * @param bool $close Whether to close file handles or not - */ - private function readPipes(bool $blocking, bool $close) - { - $result = $this->processPipes->readAndWrite($blocking, $close); - - $callback = $this->callback; - foreach ($result as $type => $data) { - if (3 !== $type) { - $callback(self::STDOUT === $type ? self::OUT : self::ERR, $data); - } elseif (!isset($this->fallbackStatus['signaled'])) { - $this->fallbackStatus['exitcode'] = (int) $data; - } - } - } - - /** - * Closes process resource, closes file handles, sets the exitcode. - * - * @return int The exitcode - */ - private function close(): int - { - $this->processPipes->close(); - if (\is_resource($this->process)) { - proc_close($this->process); - } - $this->exitcode = $this->processInformation['exitcode']; - $this->status = self::STATUS_TERMINATED; - - if (-1 === $this->exitcode) { - if ($this->processInformation['signaled'] && 0 < $this->processInformation['termsig']) { - // if process has been signaled, no exitcode but a valid termsig, apply Unix convention - $this->exitcode = 128 + $this->processInformation['termsig']; - } elseif ($this->isSigchildEnabled()) { - $this->processInformation['signaled'] = true; - $this->processInformation['termsig'] = -1; - } - } - - // Free memory from self-reference callback created by buildCallback - // Doing so in other contexts like __destruct or by garbage collector is ineffective - // Now pipes are closed, so the callback is no longer necessary - $this->callback = null; - - return $this->exitcode; - } - - /** - * Resets data related to the latest run of the process. - */ - private function resetProcessData() - { - $this->starttime = null; - $this->callback = null; - $this->exitcode = null; - $this->fallbackStatus = []; - $this->processInformation = null; - $this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+'); - $this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+'); - $this->process = null; - $this->latestSignal = null; - $this->status = self::STATUS_READY; - $this->incrementalOutputOffset = 0; - $this->incrementalErrorOutputOffset = 0; - } - - /** - * Sends a POSIX signal to the process. - * - * @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants) - * @param bool $throwException Whether to throw exception in case signal failed - * - * @throws LogicException In case the process is not running - * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed - * @throws RuntimeException In case of failure - */ - private function doSignal(int $signal, bool $throwException): bool - { - if (null === $pid = $this->getPid()) { - if ($throwException) { - throw new LogicException('Cannot send signal on a non running process.'); - } - - return false; - } - - if ('\\' === \DIRECTORY_SEPARATOR) { - exec(sprintf('taskkill /F /T /PID %d 2>&1', $pid), $output, $exitCode); - if ($exitCode && $this->isRunning()) { - if ($throwException) { - throw new RuntimeException(sprintf('Unable to kill the process (%s).', implode(' ', $output))); - } - - return false; - } - } else { - if (!$this->isSigchildEnabled()) { - $ok = @proc_terminate($this->process, $signal); - } elseif (\function_exists('posix_kill')) { - $ok = @posix_kill($pid, $signal); - } elseif ($ok = proc_open(sprintf('kill -%d %d', $signal, $pid), [2 => ['pipe', 'w']], $pipes)) { - $ok = false === fgets($pipes[2]); - } - if (!$ok) { - if ($throwException) { - throw new RuntimeException(sprintf('Error while sending signal "%s".', $signal)); - } - - return false; - } - } - - $this->latestSignal = $signal; - $this->fallbackStatus['signaled'] = true; - $this->fallbackStatus['exitcode'] = -1; - $this->fallbackStatus['termsig'] = $this->latestSignal; - - return true; - } - - private function prepareWindowsCommandLine(string $cmd, array &$env): string - { - $uid = uniqid('', true); - $varCount = 0; - $varCache = []; - $cmd = preg_replace_callback( - '/"(?:( - [^"%!^]*+ - (?: - (?: !LF! | "(?:\^[%!^])?+" ) - [^"%!^]*+ - )++ - ) | [^"]*+ )"/x', - function ($m) use (&$env, &$varCache, &$varCount, $uid) { - if (!isset($m[1])) { - return $m[0]; - } - if (isset($varCache[$m[0]])) { - return $varCache[$m[0]]; - } - if (str_contains($value = $m[1], "\0")) { - $value = str_replace("\0", '?', $value); - } - if (false === strpbrk($value, "\"%!\n")) { - return '"'.$value.'"'; - } - - $value = str_replace(['!LF!', '"^!"', '"^%"', '"^^"', '""'], ["\n", '!', '%', '^', '"'], $value); - $value = '"'.preg_replace('/(\\\\*)"/', '$1$1\\"', $value).'"'; - $var = $uid.++$varCount; - - $env[$var] = $value; - - return $varCache[$m[0]] = '!'.$var.'!'; - }, - $cmd - ); - - $cmd = 'cmd /V:ON /E:ON /D /C ('.str_replace("\n", ' ', $cmd).')'; - foreach ($this->processPipes->getFiles() as $offset => $filename) { - $cmd .= ' '.$offset.'>"'.$filename.'"'; - } - - return $cmd; - } - - /** - * Ensures the process is running or terminated, throws a LogicException if the process has a not started. - * - * @throws LogicException if the process has not run - */ - private function requireProcessIsStarted(string $functionName) - { - if (!$this->isStarted()) { - throw new LogicException(sprintf('Process must be started before calling "%s()".', $functionName)); - } - } - - /** - * Ensures the process is terminated, throws a LogicException if the process has a status different than "terminated". - * - * @throws LogicException if the process is not yet terminated - */ - private function requireProcessIsTerminated(string $functionName) - { - if (!$this->isTerminated()) { - throw new LogicException(sprintf('Process must be terminated before calling "%s()".', $functionName)); - } - } - - /** - * Escapes a string to be used as a shell argument. - */ - private function escapeArgument(?string $argument): string - { - if ('' === $argument || null === $argument) { - return '""'; - } - if ('\\' !== \DIRECTORY_SEPARATOR) { - return "'".str_replace("'", "'\\''", $argument)."'"; - } - if (str_contains($argument, "\0")) { - $argument = str_replace("\0", '?', $argument); - } - if (!preg_match('/[\/()%!^"<>&|\s]/', $argument)) { - return $argument; - } - $argument = preg_replace('/(\\\\+)$/', '$1$1', $argument); - - return '"'.str_replace(['"', '^', '%', '!', "\n"], ['""', '"^^"', '"^%"', '"^!"', '!LF!'], $argument).'"'; - } - - private function replacePlaceholders(string $commandline, array $env) - { - return preg_replace_callback('/"\$\{:([_a-zA-Z]++[_a-zA-Z0-9]*+)\}"/', function ($matches) use ($commandline, $env) { - if (!isset($env[$matches[1]]) || false === $env[$matches[1]]) { - throw new InvalidArgumentException(sprintf('Command line is missing a value for parameter "%s": ', $matches[1]).$commandline); - } - - return $this->escapeArgument($env[$matches[1]]); - }, $commandline); - } - - private function getDefaultEnv(): array - { - $env = getenv(); - $env = ('\\' === \DIRECTORY_SEPARATOR ? array_intersect_ukey($env, $_SERVER, 'strcasecmp') : array_intersect_key($env, $_SERVER)) ?: $env; - - return $_ENV + ('\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($env, $_ENV, 'strcasecmp') : $env); - } -} diff --git a/vendor/symfony/process/ProcessUtils.php b/vendor/symfony/process/ProcessUtils.php deleted file mode 100644 index 6cc7a610b..000000000 --- a/vendor/symfony/process/ProcessUtils.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process; - -use Symfony\Component\Process\Exception\InvalidArgumentException; - -/** - * ProcessUtils is a bunch of utility methods. - * - * This class contains static methods only and is not meant to be instantiated. - * - * @author Martin Hasoň - */ -class ProcessUtils -{ - /** - * This class should not be instantiated. - */ - private function __construct() - { - } - - /** - * Validates and normalizes a Process input. - * - * @param string $caller The name of method call that validates the input - * @param mixed $input The input to validate - * - * @return mixed - * - * @throws InvalidArgumentException In case the input is not valid - */ - public static function validateInput(string $caller, $input) - { - if (null !== $input) { - if (\is_resource($input)) { - return $input; - } - if (\is_string($input)) { - return $input; - } - if (is_scalar($input)) { - return (string) $input; - } - if ($input instanceof Process) { - return $input->getIterator($input::ITER_SKIP_ERR); - } - if ($input instanceof \Iterator) { - return $input; - } - if ($input instanceof \Traversable) { - return new \IteratorIterator($input); - } - - throw new InvalidArgumentException(sprintf('"%s" only accepts strings, Traversable objects or stream resources.', $caller)); - } - - return $input; - } -} diff --git a/vendor/symfony/service-contracts/Attribute/Required.php b/vendor/symfony/service-contracts/Attribute/Required.php deleted file mode 100644 index 9df851189..000000000 --- a/vendor/symfony/service-contracts/Attribute/Required.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * 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/vendor/symfony/service-contracts/Attribute/SubscribedService.php b/vendor/symfony/service-contracts/Attribute/SubscribedService.php deleted file mode 100644 index 10d1bc38e..000000000 --- a/vendor/symfony/service-contracts/Attribute/SubscribedService.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * 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\ServiceSubscriberTrait; - -/** - * Use with {@see ServiceSubscriberTrait} to mark a method's return type - * as a subscribed service. - * - * @author Kevin Bond - */ -#[\Attribute(\Attribute::TARGET_METHOD)] -final class SubscribedService -{ - /** - * @param string|null $key The key to use for the service - * If null, use "ClassName::methodName" - */ - public function __construct( - public ?string $key = null - ) { - } -} diff --git a/vendor/symfony/service-contracts/ResetInterface.php b/vendor/symfony/service-contracts/ResetInterface.php deleted file mode 100644 index 1af1075ee..000000000 --- a/vendor/symfony/service-contracts/ResetInterface.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Contracts\Service; - -/** - * Provides a way to reset an object to its initial state. - * - * When calling the "reset()" method on an object, it should be put back to its - * initial state. This usually means clearing any internal buffers and forwarding - * the call to internal dependencies. All properties of the object should be put - * back to the same state it had when it was first ready to use. - * - * This method could be called, for example, to recycle objects that are used as - * services, so that they can be used to handle several requests in the same - * process loop (note that we advise making your services stateless instead of - * implementing this interface when possible.) - */ -interface ResetInterface -{ - public function reset(); -} diff --git a/vendor/symfony/service-contracts/ServiceLocatorTrait.php b/vendor/symfony/service-contracts/ServiceLocatorTrait.php deleted file mode 100644 index 74dfa4362..000000000 --- a/vendor/symfony/service-contracts/ServiceLocatorTrait.php +++ /dev/null @@ -1,128 +0,0 @@ - - * - * 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 $factories; - private $loading = []; - private $providedTypes; - - /** - * @param callable[] $factories - */ - public function __construct(array $factories) - { - $this->factories = $factories; - } - - /** - * {@inheritdoc} - * - * @return bool - */ - public function has(string $id) - { - return isset($this->factories[$id]); - } - - /** - * {@inheritdoc} - * - * @return mixed - */ - public function get(string $id) - { - if (!isset($this->factories[$id])) { - throw $this->createNotFoundException($id); - } - - if (isset($this->loading[$id])) { - $ids = array_values($this->loading); - $ids = \array_slice($this->loading, array_search($id, $ids)); - $ids[] = $id; - - throw $this->createCircularReferenceException($id, $ids); - } - - $this->loading[$id] = $id; - try { - return $this->factories[$id]($this); - } finally { - unset($this->loading[$id]); - } - } - - /** - * {@inheritdoc} - */ - public function getProvidedServices(): array - { - if (null === $this->providedTypes) { - $this->providedTypes = []; - - foreach ($this->factories as $name => $factory) { - if (!\is_callable($factory)) { - $this->providedTypes[$name] = '?'; - } else { - $type = (new \ReflectionFunction($factory))->getReturnType(); - - $this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '').($type instanceof \ReflectionNamedType ? $type->getName() : $type) : '?'; - } - } - } - - return $this->providedTypes; - } - - private function createNotFoundException(string $id): NotFoundExceptionInterface - { - if (!$alternatives = array_keys($this->factories)) { - $message = 'is empty...'; - } else { - $last = array_pop($alternatives); - if ($alternatives) { - $message = sprintf('only knows about the "%s" and "%s" services.', implode('", "', $alternatives), $last); - } else { - $message = sprintf('only knows about the "%s" service.', $last); - } - } - - if ($this->loading) { - $message = sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $message); - } else { - $message = sprintf('Service "%s" not found: the current service locator %s', $id, $message); - } - - return new class($message) extends \InvalidArgumentException implements NotFoundExceptionInterface { - }; - } - - private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface - { - return new class(sprintf('Circular reference detected for service "%s", path: "%s".', $id, implode(' -> ', $path))) extends \RuntimeException implements ContainerExceptionInterface { - }; - } -} diff --git a/vendor/symfony/service-contracts/ServiceProviderInterface.php b/vendor/symfony/service-contracts/ServiceProviderInterface.php deleted file mode 100644 index c60ad0bd4..000000000 --- a/vendor/symfony/service-contracts/ServiceProviderInterface.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * 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 - */ -interface ServiceProviderInterface extends ContainerInterface -{ - /** - * Returns an associative array of service types keyed by the identifiers provided by the current container. - * - * Examples: - * - * * ['logger' => 'Psr\Log\LoggerInterface'] means the object provides a service named "logger" that implements Psr\Log\LoggerInterface - * * ['foo' => '?'] means the container provides service name "foo" of unspecified type - * * ['bar' => '?Bar\Baz'] means the container provides a service "bar" of type Bar\Baz|null - * - * @return string[] The provided service types, keyed by service names - */ - public function getProvidedServices(): array; -} diff --git a/vendor/symfony/service-contracts/ServiceSubscriberInterface.php b/vendor/symfony/service-contracts/ServiceSubscriberInterface.php deleted file mode 100644 index 098ab908c..000000000 --- a/vendor/symfony/service-contracts/ServiceSubscriberInterface.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. - */ - -namespace Symfony\Contracts\Service; - -/** - * A ServiceSubscriber exposes its dependencies via the static {@link getSubscribedServices} method. - * - * The getSubscribedServices method returns an array of service types required by such instances, - * optionally keyed by the service names used internally. Service types that start with an interrogation - * mark "?" are optional, while the other ones are mandatory service dependencies. - * - * The injected service locators SHOULD NOT allow access to any other services not specified by the method. - * - * It is expected that ServiceSubscriber instances consume PSR-11-based service locators internally. - * This interface does not dictate any injection method for these service locators, although constructor - * injection is recommended. - * - * @author Nicolas Grekas - */ -interface ServiceSubscriberInterface -{ - /** - * Returns an array of service types required by such instances, optionally keyed by the service names used internally. - * - * For mandatory dependencies: - * - * * ['logger' => 'Psr\Log\LoggerInterface'] means the objects use the "logger" name - * internally to fetch a service which must implement Psr\Log\LoggerInterface. - * * ['loggers' => 'Psr\Log\LoggerInterface[]'] means the objects use the "loggers" name - * internally to fetch an iterable of Psr\Log\LoggerInterface instances. - * * ['Psr\Log\LoggerInterface'] is a shortcut for - * * ['Psr\Log\LoggerInterface' => 'Psr\Log\LoggerInterface'] - * - * otherwise: - * - * * ['logger' => '?Psr\Log\LoggerInterface'] denotes an optional dependency - * * ['loggers' => '?Psr\Log\LoggerInterface[]'] denotes an optional iterable dependency - * * ['?Psr\Log\LoggerInterface'] is a shortcut for - * * ['Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface'] - * - * @return string[] The required service types, optionally keyed by service names - */ - public static function getSubscribedServices(); -} diff --git a/vendor/symfony/service-contracts/ServiceSubscriberTrait.php b/vendor/symfony/service-contracts/ServiceSubscriberTrait.php deleted file mode 100644 index 46cd007b7..000000000 --- a/vendor/symfony/service-contracts/ServiceSubscriberTrait.php +++ /dev/null @@ -1,115 +0,0 @@ - - * - * 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\SubscribedService; - -/** - * Implementation of ServiceSubscriberInterface that determines subscribed services from - * method return types. Service ids are available as "ClassName::methodName". - * - * @author Kevin Bond - */ -trait ServiceSubscriberTrait -{ - /** @var ContainerInterface */ - protected $container; - - /** - * {@inheritdoc} - */ - public static function getSubscribedServices(): array - { - static $services; - - if (null !== $services) { - return $services; - } - - $services = \is_callable(['parent', __FUNCTION__]) ? parent::getSubscribedServices() : []; - $attributeOptIn = false; - - if (\PHP_VERSION_ID >= 80000) { - 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)); - } - - $serviceId = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType; - - if ($returnType->allowsNull()) { - $serviceId = '?'.$serviceId; - } - - $services[$attribute->newInstance()->key ?? self::class.'::'.$method->name] = $serviceId; - $attributeOptIn = true; - } - } - - if (!$attributeOptIn) { - foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { - if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) { - continue; - } - - if (self::class !== $method->getDeclaringClass()->name) { - continue; - } - - if (!($returnType = $method->getReturnType()) instanceof \ReflectionNamedType) { - continue; - } - - if ($returnType->isBuiltin()) { - continue; - } - - if (\PHP_VERSION_ID >= 80000) { - trigger_deprecation('symfony/service-contracts', '2.5', 'Using "%s" in "%s" without using the "%s" attribute on any method is deprecated.', ServiceSubscriberTrait::class, self::class, SubscribedService::class); - } - - $services[self::class.'::'.$method->name] = '?'.($returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType); - } - } - - return $services; - } - - /** - * @required - * - * @return ContainerInterface|null - */ - public function setContainer(ContainerInterface $container) - { - $this->container = $container; - - if (\is_callable(['parent', __FUNCTION__])) { - return parent::setContainer($container); - } - - return null; - } -} diff --git a/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php b/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php deleted file mode 100644 index 2a1b565f5..000000000 --- a/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php +++ /dev/null @@ -1,95 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Contracts\Service\Test; - -use PHPUnit\Framework\TestCase; -use Psr\Container\ContainerInterface; -use Symfony\Contracts\Service\ServiceLocatorTrait; - -abstract class ServiceLocatorTest extends TestCase -{ - /** - * @return ContainerInterface - */ - protected function getServiceLocator(array $factories) - { - return new class($factories) implements ContainerInterface { - use ServiceLocatorTrait; - }; - } - - public function testHas() - { - $locator = $this->getServiceLocator([ - 'foo' => function () { return 'bar'; }, - 'bar' => function () { return 'baz'; }, - function () { return 'dummy'; }, - ]); - - $this->assertTrue($locator->has('foo')); - $this->assertTrue($locator->has('bar')); - $this->assertFalse($locator->has('dummy')); - } - - public function testGet() - { - $locator = $this->getServiceLocator([ - 'foo' => function () { return 'bar'; }, - 'bar' => function () { return 'baz'; }, - ]); - - $this->assertSame('bar', $locator->get('foo')); - $this->assertSame('baz', $locator->get('bar')); - } - - public function testGetDoesNotMemoize() - { - $i = 0; - $locator = $this->getServiceLocator([ - 'foo' => function () use (&$i) { - ++$i; - - return 'bar'; - }, - ]); - - $this->assertSame('bar', $locator->get('foo')); - $this->assertSame('bar', $locator->get('foo')); - $this->assertSame(2, $i); - } - - public function testThrowsOnUndefinedInternalService() - { - if (!$this->getExpectedException()) { - $this->expectException(\Psr\Container\NotFoundExceptionInterface::class); - $this->expectExceptionMessage('The service "foo" has a dependency on a non-existent service "bar". This locator only knows about the "foo" service.'); - } - $locator = $this->getServiceLocator([ - 'foo' => function () use (&$locator) { return $locator->get('bar'); }, - ]); - - $locator->get('foo'); - } - - public function testThrowsOnCircularReference() - { - $this->expectException(\Psr\Container\ContainerExceptionInterface::class); - $this->expectExceptionMessage('Circular reference detected for service "bar", path: "bar -> baz -> bar".'); - $locator = $this->getServiceLocator([ - 'foo' => function () use (&$locator) { return $locator->get('bar'); }, - 'bar' => function () use (&$locator) { return $locator->get('baz'); }, - 'baz' => function () use (&$locator) { return $locator->get('bar'); }, - ]); - - $locator->get('foo'); - } -} diff --git a/vendor/symfony/string/AbstractString.php b/vendor/symfony/string/AbstractString.php deleted file mode 100644 index cf21fef1f..000000000 --- a/vendor/symfony/string/AbstractString.php +++ /dev/null @@ -1,795 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String; - -use Symfony\Component\String\Exception\ExceptionInterface; -use Symfony\Component\String\Exception\InvalidArgumentException; -use Symfony\Component\String\Exception\RuntimeException; - -/** - * Represents a string of abstract characters. - * - * Unicode defines 3 types of "characters" (bytes, code points and grapheme clusters). - * This class is the abstract type to use as a type-hint when the logic you want to - * implement doesn't care about the exact variant it deals with. - * - * @author Nicolas Grekas - * @author Hugo Hamon - * - * @throws ExceptionInterface - */ -abstract class AbstractString implements \Stringable, \JsonSerializable -{ - public const PREG_PATTERN_ORDER = \PREG_PATTERN_ORDER; - public const PREG_SET_ORDER = \PREG_SET_ORDER; - public const PREG_OFFSET_CAPTURE = \PREG_OFFSET_CAPTURE; - public const PREG_UNMATCHED_AS_NULL = \PREG_UNMATCHED_AS_NULL; - - public const PREG_SPLIT = 0; - public const PREG_SPLIT_NO_EMPTY = \PREG_SPLIT_NO_EMPTY; - public const PREG_SPLIT_DELIM_CAPTURE = \PREG_SPLIT_DELIM_CAPTURE; - public const PREG_SPLIT_OFFSET_CAPTURE = \PREG_SPLIT_OFFSET_CAPTURE; - - protected $string = ''; - protected $ignoreCase = false; - - abstract public function __construct(string $string = ''); - - /** - * Unwraps instances of AbstractString back to strings. - * - * @return string[]|array - */ - public static function unwrap(array $values): array - { - foreach ($values as $k => $v) { - if ($v instanceof self) { - $values[$k] = $v->__toString(); - } elseif (\is_array($v) && $values[$k] !== $v = static::unwrap($v)) { - $values[$k] = $v; - } - } - - return $values; - } - - /** - * Wraps (and normalizes) strings in instances of AbstractString. - * - * @return static[]|array - */ - public static function wrap(array $values): array - { - $i = 0; - $keys = null; - - foreach ($values as $k => $v) { - if (\is_string($k) && '' !== $k && $k !== $j = (string) new static($k)) { - $keys = $keys ?? array_keys($values); - $keys[$i] = $j; - } - - if (\is_string($v)) { - $values[$k] = new static($v); - } elseif (\is_array($v) && $values[$k] !== $v = static::wrap($v)) { - $values[$k] = $v; - } - - ++$i; - } - - return null !== $keys ? array_combine($keys, $values) : $values; - } - - /** - * @param string|string[] $needle - * - * @return static - */ - public function after($needle, bool $includeNeedle = false, int $offset = 0): self - { - $str = clone $this; - $i = \PHP_INT_MAX; - - foreach ((array) $needle as $n) { - $n = (string) $n; - $j = $this->indexOf($n, $offset); - - if (null !== $j && $j < $i) { - $i = $j; - $str->string = $n; - } - } - - if (\PHP_INT_MAX === $i) { - return $str; - } - - if (!$includeNeedle) { - $i += $str->length(); - } - - return $this->slice($i); - } - - /** - * @param string|string[] $needle - * - * @return static - */ - public function afterLast($needle, bool $includeNeedle = false, int $offset = 0): self - { - $str = clone $this; - $i = null; - - foreach ((array) $needle as $n) { - $n = (string) $n; - $j = $this->indexOfLast($n, $offset); - - if (null !== $j && $j >= $i) { - $i = $offset = $j; - $str->string = $n; - } - } - - if (null === $i) { - return $str; - } - - if (!$includeNeedle) { - $i += $str->length(); - } - - return $this->slice($i); - } - - /** - * @return static - */ - abstract public function append(string ...$suffix): self; - - /** - * @param string|string[] $needle - * - * @return static - */ - public function before($needle, bool $includeNeedle = false, int $offset = 0): self - { - $str = clone $this; - $i = \PHP_INT_MAX; - - foreach ((array) $needle as $n) { - $n = (string) $n; - $j = $this->indexOf($n, $offset); - - if (null !== $j && $j < $i) { - $i = $j; - $str->string = $n; - } - } - - if (\PHP_INT_MAX === $i) { - return $str; - } - - if ($includeNeedle) { - $i += $str->length(); - } - - return $this->slice(0, $i); - } - - /** - * @param string|string[] $needle - * - * @return static - */ - public function beforeLast($needle, bool $includeNeedle = false, int $offset = 0): self - { - $str = clone $this; - $i = null; - - foreach ((array) $needle as $n) { - $n = (string) $n; - $j = $this->indexOfLast($n, $offset); - - if (null !== $j && $j >= $i) { - $i = $offset = $j; - $str->string = $n; - } - } - - if (null === $i) { - return $str; - } - - if ($includeNeedle) { - $i += $str->length(); - } - - return $this->slice(0, $i); - } - - /** - * @return int[] - */ - public function bytesAt(int $offset): array - { - $str = $this->slice($offset, 1); - - return '' === $str->string ? [] : array_values(unpack('C*', $str->string)); - } - - /** - * @return static - */ - abstract public function camel(): self; - - /** - * @return static[] - */ - abstract public function chunk(int $length = 1): array; - - /** - * @return static - */ - public function collapseWhitespace(): self - { - $str = clone $this; - $str->string = trim(preg_replace('/(?:\s{2,}+|[^\S ])/', ' ', $str->string)); - - return $str; - } - - /** - * @param string|string[] $needle - */ - public function containsAny($needle): bool - { - return null !== $this->indexOf($needle); - } - - /** - * @param string|string[] $suffix - */ - public function endsWith($suffix): bool - { - if (!\is_array($suffix) && !$suffix instanceof \Traversable) { - throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); - } - - foreach ($suffix as $s) { - if ($this->endsWith((string) $s)) { - return true; - } - } - - return false; - } - - /** - * @return static - */ - public function ensureEnd(string $suffix): self - { - if (!$this->endsWith($suffix)) { - return $this->append($suffix); - } - - $suffix = preg_quote($suffix); - $regex = '{('.$suffix.')(?:'.$suffix.')++$}D'; - - return $this->replaceMatches($regex.($this->ignoreCase ? 'i' : ''), '$1'); - } - - /** - * @return static - */ - public function ensureStart(string $prefix): self - { - $prefix = new static($prefix); - - if (!$this->startsWith($prefix)) { - return $this->prepend($prefix); - } - - $str = clone $this; - $i = $prefixLen = $prefix->length(); - - while ($this->indexOf($prefix, $i) === $i) { - $str = $str->slice($prefixLen); - $i += $prefixLen; - } - - return $str; - } - - /** - * @param string|string[] $string - */ - public function equalsTo($string): bool - { - if (!\is_array($string) && !$string instanceof \Traversable) { - throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); - } - - foreach ($string as $s) { - if ($this->equalsTo((string) $s)) { - return true; - } - } - - return false; - } - - /** - * @return static - */ - abstract public function folded(): self; - - /** - * @return static - */ - public function ignoreCase(): self - { - $str = clone $this; - $str->ignoreCase = true; - - return $str; - } - - /** - * @param string|string[] $needle - */ - public function indexOf($needle, int $offset = 0): ?int - { - if (!\is_array($needle) && !$needle instanceof \Traversable) { - throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); - } - - $i = \PHP_INT_MAX; - - foreach ($needle as $n) { - $j = $this->indexOf((string) $n, $offset); - - if (null !== $j && $j < $i) { - $i = $j; - } - } - - return \PHP_INT_MAX === $i ? null : $i; - } - - /** - * @param string|string[] $needle - */ - public function indexOfLast($needle, int $offset = 0): ?int - { - if (!\is_array($needle) && !$needle instanceof \Traversable) { - throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); - } - - $i = null; - - foreach ($needle as $n) { - $j = $this->indexOfLast((string) $n, $offset); - - if (null !== $j && $j >= $i) { - $i = $offset = $j; - } - } - - return $i; - } - - public function isEmpty(): bool - { - return '' === $this->string; - } - - /** - * @return static - */ - abstract public function join(array $strings, string $lastGlue = null): self; - - public function jsonSerialize(): string - { - return $this->string; - } - - abstract public function length(): int; - - /** - * @return static - */ - abstract public function lower(): self; - - /** - * Matches the string using a regular expression. - * - * Pass PREG_PATTERN_ORDER or PREG_SET_ORDER as $flags to get all occurrences matching the regular expression. - * - * @return array All matches in a multi-dimensional array ordered according to flags - */ - abstract public function match(string $regexp, int $flags = 0, int $offset = 0): array; - - /** - * @return static - */ - abstract public function padBoth(int $length, string $padStr = ' '): self; - - /** - * @return static - */ - abstract public function padEnd(int $length, string $padStr = ' '): self; - - /** - * @return static - */ - abstract public function padStart(int $length, string $padStr = ' '): self; - - /** - * @return static - */ - abstract public function prepend(string ...$prefix): self; - - /** - * @return static - */ - public function repeat(int $multiplier): self - { - if (0 > $multiplier) { - throw new InvalidArgumentException(sprintf('Multiplier must be positive, %d given.', $multiplier)); - } - - $str = clone $this; - $str->string = str_repeat($str->string, $multiplier); - - return $str; - } - - /** - * @return static - */ - abstract public function replace(string $from, string $to): self; - - /** - * @param string|callable $to - * - * @return static - */ - abstract public function replaceMatches(string $fromRegexp, $to): self; - - /** - * @return static - */ - abstract public function reverse(): self; - - /** - * @return static - */ - abstract public function slice(int $start = 0, int $length = null): self; - - /** - * @return static - */ - abstract public function snake(): self; - - /** - * @return static - */ - abstract public function splice(string $replacement, int $start = 0, int $length = null): self; - - /** - * @return static[] - */ - public function split(string $delimiter, int $limit = null, int $flags = null): array - { - if (null === $flags) { - throw new \TypeError('Split behavior when $flags is null must be implemented by child classes.'); - } - - if ($this->ignoreCase) { - $delimiter .= 'i'; - } - - set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); }); - - try { - if (false === $chunks = preg_split($delimiter, $this->string, $limit, $flags)) { - $lastError = preg_last_error(); - - foreach (get_defined_constants(true)['pcre'] as $k => $v) { - if ($lastError === $v && '_ERROR' === substr($k, -6)) { - throw new RuntimeException('Splitting failed with '.$k.'.'); - } - } - - throw new RuntimeException('Splitting failed with unknown error code.'); - } - } finally { - restore_error_handler(); - } - - $str = clone $this; - - if (self::PREG_SPLIT_OFFSET_CAPTURE & $flags) { - foreach ($chunks as &$chunk) { - $str->string = $chunk[0]; - $chunk[0] = clone $str; - } - } else { - foreach ($chunks as &$chunk) { - $str->string = $chunk; - $chunk = clone $str; - } - } - - return $chunks; - } - - /** - * @param string|string[] $prefix - */ - public function startsWith($prefix): bool - { - if (!\is_array($prefix) && !$prefix instanceof \Traversable) { - throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); - } - - foreach ($prefix as $prefix) { - if ($this->startsWith((string) $prefix)) { - return true; - } - } - - return false; - } - - /** - * @return static - */ - abstract public function title(bool $allWords = false): self; - - public function toByteString(string $toEncoding = null): ByteString - { - $b = new ByteString(); - - $toEncoding = \in_array($toEncoding, ['utf8', 'utf-8', 'UTF8'], true) ? 'UTF-8' : $toEncoding; - - if (null === $toEncoding || $toEncoding === $fromEncoding = $this instanceof AbstractUnicodeString || preg_match('//u', $b->string) ? 'UTF-8' : 'Windows-1252') { - $b->string = $this->string; - - return $b; - } - - set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); }); - - try { - try { - $b->string = mb_convert_encoding($this->string, $toEncoding, 'UTF-8'); - } catch (InvalidArgumentException $e) { - if (!\function_exists('iconv')) { - throw $e; - } - - $b->string = iconv('UTF-8', $toEncoding, $this->string); - } - } finally { - restore_error_handler(); - } - - return $b; - } - - public function toCodePointString(): CodePointString - { - return new CodePointString($this->string); - } - - public function toString(): string - { - return $this->string; - } - - public function toUnicodeString(): UnicodeString - { - return new UnicodeString($this->string); - } - - /** - * @return static - */ - abstract public function trim(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): self; - - /** - * @return static - */ - abstract public function trimEnd(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): self; - - /** - * @param string|string[] $prefix - * - * @return static - */ - public function trimPrefix($prefix): self - { - if (\is_array($prefix) || $prefix instanceof \Traversable) { - foreach ($prefix as $s) { - $t = $this->trimPrefix($s); - - if ($t->string !== $this->string) { - return $t; - } - } - - return clone $this; - } - - $str = clone $this; - - if ($prefix instanceof self) { - $prefix = $prefix->string; - } else { - $prefix = (string) $prefix; - } - - if ('' !== $prefix && \strlen($this->string) >= \strlen($prefix) && 0 === substr_compare($this->string, $prefix, 0, \strlen($prefix), $this->ignoreCase)) { - $str->string = substr($this->string, \strlen($prefix)); - } - - return $str; - } - - /** - * @return static - */ - abstract public function trimStart(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): self; - - /** - * @param string|string[] $suffix - * - * @return static - */ - public function trimSuffix($suffix): self - { - if (\is_array($suffix) || $suffix instanceof \Traversable) { - foreach ($suffix as $s) { - $t = $this->trimSuffix($s); - - if ($t->string !== $this->string) { - return $t; - } - } - - return clone $this; - } - - $str = clone $this; - - if ($suffix instanceof self) { - $suffix = $suffix->string; - } else { - $suffix = (string) $suffix; - } - - if ('' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase)) { - $str->string = substr($this->string, 0, -\strlen($suffix)); - } - - return $str; - } - - /** - * @return static - */ - public function truncate(int $length, string $ellipsis = '', bool $cut = true): self - { - $stringLength = $this->length(); - - if ($stringLength <= $length) { - return clone $this; - } - - $ellipsisLength = '' !== $ellipsis ? (new static($ellipsis))->length() : 0; - - if ($length < $ellipsisLength) { - $ellipsisLength = 0; - } - - if (!$cut) { - if (null === $length = $this->indexOf([' ', "\r", "\n", "\t"], ($length ?: 1) - 1)) { - return clone $this; - } - - $length += $ellipsisLength; - } - - $str = $this->slice(0, $length - $ellipsisLength); - - return $ellipsisLength ? $str->trimEnd()->append($ellipsis) : $str; - } - - /** - * @return static - */ - abstract public function upper(): self; - - /** - * Returns the printable length on a terminal. - */ - abstract public function width(bool $ignoreAnsiDecoration = true): int; - - /** - * @return static - */ - public function wordwrap(int $width = 75, string $break = "\n", bool $cut = false): self - { - $lines = '' !== $break ? $this->split($break) : [clone $this]; - $chars = []; - $mask = ''; - - if (1 === \count($lines) && '' === $lines[0]->string) { - return $lines[0]; - } - - foreach ($lines as $i => $line) { - if ($i) { - $chars[] = $break; - $mask .= '#'; - } - - foreach ($line->chunk() as $char) { - $chars[] = $char->string; - $mask .= ' ' === $char->string ? ' ' : '?'; - } - } - - $string = ''; - $j = 0; - $b = $i = -1; - $mask = wordwrap($mask, $width, '#', $cut); - - while (false !== $b = strpos($mask, '#', $b + 1)) { - for (++$i; $i < $b; ++$i) { - $string .= $chars[$j]; - unset($chars[$j++]); - } - - if ($break === $chars[$j] || ' ' === $chars[$j]) { - unset($chars[$j++]); - } - - $string .= $break; - } - - $str = clone $this; - $str->string = $string.implode('', $chars); - - return $str; - } - - public function __sleep(): array - { - return ['string']; - } - - public function __clone() - { - $this->ignoreCase = false; - } - - public function __toString(): string - { - return $this->string; - } -} diff --git a/vendor/symfony/string/AbstractUnicodeString.php b/vendor/symfony/string/AbstractUnicodeString.php deleted file mode 100644 index db810cb6d..000000000 --- a/vendor/symfony/string/AbstractUnicodeString.php +++ /dev/null @@ -1,620 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String; - -use Symfony\Component\String\Exception\ExceptionInterface; -use Symfony\Component\String\Exception\InvalidArgumentException; -use Symfony\Component\String\Exception\RuntimeException; - -/** - * Represents a string of abstract Unicode characters. - * - * Unicode defines 3 types of "characters" (bytes, code points and grapheme clusters). - * This class is the abstract type to use as a type-hint when the logic you want to - * implement is Unicode-aware but doesn't care about code points vs grapheme clusters. - * - * @author Nicolas Grekas - * - * @throws ExceptionInterface - */ -abstract class AbstractUnicodeString extends AbstractString -{ - public const NFC = \Normalizer::NFC; - public const NFD = \Normalizer::NFD; - public const NFKC = \Normalizer::NFKC; - public const NFKD = \Normalizer::NFKD; - - // all ASCII letters sorted by typical frequency of occurrence - private const ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"; - - // the subset of folded case mappings that is not in lower case mappings - private const FOLD_FROM = ['İ', 'µ', 'ſ', "\xCD\x85", 'ς', 'ϐ', 'ϑ', 'ϕ', 'ϖ', 'ϰ', 'ϱ', 'ϵ', 'ẛ', "\xE1\xBE\xBE", 'ß', 'İ', 'ʼn', 'ǰ', 'ΐ', 'ΰ', 'և', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'ẚ', 'ẞ', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'ᾐ', 'ᾑ', 'ᾒ', 'ᾓ', 'ᾔ', 'ᾕ', 'ᾖ', 'ᾗ', 'ᾘ', 'ᾙ', 'ᾚ', 'ᾛ', 'ᾜ', 'ᾝ', 'ᾞ', 'ᾟ', 'ᾠ', 'ᾡ', 'ᾢ', 'ᾣ', 'ᾤ', 'ᾥ', 'ᾦ', 'ᾧ', 'ᾨ', 'ᾩ', 'ᾪ', 'ᾫ', 'ᾬ', 'ᾭ', 'ᾮ', 'ᾯ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'ᾼ', 'ῂ', 'ῃ', 'ῄ', 'ῆ', 'ῇ', 'ῌ', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'ῢ', 'ΰ', 'ῤ', 'ῦ', 'ῧ', 'ῲ', 'ῳ', 'ῴ', 'ῶ', 'ῷ', 'ῼ', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'ſt', 'st', 'ﬓ', 'ﬔ', 'ﬕ', 'ﬖ', 'ﬗ']; - private const FOLD_TO = ['i̇', 'μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', 'ṡ', 'ι', 'ss', 'i̇', 'ʼn', 'ǰ', 'ΐ', 'ΰ', 'եւ', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'aʾ', 'ss', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ἀι', 'ἁι', 'ἂι', 'ἃι', 'ἄι', 'ἅι', 'ἆι', 'ἇι', 'ἀι', 'ἁι', 'ἂι', 'ἃι', 'ἄι', 'ἅι', 'ἆι', 'ἇι', 'ἠι', 'ἡι', 'ἢι', 'ἣι', 'ἤι', 'ἥι', 'ἦι', 'ἧι', 'ἠι', 'ἡι', 'ἢι', 'ἣι', 'ἤι', 'ἥι', 'ἦι', 'ἧι', 'ὠι', 'ὡι', 'ὢι', 'ὣι', 'ὤι', 'ὥι', 'ὦι', 'ὧι', 'ὠι', 'ὡι', 'ὢι', 'ὣι', 'ὤι', 'ὥι', 'ὦι', 'ὧι', 'ὰι', 'αι', 'άι', 'ᾶ', 'ᾶι', 'αι', 'ὴι', 'ηι', 'ήι', 'ῆ', 'ῆι', 'ηι', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'ῢ', 'ΰ', 'ῤ', 'ῦ', 'ῧ', 'ὼι', 'ωι', 'ώι', 'ῶ', 'ῶι', 'ωι', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'st', 'st', 'մն', 'մե', 'մի', 'վն', 'մխ']; - - // the subset of upper case mappings that map one code point to many code points - private const UPPER_FROM = ['ß', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'ſt', 'st', 'և', 'ﬓ', 'ﬔ', 'ﬕ', 'ﬖ', 'ﬗ', 'ʼn', 'ΐ', 'ΰ', 'ǰ', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'ẚ', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ᾶ', 'ῆ', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'ῢ', 'ΰ', 'ῤ', 'ῦ', 'ῧ', 'ῶ']; - private const UPPER_TO = ['SS', 'FF', 'FI', 'FL', 'FFI', 'FFL', 'ST', 'ST', 'ԵՒ', 'ՄՆ', 'ՄԵ', 'ՄԻ', 'ՎՆ', 'ՄԽ', 'ʼN', 'Ϊ́', 'Ϋ́', 'J̌', 'H̱', 'T̈', 'W̊', 'Y̊', 'Aʾ', 'Υ̓', 'Υ̓̀', 'Υ̓́', 'Υ̓͂', 'Α͂', 'Η͂', 'Ϊ̀', 'Ϊ́', 'Ι͂', 'Ϊ͂', 'Ϋ̀', 'Ϋ́', 'Ρ̓', 'Υ͂', 'Ϋ͂', 'Ω͂']; - - // the subset of https://github.com/unicode-org/cldr/blob/master/common/transforms/Latin-ASCII.xml that is not in NFKD - private const TRANSLIT_FROM = ['Æ', 'Ð', 'Ø', 'Þ', 'ß', 'æ', 'ð', 'ø', 'þ', 'Đ', 'đ', 'Ħ', 'ħ', 'ı', 'ĸ', 'Ŀ', 'ŀ', 'Ł', 'ł', 'ʼn', 'Ŋ', 'ŋ', 'Œ', 'œ', 'Ŧ', 'ŧ', 'ƀ', 'Ɓ', 'Ƃ', 'ƃ', 'Ƈ', 'ƈ', 'Ɖ', 'Ɗ', 'Ƌ', 'ƌ', 'Ɛ', 'Ƒ', 'ƒ', 'Ɠ', 'ƕ', 'Ɩ', 'Ɨ', 'Ƙ', 'ƙ', 'ƚ', 'Ɲ', 'ƞ', 'Ƣ', 'ƣ', 'Ƥ', 'ƥ', 'ƫ', 'Ƭ', 'ƭ', 'Ʈ', 'Ʋ', 'Ƴ', 'ƴ', 'Ƶ', 'ƶ', 'DŽ', 'Dž', 'dž', 'Ǥ', 'ǥ', 'ȡ', 'Ȥ', 'ȥ', 'ȴ', 'ȵ', 'ȶ', 'ȷ', 'ȸ', 'ȹ', 'Ⱥ', 'Ȼ', 'ȼ', 'Ƚ', 'Ⱦ', 'ȿ', 'ɀ', 'Ƀ', 'Ʉ', 'Ɇ', 'ɇ', 'Ɉ', 'ɉ', 'Ɍ', 'ɍ', 'Ɏ', 'ɏ', 'ɓ', 'ɕ', 'ɖ', 'ɗ', 'ɛ', 'ɟ', 'ɠ', 'ɡ', 'ɢ', 'ɦ', 'ɧ', 'ɨ', 'ɪ', 'ɫ', 'ɬ', 'ɭ', 'ɱ', 'ɲ', 'ɳ', 'ɴ', 'ɶ', 'ɼ', 'ɽ', 'ɾ', 'ʀ', 'ʂ', 'ʈ', 'ʉ', 'ʋ', 'ʏ', 'ʐ', 'ʑ', 'ʙ', 'ʛ', 'ʜ', 'ʝ', 'ʟ', 'ʠ', 'ʣ', 'ʥ', 'ʦ', 'ʪ', 'ʫ', 'ᴀ', 'ᴁ', 'ᴃ', 'ᴄ', 'ᴅ', 'ᴆ', 'ᴇ', 'ᴊ', 'ᴋ', 'ᴌ', 'ᴍ', 'ᴏ', 'ᴘ', 'ᴛ', 'ᴜ', 'ᴠ', 'ᴡ', 'ᴢ', 'ᵫ', 'ᵬ', 'ᵭ', 'ᵮ', 'ᵯ', 'ᵰ', 'ᵱ', 'ᵲ', 'ᵳ', 'ᵴ', 'ᵵ', 'ᵶ', 'ᵺ', 'ᵻ', 'ᵽ', 'ᵾ', 'ᶀ', 'ᶁ', 'ᶂ', 'ᶃ', 'ᶄ', 'ᶅ', 'ᶆ', 'ᶇ', 'ᶈ', 'ᶉ', 'ᶊ', 'ᶌ', 'ᶍ', 'ᶎ', 'ᶏ', 'ᶑ', 'ᶒ', 'ᶓ', 'ᶖ', 'ᶙ', 'ẚ', 'ẜ', 'ẝ', 'ẞ', 'Ỻ', 'ỻ', 'Ỽ', 'ỽ', 'Ỿ', 'ỿ', '©', '®', '₠', '₢', '₣', '₤', '₧', '₺', '₹', 'ℌ', '℞', '㎧', '㎮', '㏆', '㏗', '㏞', '㏟', '¼', '½', '¾', '⅓', '⅔', '⅕', '⅖', '⅗', '⅘', '⅙', '⅚', '⅛', '⅜', '⅝', '⅞', '⅟', '〇', '‘', '’', '‚', '‛', '“', '”', '„', '‟', '′', '″', '〝', '〞', '«', '»', '‹', '›', '‐', '‑', '‒', '–', '—', '―', '︱', '︲', '﹘', '‖', '⁄', '⁅', '⁆', '⁎', '、', '。', '〈', '〉', '《', '》', '〔', '〕', '〘', '〙', '〚', '〛', '︑', '︒', '︹', '︺', '︽', '︾', '︿', '﹀', '﹑', '﹝', '﹞', '⦅', '⦆', '。', '、', '×', '÷', '−', '∕', '∖', '∣', '∥', '≪', '≫', '⦅', '⦆']; - private const TRANSLIT_TO = ['AE', 'D', 'O', 'TH', 'ss', 'ae', 'd', 'o', 'th', 'D', 'd', 'H', 'h', 'i', 'q', 'L', 'l', 'L', 'l', '\'n', 'N', 'n', 'OE', 'oe', 'T', 't', 'b', 'B', 'B', 'b', 'C', 'c', 'D', 'D', 'D', 'd', 'E', 'F', 'f', 'G', 'hv', 'I', 'I', 'K', 'k', 'l', 'N', 'n', 'OI', 'oi', 'P', 'p', 't', 'T', 't', 'T', 'V', 'Y', 'y', 'Z', 'z', 'DZ', 'Dz', 'dz', 'G', 'g', 'd', 'Z', 'z', 'l', 'n', 't', 'j', 'db', 'qp', 'A', 'C', 'c', 'L', 'T', 's', 'z', 'B', 'U', 'E', 'e', 'J', 'j', 'R', 'r', 'Y', 'y', 'b', 'c', 'd', 'd', 'e', 'j', 'g', 'g', 'G', 'h', 'h', 'i', 'I', 'l', 'l', 'l', 'm', 'n', 'n', 'N', 'OE', 'r', 'r', 'r', 'R', 's', 't', 'u', 'v', 'Y', 'z', 'z', 'B', 'G', 'H', 'j', 'L', 'q', 'dz', 'dz', 'ts', 'ls', 'lz', 'A', 'AE', 'B', 'C', 'D', 'D', 'E', 'J', 'K', 'L', 'M', 'O', 'P', 'T', 'U', 'V', 'W', 'Z', 'ue', 'b', 'd', 'f', 'm', 'n', 'p', 'r', 'r', 's', 't', 'z', 'th', 'I', 'p', 'U', 'b', 'd', 'f', 'g', 'k', 'l', 'm', 'n', 'p', 'r', 's', 'v', 'x', 'z', 'a', 'd', 'e', 'e', 'i', 'u', 'a', 's', 's', 'SS', 'LL', 'll', 'V', 'v', 'Y', 'y', '(C)', '(R)', 'CE', 'Cr', 'Fr.', 'L.', 'Pts', 'TL', 'Rs', 'x', 'Rx', 'm/s', 'rad/s', 'C/kg', 'pH', 'V/m', 'A/m', ' 1/4', ' 1/2', ' 3/4', ' 1/3', ' 2/3', ' 1/5', ' 2/5', ' 3/5', ' 4/5', ' 1/6', ' 5/6', ' 1/8', ' 3/8', ' 5/8', ' 7/8', ' 1/', '0', '\'', '\'', ',', '\'', '"', '"', ',,', '"', '\'', '"', '"', '"', '<<', '>>', '<', '>', '-', '-', '-', '-', '-', '-', '-', '-', '-', '||', '/', '[', ']', '*', ',', '.', '<', '>', '<<', '>>', '[', ']', '[', ']', '[', ']', ',', '.', '[', ']', '<<', '>>', '<', '>', ',', '[', ']', '((', '))', '.', ',', '*', '/', '-', '/', '\\', '|', '||', '<<', '>>', '((', '))']; - - private static $transliterators = []; - private static $tableZero; - private static $tableWide; - - /** - * @return static - */ - public static function fromCodePoints(int ...$codes): self - { - $string = ''; - - foreach ($codes as $code) { - if (0x80 > $code %= 0x200000) { - $string .= \chr($code); - } elseif (0x800 > $code) { - $string .= \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F); - } elseif (0x10000 > $code) { - $string .= \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); - } else { - $string .= \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); - } - } - - return new static($string); - } - - /** - * Generic UTF-8 to ASCII transliteration. - * - * Install the intl extension for best results. - * - * @param string[]|\Transliterator[]|\Closure[] $rules See "*-Latin" rules from Transliterator::listIDs() - */ - public function ascii(array $rules = []): self - { - $str = clone $this; - $s = $str->string; - $str->string = ''; - - array_unshift($rules, 'nfd'); - $rules[] = 'latin-ascii'; - - if (\function_exists('transliterator_transliterate')) { - $rules[] = 'any-latin/bgn'; - } - - $rules[] = 'nfkd'; - $rules[] = '[:nonspacing mark:] remove'; - - while (\strlen($s) - 1 > $i = strspn($s, self::ASCII)) { - if (0 < --$i) { - $str->string .= substr($s, 0, $i); - $s = substr($s, $i); - } - - if (!$rule = array_shift($rules)) { - $rules = []; // An empty rule interrupts the next ones - } - - if ($rule instanceof \Transliterator) { - $s = $rule->transliterate($s); - } elseif ($rule instanceof \Closure) { - $s = $rule($s); - } elseif ($rule) { - if ('nfd' === $rule = strtolower($rule)) { - normalizer_is_normalized($s, self::NFD) ?: $s = normalizer_normalize($s, self::NFD); - } elseif ('nfkd' === $rule) { - normalizer_is_normalized($s, self::NFKD) ?: $s = normalizer_normalize($s, self::NFKD); - } elseif ('[:nonspacing mark:] remove' === $rule) { - $s = preg_replace('/\p{Mn}++/u', '', $s); - } elseif ('latin-ascii' === $rule) { - $s = str_replace(self::TRANSLIT_FROM, self::TRANSLIT_TO, $s); - } elseif ('de-ascii' === $rule) { - $s = preg_replace("/([AUO])\u{0308}(?=\p{Ll})/u", '$1e', $s); - $s = str_replace(["a\u{0308}", "o\u{0308}", "u\u{0308}", "A\u{0308}", "O\u{0308}", "U\u{0308}"], ['ae', 'oe', 'ue', 'AE', 'OE', 'UE'], $s); - } elseif (\function_exists('transliterator_transliterate')) { - if (null === $transliterator = self::$transliterators[$rule] ?? self::$transliterators[$rule] = \Transliterator::create($rule)) { - if ('any-latin/bgn' === $rule) { - $rule = 'any-latin'; - $transliterator = self::$transliterators[$rule] ?? self::$transliterators[$rule] = \Transliterator::create($rule); - } - - if (null === $transliterator) { - throw new InvalidArgumentException(sprintf('Unknown transliteration rule "%s".', $rule)); - } - - self::$transliterators['any-latin/bgn'] = $transliterator; - } - - $s = $transliterator->transliterate($s); - } - } elseif (!\function_exists('iconv')) { - $s = preg_replace('/[^\x00-\x7F]/u', '?', $s); - } else { - $s = @preg_replace_callback('/[^\x00-\x7F]/u', static function ($c) { - $c = (string) iconv('UTF-8', 'ASCII//TRANSLIT', $c[0]); - - if ('' === $c && '' === iconv('UTF-8', 'ASCII//TRANSLIT', '²')) { - throw new \LogicException(sprintf('"%s" requires a translit-able iconv implementation, try installing "gnu-libiconv" if you\'re using Alpine Linux.', static::class)); - } - - return 1 < \strlen($c) ? ltrim($c, '\'`"^~') : ('' !== $c ? $c : '?'); - }, $s); - } - } - - $str->string .= $s; - - return $str; - } - - public function camel(): parent - { - $str = clone $this; - $str->string = str_replace(' ', '', preg_replace_callback('/\b./u', static function ($m) use (&$i) { - return 1 === ++$i ? ('İ' === $m[0] ? 'i̇' : mb_strtolower($m[0], 'UTF-8')) : mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8'); - }, preg_replace('/[^\pL0-9]++/u', ' ', $this->string))); - - return $str; - } - - /** - * @return int[] - */ - public function codePointsAt(int $offset): array - { - $str = $this->slice($offset, 1); - - if ('' === $str->string) { - return []; - } - - $codePoints = []; - - foreach (preg_split('//u', $str->string, -1, \PREG_SPLIT_NO_EMPTY) as $c) { - $codePoints[] = mb_ord($c, 'UTF-8'); - } - - return $codePoints; - } - - public function folded(bool $compat = true): parent - { - $str = clone $this; - - if (!$compat || \PHP_VERSION_ID < 70300 || !\defined('Normalizer::NFKC_CF')) { - $str->string = normalizer_normalize($str->string, $compat ? \Normalizer::NFKC : \Normalizer::NFC); - $str->string = mb_strtolower(str_replace(self::FOLD_FROM, self::FOLD_TO, $this->string), 'UTF-8'); - } else { - $str->string = normalizer_normalize($str->string, \Normalizer::NFKC_CF); - } - - return $str; - } - - public function join(array $strings, string $lastGlue = null): parent - { - $str = clone $this; - - $tail = null !== $lastGlue && 1 < \count($strings) ? $lastGlue.array_pop($strings) : ''; - $str->string = implode($this->string, $strings).$tail; - - if (!preg_match('//u', $str->string)) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - - return $str; - } - - public function lower(): parent - { - $str = clone $this; - $str->string = mb_strtolower(str_replace('İ', 'i̇', $str->string), 'UTF-8'); - - return $str; - } - - public function match(string $regexp, int $flags = 0, int $offset = 0): array - { - $match = ((\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags) ? 'preg_match_all' : 'preg_match'; - - if ($this->ignoreCase) { - $regexp .= 'i'; - } - - set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); }); - - try { - if (false === $match($regexp.'u', $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) { - $lastError = preg_last_error(); - - foreach (get_defined_constants(true)['pcre'] as $k => $v) { - if ($lastError === $v && '_ERROR' === substr($k, -6)) { - throw new RuntimeException('Matching failed with '.$k.'.'); - } - } - - throw new RuntimeException('Matching failed with unknown error code.'); - } - } finally { - restore_error_handler(); - } - - return $matches; - } - - /** - * @return static - */ - public function normalize(int $form = self::NFC): self - { - if (!\in_array($form, [self::NFC, self::NFD, self::NFKC, self::NFKD])) { - throw new InvalidArgumentException('Unsupported normalization form.'); - } - - $str = clone $this; - normalizer_is_normalized($str->string, $form) ?: $str->string = normalizer_normalize($str->string, $form); - - return $str; - } - - public function padBoth(int $length, string $padStr = ' '): parent - { - if ('' === $padStr || !preg_match('//u', $padStr)) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - - $pad = clone $this; - $pad->string = $padStr; - - return $this->pad($length, $pad, \STR_PAD_BOTH); - } - - public function padEnd(int $length, string $padStr = ' '): parent - { - if ('' === $padStr || !preg_match('//u', $padStr)) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - - $pad = clone $this; - $pad->string = $padStr; - - return $this->pad($length, $pad, \STR_PAD_RIGHT); - } - - public function padStart(int $length, string $padStr = ' '): parent - { - if ('' === $padStr || !preg_match('//u', $padStr)) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - - $pad = clone $this; - $pad->string = $padStr; - - return $this->pad($length, $pad, \STR_PAD_LEFT); - } - - public function replaceMatches(string $fromRegexp, $to): parent - { - if ($this->ignoreCase) { - $fromRegexp .= 'i'; - } - - if (\is_array($to) || $to instanceof \Closure) { - if (!\is_callable($to)) { - throw new \TypeError(sprintf('Argument 2 passed to "%s::replaceMatches()" must be callable, array given.', static::class)); - } - - $replace = 'preg_replace_callback'; - $to = static function (array $m) use ($to): string { - $to = $to($m); - - if ('' !== $to && (!\is_string($to) || !preg_match('//u', $to))) { - throw new InvalidArgumentException('Replace callback must return a valid UTF-8 string.'); - } - - return $to; - }; - } elseif ('' !== $to && !preg_match('//u', $to)) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } else { - $replace = 'preg_replace'; - } - - set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); }); - - try { - if (null === $string = $replace($fromRegexp.'u', $to, $this->string)) { - $lastError = preg_last_error(); - - foreach (get_defined_constants(true)['pcre'] as $k => $v) { - if ($lastError === $v && '_ERROR' === substr($k, -6)) { - throw new RuntimeException('Matching failed with '.$k.'.'); - } - } - - throw new RuntimeException('Matching failed with unknown error code.'); - } - } finally { - restore_error_handler(); - } - - $str = clone $this; - $str->string = $string; - - return $str; - } - - public function reverse(): parent - { - $str = clone $this; - $str->string = implode('', array_reverse(preg_split('/(\X)/u', $str->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY))); - - return $str; - } - - public function snake(): parent - { - $str = $this->camel()->title(); - $str->string = mb_strtolower(preg_replace(['/(\p{Lu}+)(\p{Lu}\p{Ll})/u', '/([\p{Ll}0-9])(\p{Lu})/u'], '\1_\2', $str->string), 'UTF-8'); - - return $str; - } - - public function title(bool $allWords = false): parent - { - $str = clone $this; - - $limit = $allWords ? -1 : 1; - - $str->string = preg_replace_callback('/\b./u', static function (array $m): string { - return mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8'); - }, $str->string, $limit); - - return $str; - } - - public function trim(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): parent - { - if (" \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}" !== $chars && !preg_match('//u', $chars)) { - throw new InvalidArgumentException('Invalid UTF-8 chars.'); - } - $chars = preg_quote($chars); - - $str = clone $this; - $str->string = preg_replace("{^[$chars]++|[$chars]++$}uD", '', $str->string); - - return $str; - } - - public function trimEnd(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): parent - { - if (" \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}" !== $chars && !preg_match('//u', $chars)) { - throw new InvalidArgumentException('Invalid UTF-8 chars.'); - } - $chars = preg_quote($chars); - - $str = clone $this; - $str->string = preg_replace("{[$chars]++$}uD", '', $str->string); - - return $str; - } - - public function trimPrefix($prefix): parent - { - if (!$this->ignoreCase) { - return parent::trimPrefix($prefix); - } - - $str = clone $this; - - if ($prefix instanceof \Traversable) { - $prefix = iterator_to_array($prefix, false); - } elseif ($prefix instanceof parent) { - $prefix = $prefix->string; - } - - $prefix = implode('|', array_map('preg_quote', (array) $prefix)); - $str->string = preg_replace("{^(?:$prefix)}iuD", '', $this->string); - - return $str; - } - - public function trimStart(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): parent - { - if (" \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}" !== $chars && !preg_match('//u', $chars)) { - throw new InvalidArgumentException('Invalid UTF-8 chars.'); - } - $chars = preg_quote($chars); - - $str = clone $this; - $str->string = preg_replace("{^[$chars]++}uD", '', $str->string); - - return $str; - } - - public function trimSuffix($suffix): parent - { - if (!$this->ignoreCase) { - return parent::trimSuffix($suffix); - } - - $str = clone $this; - - if ($suffix instanceof \Traversable) { - $suffix = iterator_to_array($suffix, false); - } elseif ($suffix instanceof parent) { - $suffix = $suffix->string; - } - - $suffix = implode('|', array_map('preg_quote', (array) $suffix)); - $str->string = preg_replace("{(?:$suffix)$}iuD", '', $this->string); - - return $str; - } - - public function upper(): parent - { - $str = clone $this; - $str->string = mb_strtoupper($str->string, 'UTF-8'); - - if (\PHP_VERSION_ID < 70300) { - $str->string = str_replace(self::UPPER_FROM, self::UPPER_TO, $str->string); - } - - return $str; - } - - public function width(bool $ignoreAnsiDecoration = true): int - { - $width = 0; - $s = str_replace(["\x00", "\x05", "\x07"], '', $this->string); - - if (false !== strpos($s, "\r")) { - $s = str_replace(["\r\n", "\r"], "\n", $s); - } - - if (!$ignoreAnsiDecoration) { - $s = preg_replace('/[\p{Cc}\x7F]++/u', '', $s); - } - - foreach (explode("\n", $s) as $s) { - if ($ignoreAnsiDecoration) { - $s = preg_replace('/(?:\x1B(?: - \[ [\x30-\x3F]*+ [\x20-\x2F]*+ [0x40-\x7E] - | [P\]X^_] .*? \x1B\\\\ - | [\x41-\x7E] - )|[\p{Cc}\x7F]++)/xu', '', $s); - } - - // Non printable characters have been dropped, so wcswidth cannot logically return -1. - $width += $this->wcswidth($s); - } - - return $width; - } - - /** - * @return static - */ - private function pad(int $len, self $pad, int $type): parent - { - $sLen = $this->length(); - - if ($len <= $sLen) { - return clone $this; - } - - $padLen = $pad->length(); - $freeLen = $len - $sLen; - $len = $freeLen % $padLen; - - switch ($type) { - case \STR_PAD_RIGHT: - return $this->append(str_repeat($pad->string, intdiv($freeLen, $padLen)).($len ? $pad->slice(0, $len) : '')); - - case \STR_PAD_LEFT: - return $this->prepend(str_repeat($pad->string, intdiv($freeLen, $padLen)).($len ? $pad->slice(0, $len) : '')); - - case \STR_PAD_BOTH: - $freeLen /= 2; - - $rightLen = ceil($freeLen); - $len = $rightLen % $padLen; - $str = $this->append(str_repeat($pad->string, intdiv($rightLen, $padLen)).($len ? $pad->slice(0, $len) : '')); - - $leftLen = floor($freeLen); - $len = $leftLen % $padLen; - - return $str->prepend(str_repeat($pad->string, intdiv($leftLen, $padLen)).($len ? $pad->slice(0, $len) : '')); - - default: - throw new InvalidArgumentException('Invalid padding type.'); - } - } - - /** - * Based on https://github.com/jquast/wcwidth, a Python implementation of https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c. - */ - private function wcswidth(string $string): int - { - $width = 0; - - foreach (preg_split('//u', $string, -1, \PREG_SPLIT_NO_EMPTY) as $c) { - $codePoint = mb_ord($c, 'UTF-8'); - - if (0 === $codePoint // NULL - || 0x034F === $codePoint // COMBINING GRAPHEME JOINER - || (0x200B <= $codePoint && 0x200F >= $codePoint) // ZERO WIDTH SPACE to RIGHT-TO-LEFT MARK - || 0x2028 === $codePoint // LINE SEPARATOR - || 0x2029 === $codePoint // PARAGRAPH SEPARATOR - || (0x202A <= $codePoint && 0x202E >= $codePoint) // LEFT-TO-RIGHT EMBEDDING to RIGHT-TO-LEFT OVERRIDE - || (0x2060 <= $codePoint && 0x2063 >= $codePoint) // WORD JOINER to INVISIBLE SEPARATOR - ) { - continue; - } - - // Non printable characters - if (32 > $codePoint // C0 control characters - || (0x07F <= $codePoint && 0x0A0 > $codePoint) // C1 control characters and DEL - ) { - return -1; - } - - if (null === self::$tableZero) { - self::$tableZero = require __DIR__.'/Resources/data/wcswidth_table_zero.php'; - } - - if ($codePoint >= self::$tableZero[0][0] && $codePoint <= self::$tableZero[$ubound = \count(self::$tableZero) - 1][1]) { - $lbound = 0; - while ($ubound >= $lbound) { - $mid = floor(($lbound + $ubound) / 2); - - if ($codePoint > self::$tableZero[$mid][1]) { - $lbound = $mid + 1; - } elseif ($codePoint < self::$tableZero[$mid][0]) { - $ubound = $mid - 1; - } else { - continue 2; - } - } - } - - if (null === self::$tableWide) { - self::$tableWide = require __DIR__.'/Resources/data/wcswidth_table_wide.php'; - } - - if ($codePoint >= self::$tableWide[0][0] && $codePoint <= self::$tableWide[$ubound = \count(self::$tableWide) - 1][1]) { - $lbound = 0; - while ($ubound >= $lbound) { - $mid = floor(($lbound + $ubound) / 2); - - if ($codePoint > self::$tableWide[$mid][1]) { - $lbound = $mid + 1; - } elseif ($codePoint < self::$tableWide[$mid][0]) { - $ubound = $mid - 1; - } else { - $width += 2; - - continue 2; - } - } - } - - ++$width; - } - - return $width; - } -} diff --git a/vendor/symfony/string/ByteString.php b/vendor/symfony/string/ByteString.php deleted file mode 100644 index bbf8614cf..000000000 --- a/vendor/symfony/string/ByteString.php +++ /dev/null @@ -1,506 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String; - -use Symfony\Component\String\Exception\ExceptionInterface; -use Symfony\Component\String\Exception\InvalidArgumentException; -use Symfony\Component\String\Exception\RuntimeException; - -/** - * Represents a binary-safe string of bytes. - * - * @author Nicolas Grekas - * @author Hugo Hamon - * - * @throws ExceptionInterface - */ -class ByteString extends AbstractString -{ - private const ALPHABET_ALPHANUMERIC = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; - - public function __construct(string $string = '') - { - $this->string = $string; - } - - /* - * The following method was derived from code of the Hack Standard Library (v4.40 - 2020-05-03) - * - * https://github.com/hhvm/hsl/blob/80a42c02f036f72a42f0415e80d6b847f4bf62d5/src/random/private.php#L16 - * - * Code subject to the MIT license (https://github.com/hhvm/hsl/blob/master/LICENSE). - * - * Copyright (c) 2004-2020, Facebook, Inc. (https://www.facebook.com/) - */ - - public static function fromRandom(int $length = 16, string $alphabet = null): self - { - if ($length <= 0) { - throw new InvalidArgumentException(sprintf('A strictly positive length is expected, "%d" given.', $length)); - } - - $alphabet = $alphabet ?? self::ALPHABET_ALPHANUMERIC; - $alphabetSize = \strlen($alphabet); - $bits = (int) ceil(log($alphabetSize, 2.0)); - if ($bits <= 0 || $bits > 56) { - throw new InvalidArgumentException('The length of the alphabet must in the [2^1, 2^56] range.'); - } - - $ret = ''; - while ($length > 0) { - $urandomLength = (int) ceil(2 * $length * $bits / 8.0); - $data = random_bytes($urandomLength); - $unpackedData = 0; - $unpackedBits = 0; - for ($i = 0; $i < $urandomLength && $length > 0; ++$i) { - // Unpack 8 bits - $unpackedData = ($unpackedData << 8) | \ord($data[$i]); - $unpackedBits += 8; - - // While we have enough bits to select a character from the alphabet, keep - // consuming the random data - for (; $unpackedBits >= $bits && $length > 0; $unpackedBits -= $bits) { - $index = ($unpackedData & ((1 << $bits) - 1)); - $unpackedData >>= $bits; - // Unfortunately, the alphabet size is not necessarily a power of two. - // Worst case, it is 2^k + 1, which means we need (k+1) bits and we - // have around a 50% chance of missing as k gets larger - if ($index < $alphabetSize) { - $ret .= $alphabet[$index]; - --$length; - } - } - } - } - - return new static($ret); - } - - public function bytesAt(int $offset): array - { - $str = $this->string[$offset] ?? ''; - - return '' === $str ? [] : [\ord($str)]; - } - - public function append(string ...$suffix): parent - { - $str = clone $this; - $str->string .= 1 >= \count($suffix) ? ($suffix[0] ?? '') : implode('', $suffix); - - return $str; - } - - public function camel(): parent - { - $str = clone $this; - $str->string = lcfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $this->string)))); - - return $str; - } - - public function chunk(int $length = 1): array - { - if (1 > $length) { - throw new InvalidArgumentException('The chunk length must be greater than zero.'); - } - - if ('' === $this->string) { - return []; - } - - $str = clone $this; - $chunks = []; - - foreach (str_split($this->string, $length) as $chunk) { - $str->string = $chunk; - $chunks[] = clone $str; - } - - return $chunks; - } - - public function endsWith($suffix): bool - { - if ($suffix instanceof parent) { - $suffix = $suffix->string; - } elseif (\is_array($suffix) || $suffix instanceof \Traversable) { - return parent::endsWith($suffix); - } else { - $suffix = (string) $suffix; - } - - return '' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase); - } - - public function equalsTo($string): bool - { - if ($string instanceof parent) { - $string = $string->string; - } elseif (\is_array($string) || $string instanceof \Traversable) { - return parent::equalsTo($string); - } else { - $string = (string) $string; - } - - if ('' !== $string && $this->ignoreCase) { - return 0 === strcasecmp($string, $this->string); - } - - return $string === $this->string; - } - - public function folded(): parent - { - $str = clone $this; - $str->string = strtolower($str->string); - - return $str; - } - - public function indexOf($needle, int $offset = 0): ?int - { - if ($needle instanceof parent) { - $needle = $needle->string; - } elseif (\is_array($needle) || $needle instanceof \Traversable) { - return parent::indexOf($needle, $offset); - } else { - $needle = (string) $needle; - } - - if ('' === $needle) { - return null; - } - - $i = $this->ignoreCase ? stripos($this->string, $needle, $offset) : strpos($this->string, $needle, $offset); - - return false === $i ? null : $i; - } - - public function indexOfLast($needle, int $offset = 0): ?int - { - if ($needle instanceof parent) { - $needle = $needle->string; - } elseif (\is_array($needle) || $needle instanceof \Traversable) { - return parent::indexOfLast($needle, $offset); - } else { - $needle = (string) $needle; - } - - if ('' === $needle) { - return null; - } - - $i = $this->ignoreCase ? strripos($this->string, $needle, $offset) : strrpos($this->string, $needle, $offset); - - return false === $i ? null : $i; - } - - public function isUtf8(): bool - { - return '' === $this->string || preg_match('//u', $this->string); - } - - public function join(array $strings, string $lastGlue = null): parent - { - $str = clone $this; - - $tail = null !== $lastGlue && 1 < \count($strings) ? $lastGlue.array_pop($strings) : ''; - $str->string = implode($this->string, $strings).$tail; - - return $str; - } - - public function length(): int - { - return \strlen($this->string); - } - - public function lower(): parent - { - $str = clone $this; - $str->string = strtolower($str->string); - - return $str; - } - - public function match(string $regexp, int $flags = 0, int $offset = 0): array - { - $match = ((\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags) ? 'preg_match_all' : 'preg_match'; - - if ($this->ignoreCase) { - $regexp .= 'i'; - } - - set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); }); - - try { - if (false === $match($regexp, $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) { - $lastError = preg_last_error(); - - foreach (get_defined_constants(true)['pcre'] as $k => $v) { - if ($lastError === $v && '_ERROR' === substr($k, -6)) { - throw new RuntimeException('Matching failed with '.$k.'.'); - } - } - - throw new RuntimeException('Matching failed with unknown error code.'); - } - } finally { - restore_error_handler(); - } - - return $matches; - } - - public function padBoth(int $length, string $padStr = ' '): parent - { - $str = clone $this; - $str->string = str_pad($this->string, $length, $padStr, \STR_PAD_BOTH); - - return $str; - } - - public function padEnd(int $length, string $padStr = ' '): parent - { - $str = clone $this; - $str->string = str_pad($this->string, $length, $padStr, \STR_PAD_RIGHT); - - return $str; - } - - public function padStart(int $length, string $padStr = ' '): parent - { - $str = clone $this; - $str->string = str_pad($this->string, $length, $padStr, \STR_PAD_LEFT); - - return $str; - } - - public function prepend(string ...$prefix): parent - { - $str = clone $this; - $str->string = (1 >= \count($prefix) ? ($prefix[0] ?? '') : implode('', $prefix)).$str->string; - - return $str; - } - - public function replace(string $from, string $to): parent - { - $str = clone $this; - - if ('' !== $from) { - $str->string = $this->ignoreCase ? str_ireplace($from, $to, $this->string) : str_replace($from, $to, $this->string); - } - - return $str; - } - - public function replaceMatches(string $fromRegexp, $to): parent - { - if ($this->ignoreCase) { - $fromRegexp .= 'i'; - } - - if (\is_array($to)) { - if (!\is_callable($to)) { - throw new \TypeError(sprintf('Argument 2 passed to "%s::replaceMatches()" must be callable, array given.', static::class)); - } - - $replace = 'preg_replace_callback'; - } else { - $replace = $to instanceof \Closure ? 'preg_replace_callback' : 'preg_replace'; - } - - set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); }); - - try { - if (null === $string = $replace($fromRegexp, $to, $this->string)) { - $lastError = preg_last_error(); - - foreach (get_defined_constants(true)['pcre'] as $k => $v) { - if ($lastError === $v && '_ERROR' === substr($k, -6)) { - throw new RuntimeException('Matching failed with '.$k.'.'); - } - } - - throw new RuntimeException('Matching failed with unknown error code.'); - } - } finally { - restore_error_handler(); - } - - $str = clone $this; - $str->string = $string; - - return $str; - } - - public function reverse(): parent - { - $str = clone $this; - $str->string = strrev($str->string); - - return $str; - } - - public function slice(int $start = 0, int $length = null): parent - { - $str = clone $this; - $str->string = (string) substr($this->string, $start, $length ?? \PHP_INT_MAX); - - return $str; - } - - public function snake(): parent - { - $str = $this->camel()->title(); - $str->string = strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], '\1_\2', $str->string)); - - return $str; - } - - public function splice(string $replacement, int $start = 0, int $length = null): parent - { - $str = clone $this; - $str->string = substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX); - - return $str; - } - - public function split(string $delimiter, int $limit = null, int $flags = null): array - { - if (1 > $limit = $limit ?? \PHP_INT_MAX) { - throw new InvalidArgumentException('Split limit must be a positive integer.'); - } - - if ('' === $delimiter) { - throw new InvalidArgumentException('Split delimiter is empty.'); - } - - if (null !== $flags) { - return parent::split($delimiter, $limit, $flags); - } - - $str = clone $this; - $chunks = $this->ignoreCase - ? preg_split('{'.preg_quote($delimiter).'}iD', $this->string, $limit) - : explode($delimiter, $this->string, $limit); - - foreach ($chunks as &$chunk) { - $str->string = $chunk; - $chunk = clone $str; - } - - return $chunks; - } - - public function startsWith($prefix): bool - { - if ($prefix instanceof parent) { - $prefix = $prefix->string; - } elseif (!\is_string($prefix)) { - return parent::startsWith($prefix); - } - - return '' !== $prefix && 0 === ($this->ignoreCase ? strncasecmp($this->string, $prefix, \strlen($prefix)) : strncmp($this->string, $prefix, \strlen($prefix))); - } - - public function title(bool $allWords = false): parent - { - $str = clone $this; - $str->string = $allWords ? ucwords($str->string) : ucfirst($str->string); - - return $str; - } - - public function toUnicodeString(string $fromEncoding = null): UnicodeString - { - return new UnicodeString($this->toCodePointString($fromEncoding)->string); - } - - public function toCodePointString(string $fromEncoding = null): CodePointString - { - $u = new CodePointString(); - - if (\in_array($fromEncoding, [null, 'utf8', 'utf-8', 'UTF8', 'UTF-8'], true) && preg_match('//u', $this->string)) { - $u->string = $this->string; - - return $u; - } - - set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); }); - - try { - try { - $validEncoding = false !== mb_detect_encoding($this->string, $fromEncoding ?? 'Windows-1252', true); - } catch (InvalidArgumentException $e) { - if (!\function_exists('iconv')) { - throw $e; - } - - $u->string = iconv($fromEncoding ?? 'Windows-1252', 'UTF-8', $this->string); - - return $u; - } - } finally { - restore_error_handler(); - } - - if (!$validEncoding) { - throw new InvalidArgumentException(sprintf('Invalid "%s" string.', $fromEncoding ?? 'Windows-1252')); - } - - $u->string = mb_convert_encoding($this->string, 'UTF-8', $fromEncoding ?? 'Windows-1252'); - - return $u; - } - - public function trim(string $chars = " \t\n\r\0\x0B\x0C"): parent - { - $str = clone $this; - $str->string = trim($str->string, $chars); - - return $str; - } - - public function trimEnd(string $chars = " \t\n\r\0\x0B\x0C"): parent - { - $str = clone $this; - $str->string = rtrim($str->string, $chars); - - return $str; - } - - public function trimStart(string $chars = " \t\n\r\0\x0B\x0C"): parent - { - $str = clone $this; - $str->string = ltrim($str->string, $chars); - - return $str; - } - - public function upper(): parent - { - $str = clone $this; - $str->string = strtoupper($str->string); - - return $str; - } - - public function width(bool $ignoreAnsiDecoration = true): int - { - $string = preg_match('//u', $this->string) ? $this->string : preg_replace('/[\x80-\xFF]/', '?', $this->string); - - return (new CodePointString($string))->width($ignoreAnsiDecoration); - } -} diff --git a/vendor/symfony/string/CodePointString.php b/vendor/symfony/string/CodePointString.php deleted file mode 100644 index 8ab920941..000000000 --- a/vendor/symfony/string/CodePointString.php +++ /dev/null @@ -1,270 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String; - -use Symfony\Component\String\Exception\ExceptionInterface; -use Symfony\Component\String\Exception\InvalidArgumentException; - -/** - * Represents a string of Unicode code points encoded as UTF-8. - * - * @author Nicolas Grekas - * @author Hugo Hamon - * - * @throws ExceptionInterface - */ -class CodePointString extends AbstractUnicodeString -{ - public function __construct(string $string = '') - { - if ('' !== $string && !preg_match('//u', $string)) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - - $this->string = $string; - } - - public function append(string ...$suffix): AbstractString - { - $str = clone $this; - $str->string .= 1 >= \count($suffix) ? ($suffix[0] ?? '') : implode('', $suffix); - - if (!preg_match('//u', $str->string)) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - - return $str; - } - - public function chunk(int $length = 1): array - { - if (1 > $length) { - throw new InvalidArgumentException('The chunk length must be greater than zero.'); - } - - if ('' === $this->string) { - return []; - } - - $rx = '/('; - while (65535 < $length) { - $rx .= '.{65535}'; - $length -= 65535; - } - $rx .= '.{'.$length.'})/us'; - - $str = clone $this; - $chunks = []; - - foreach (preg_split($rx, $this->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY) as $chunk) { - $str->string = $chunk; - $chunks[] = clone $str; - } - - return $chunks; - } - - public function codePointsAt(int $offset): array - { - $str = $offset ? $this->slice($offset, 1) : $this; - - return '' === $str->string ? [] : [mb_ord($str->string, 'UTF-8')]; - } - - public function endsWith($suffix): bool - { - if ($suffix instanceof AbstractString) { - $suffix = $suffix->string; - } elseif (\is_array($suffix) || $suffix instanceof \Traversable) { - return parent::endsWith($suffix); - } else { - $suffix = (string) $suffix; - } - - if ('' === $suffix || !preg_match('//u', $suffix)) { - return false; - } - - if ($this->ignoreCase) { - return preg_match('{'.preg_quote($suffix).'$}iuD', $this->string); - } - - return \strlen($this->string) >= \strlen($suffix) && 0 === substr_compare($this->string, $suffix, -\strlen($suffix)); - } - - public function equalsTo($string): bool - { - if ($string instanceof AbstractString) { - $string = $string->string; - } elseif (\is_array($string) || $string instanceof \Traversable) { - return parent::equalsTo($string); - } else { - $string = (string) $string; - } - - if ('' !== $string && $this->ignoreCase) { - return \strlen($string) === \strlen($this->string) && 0 === mb_stripos($this->string, $string, 0, 'UTF-8'); - } - - return $string === $this->string; - } - - public function indexOf($needle, int $offset = 0): ?int - { - if ($needle instanceof AbstractString) { - $needle = $needle->string; - } elseif (\is_array($needle) || $needle instanceof \Traversable) { - return parent::indexOf($needle, $offset); - } else { - $needle = (string) $needle; - } - - if ('' === $needle) { - return null; - } - - $i = $this->ignoreCase ? mb_stripos($this->string, $needle, $offset, 'UTF-8') : mb_strpos($this->string, $needle, $offset, 'UTF-8'); - - return false === $i ? null : $i; - } - - public function indexOfLast($needle, int $offset = 0): ?int - { - if ($needle instanceof AbstractString) { - $needle = $needle->string; - } elseif (\is_array($needle) || $needle instanceof \Traversable) { - return parent::indexOfLast($needle, $offset); - } else { - $needle = (string) $needle; - } - - if ('' === $needle) { - return null; - } - - $i = $this->ignoreCase ? mb_strripos($this->string, $needle, $offset, 'UTF-8') : mb_strrpos($this->string, $needle, $offset, 'UTF-8'); - - return false === $i ? null : $i; - } - - public function length(): int - { - return mb_strlen($this->string, 'UTF-8'); - } - - public function prepend(string ...$prefix): AbstractString - { - $str = clone $this; - $str->string = (1 >= \count($prefix) ? ($prefix[0] ?? '') : implode('', $prefix)).$this->string; - - if (!preg_match('//u', $str->string)) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - - return $str; - } - - public function replace(string $from, string $to): AbstractString - { - $str = clone $this; - - if ('' === $from || !preg_match('//u', $from)) { - return $str; - } - - if ('' !== $to && !preg_match('//u', $to)) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - - if ($this->ignoreCase) { - $str->string = implode($to, preg_split('{'.preg_quote($from).'}iuD', $this->string)); - } else { - $str->string = str_replace($from, $to, $this->string); - } - - return $str; - } - - public function slice(int $start = 0, int $length = null): AbstractString - { - $str = clone $this; - $str->string = mb_substr($this->string, $start, $length, 'UTF-8'); - - return $str; - } - - public function splice(string $replacement, int $start = 0, int $length = null): AbstractString - { - if (!preg_match('//u', $replacement)) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - - $str = clone $this; - $start = $start ? \strlen(mb_substr($this->string, 0, $start, 'UTF-8')) : 0; - $length = $length ? \strlen(mb_substr($this->string, $start, $length, 'UTF-8')) : $length; - $str->string = substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX); - - return $str; - } - - public function split(string $delimiter, int $limit = null, int $flags = null): array - { - if (1 > $limit = $limit ?? \PHP_INT_MAX) { - throw new InvalidArgumentException('Split limit must be a positive integer.'); - } - - if ('' === $delimiter) { - throw new InvalidArgumentException('Split delimiter is empty.'); - } - - if (null !== $flags) { - return parent::split($delimiter.'u', $limit, $flags); - } - - if (!preg_match('//u', $delimiter)) { - throw new InvalidArgumentException('Split delimiter is not a valid UTF-8 string.'); - } - - $str = clone $this; - $chunks = $this->ignoreCase - ? preg_split('{'.preg_quote($delimiter).'}iuD', $this->string, $limit) - : explode($delimiter, $this->string, $limit); - - foreach ($chunks as &$chunk) { - $str->string = $chunk; - $chunk = clone $str; - } - - return $chunks; - } - - public function startsWith($prefix): bool - { - if ($prefix instanceof AbstractString) { - $prefix = $prefix->string; - } elseif (\is_array($prefix) || $prefix instanceof \Traversable) { - return parent::startsWith($prefix); - } else { - $prefix = (string) $prefix; - } - - if ('' === $prefix || !preg_match('//u', $prefix)) { - return false; - } - - if ($this->ignoreCase) { - return 0 === mb_stripos($this->string, $prefix, 0, 'UTF-8'); - } - - return 0 === strncmp($this->string, $prefix, \strlen($prefix)); - } -} diff --git a/vendor/symfony/string/Exception/ExceptionInterface.php b/vendor/symfony/string/Exception/ExceptionInterface.php deleted file mode 100644 index 361978656..000000000 --- a/vendor/symfony/string/Exception/ExceptionInterface.php +++ /dev/null @@ -1,16 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String\Exception; - -interface ExceptionInterface extends \Throwable -{ -} diff --git a/vendor/symfony/string/Exception/InvalidArgumentException.php b/vendor/symfony/string/Exception/InvalidArgumentException.php deleted file mode 100644 index 6aa586bcf..000000000 --- a/vendor/symfony/string/Exception/InvalidArgumentException.php +++ /dev/null @@ -1,16 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String\Exception; - -class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface -{ -} diff --git a/vendor/symfony/string/Exception/RuntimeException.php b/vendor/symfony/string/Exception/RuntimeException.php deleted file mode 100644 index 77cb091f9..000000000 --- a/vendor/symfony/string/Exception/RuntimeException.php +++ /dev/null @@ -1,16 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String\Exception; - -class RuntimeException extends \RuntimeException implements ExceptionInterface -{ -} diff --git a/vendor/symfony/string/Inflector/EnglishInflector.php b/vendor/symfony/string/Inflector/EnglishInflector.php deleted file mode 100644 index 9f2fac675..000000000 --- a/vendor/symfony/string/Inflector/EnglishInflector.php +++ /dev/null @@ -1,511 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String\Inflector; - -final class EnglishInflector implements InflectorInterface -{ - /** - * Map English plural to singular suffixes. - * - * @see http://english-zone.com/spelling/plurals.html - */ - private const PLURAL_MAP = [ - // First entry: plural suffix, reversed - // Second entry: length of plural suffix - // Third entry: Whether the suffix may succeed a vocal - // Fourth entry: Whether the suffix may succeed a consonant - // Fifth entry: singular suffix, normal - - // bacteria (bacterium), criteria (criterion), phenomena (phenomenon) - ['a', 1, true, true, ['on', 'um']], - - // nebulae (nebula) - ['ea', 2, true, true, 'a'], - - // services (service) - ['secivres', 8, true, true, 'service'], - - // mice (mouse), lice (louse) - ['eci', 3, false, true, 'ouse'], - - // geese (goose) - ['esee', 4, false, true, 'oose'], - - // fungi (fungus), alumni (alumnus), syllabi (syllabus), radii (radius) - ['i', 1, true, true, 'us'], - - // men (man), women (woman) - ['nem', 3, true, true, 'man'], - - // children (child) - ['nerdlihc', 8, true, true, 'child'], - - // oxen (ox) - ['nexo', 4, false, false, 'ox'], - - // indices (index), appendices (appendix), prices (price) - ['seci', 4, false, true, ['ex', 'ix', 'ice']], - - // selfies (selfie) - ['seifles', 7, true, true, 'selfie'], - - // zombies (zombie) - ['seibmoz', 7, true, true, 'zombie'], - - // movies (movie) - ['seivom', 6, true, true, 'movie'], - - // conspectuses (conspectus), prospectuses (prospectus) - ['sesutcep', 8, true, true, 'pectus'], - - // feet (foot) - ['teef', 4, true, true, 'foot'], - - // geese (goose) - ['eseeg', 5, true, true, 'goose'], - - // teeth (tooth) - ['hteet', 5, true, true, 'tooth'], - - // news (news) - ['swen', 4, true, true, 'news'], - - // series (series) - ['seires', 6, true, true, 'series'], - - // babies (baby) - ['sei', 3, false, true, 'y'], - - // accesses (access), addresses (address), kisses (kiss) - ['sess', 4, true, false, 'ss'], - - // analyses (analysis), ellipses (ellipsis), fungi (fungus), - // neuroses (neurosis), theses (thesis), emphases (emphasis), - // oases (oasis), crises (crisis), houses (house), bases (base), - // atlases (atlas) - ['ses', 3, true, true, ['s', 'se', 'sis']], - - // objectives (objective), alternative (alternatives) - ['sevit', 5, true, true, 'tive'], - - // drives (drive) - ['sevird', 6, false, true, 'drive'], - - // lives (life), wives (wife) - ['sevi', 4, false, true, 'ife'], - - // moves (move) - ['sevom', 5, true, true, 'move'], - - // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf), caves (cave), staves (staff) - ['sev', 3, true, true, ['f', 've', 'ff']], - - // axes (axis), axes (ax), axes (axe) - ['sexa', 4, false, false, ['ax', 'axe', 'axis']], - - // indexes (index), matrixes (matrix) - ['sex', 3, true, false, 'x'], - - // quizzes (quiz) - ['sezz', 4, true, false, 'z'], - - // bureaus (bureau) - ['suae', 4, false, true, 'eau'], - - // fees (fee), trees (tree), employees (employee) - ['see', 3, true, true, 'ee'], - - // edges (edge) - ['segd', 4, true, true, 'dge'], - - // roses (rose), garages (garage), cassettes (cassette), - // waltzes (waltz), heroes (hero), bushes (bush), arches (arch), - // shoes (shoe) - ['se', 2, true, true, ['', 'e']], - - // tags (tag) - ['s', 1, true, true, ''], - - // chateaux (chateau) - ['xuae', 4, false, true, 'eau'], - - // people (person) - ['elpoep', 6, true, true, 'person'], - ]; - - /** - * Map English singular to plural suffixes. - * - * @see http://english-zone.com/spelling/plurals.html - */ - private const SINGULAR_MAP = [ - // First entry: singular suffix, reversed - // Second entry: length of singular suffix - // Third entry: Whether the suffix may succeed a vocal - // Fourth entry: Whether the suffix may succeed a consonant - // Fifth entry: plural suffix, normal - - // criterion (criteria) - ['airetirc', 8, false, false, 'criterion'], - - // nebulae (nebula) - ['aluben', 6, false, false, 'nebulae'], - - // children (child) - ['dlihc', 5, true, true, 'children'], - - // prices (price) - ['eci', 3, false, true, 'ices'], - - // services (service) - ['ecivres', 7, true, true, 'services'], - - // lives (life), wives (wife) - ['efi', 3, false, true, 'ives'], - - // selfies (selfie) - ['eifles', 6, true, true, 'selfies'], - - // movies (movie) - ['eivom', 5, true, true, 'movies'], - - // lice (louse) - ['esuol', 5, false, true, 'lice'], - - // mice (mouse) - ['esuom', 5, false, true, 'mice'], - - // geese (goose) - ['esoo', 4, false, true, 'eese'], - - // houses (house), bases (base) - ['es', 2, true, true, 'ses'], - - // geese (goose) - ['esoog', 5, true, true, 'geese'], - - // caves (cave) - ['ev', 2, true, true, 'ves'], - - // drives (drive) - ['evird', 5, false, true, 'drives'], - - // objectives (objective), alternative (alternatives) - ['evit', 4, true, true, 'tives'], - - // moves (move) - ['evom', 4, true, true, 'moves'], - - // staves (staff) - ['ffats', 5, true, true, 'staves'], - - // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf) - ['ff', 2, true, true, 'ffs'], - - // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf) - ['f', 1, true, true, ['fs', 'ves']], - - // arches (arch) - ['hc', 2, true, true, 'ches'], - - // bushes (bush) - ['hs', 2, true, true, 'shes'], - - // teeth (tooth) - ['htoot', 5, true, true, 'teeth'], - - // bacteria (bacterium), criteria (criterion), phenomena (phenomenon) - ['mu', 2, true, true, 'a'], - - // men (man), women (woman) - ['nam', 3, true, true, 'men'], - - // people (person) - ['nosrep', 6, true, true, ['persons', 'people']], - - // bacteria (bacterium), criteria (criterion), phenomena (phenomenon) - ['noi', 3, true, true, 'ions'], - - // coupon (coupons) - ['nop', 3, true, true, 'pons'], - - // seasons (season), treasons (treason), poisons (poison), lessons (lesson) - ['nos', 3, true, true, 'sons'], - - // bacteria (bacterium), criteria (criterion), phenomena (phenomenon) - ['no', 2, true, true, 'a'], - - // echoes (echo) - ['ohce', 4, true, true, 'echoes'], - - // heroes (hero) - ['oreh', 4, true, true, 'heroes'], - - // atlases (atlas) - ['salta', 5, true, true, 'atlases'], - - // irises (iris) - ['siri', 4, true, true, 'irises'], - - // analyses (analysis), ellipses (ellipsis), neuroses (neurosis) - // theses (thesis), emphases (emphasis), oases (oasis), - // crises (crisis) - ['sis', 3, true, true, 'ses'], - - // accesses (access), addresses (address), kisses (kiss) - ['ss', 2, true, false, 'sses'], - - // syllabi (syllabus) - ['suballys', 8, true, true, 'syllabi'], - - // buses (bus) - ['sub', 3, true, true, 'buses'], - - // circuses (circus) - ['suc', 3, true, true, 'cuses'], - - // conspectuses (conspectus), prospectuses (prospectus) - ['sutcep', 6, true, true, 'pectuses'], - - // fungi (fungus), alumni (alumnus), syllabi (syllabus), radii (radius) - ['su', 2, true, true, 'i'], - - // news (news) - ['swen', 4, true, true, 'news'], - - // feet (foot) - ['toof', 4, true, true, 'feet'], - - // chateaux (chateau), bureaus (bureau) - ['uae', 3, false, true, ['eaus', 'eaux']], - - // oxen (ox) - ['xo', 2, false, false, 'oxen'], - - // hoaxes (hoax) - ['xaoh', 4, true, false, 'hoaxes'], - - // indices (index) - ['xedni', 5, false, true, ['indicies', 'indexes']], - - // boxes (box) - ['xo', 2, false, true, 'oxes'], - - // indexes (index), matrixes (matrix) - ['x', 1, true, false, ['cies', 'xes']], - - // appendices (appendix) - ['xi', 2, false, true, 'ices'], - - // babies (baby) - ['y', 1, false, true, 'ies'], - - // quizzes (quiz) - ['ziuq', 4, true, false, 'quizzes'], - - // waltzes (waltz) - ['z', 1, true, true, 'zes'], - ]; - - /** - * A list of words which should not be inflected, reversed. - */ - private const UNINFLECTED = [ - '', - - // data - 'atad', - - // deer - 'reed', - - // feedback - 'kcabdeef', - - // fish - 'hsif', - - // info - 'ofni', - - // moose - 'esoom', - - // series - 'seires', - - // sheep - 'peehs', - - // species - 'seiceps', - ]; - - /** - * {@inheritdoc} - */ - public function singularize(string $plural): array - { - $pluralRev = strrev($plural); - $lowerPluralRev = strtolower($pluralRev); - $pluralLength = \strlen($lowerPluralRev); - - // Check if the word is one which is not inflected, return early if so - if (\in_array($lowerPluralRev, self::UNINFLECTED, true)) { - return [$plural]; - } - - // The outer loop iterates over the entries of the plural table - // The inner loop $j iterates over the characters of the plural suffix - // in the plural table to compare them with the characters of the actual - // given plural suffix - foreach (self::PLURAL_MAP as $map) { - $suffix = $map[0]; - $suffixLength = $map[1]; - $j = 0; - - // Compare characters in the plural table and of the suffix of the - // given plural one by one - while ($suffix[$j] === $lowerPluralRev[$j]) { - // Let $j point to the next character - ++$j; - - // Successfully compared the last character - // Add an entry with the singular suffix to the singular array - if ($j === $suffixLength) { - // Is there any character preceding the suffix in the plural string? - if ($j < $pluralLength) { - $nextIsVocal = false !== strpos('aeiou', $lowerPluralRev[$j]); - - if (!$map[2] && $nextIsVocal) { - // suffix may not succeed a vocal but next char is one - break; - } - - if (!$map[3] && !$nextIsVocal) { - // suffix may not succeed a consonant but next char is one - break; - } - } - - $newBase = substr($plural, 0, $pluralLength - $suffixLength); - $newSuffix = $map[4]; - - // Check whether the first character in the plural suffix - // is uppercased. If yes, uppercase the first character in - // the singular suffix too - $firstUpper = ctype_upper($pluralRev[$j - 1]); - - if (\is_array($newSuffix)) { - $singulars = []; - - foreach ($newSuffix as $newSuffixEntry) { - $singulars[] = $newBase.($firstUpper ? ucfirst($newSuffixEntry) : $newSuffixEntry); - } - - return $singulars; - } - - return [$newBase.($firstUpper ? ucfirst($newSuffix) : $newSuffix)]; - } - - // Suffix is longer than word - if ($j === $pluralLength) { - break; - } - } - } - - // Assume that plural and singular is identical - return [$plural]; - } - - /** - * {@inheritdoc} - */ - public function pluralize(string $singular): array - { - $singularRev = strrev($singular); - $lowerSingularRev = strtolower($singularRev); - $singularLength = \strlen($lowerSingularRev); - - // Check if the word is one which is not inflected, return early if so - if (\in_array($lowerSingularRev, self::UNINFLECTED, true)) { - return [$singular]; - } - - // The outer loop iterates over the entries of the singular table - // The inner loop $j iterates over the characters of the singular suffix - // in the singular table to compare them with the characters of the actual - // given singular suffix - foreach (self::SINGULAR_MAP as $map) { - $suffix = $map[0]; - $suffixLength = $map[1]; - $j = 0; - - // Compare characters in the singular table and of the suffix of the - // given plural one by one - - while ($suffix[$j] === $lowerSingularRev[$j]) { - // Let $j point to the next character - ++$j; - - // Successfully compared the last character - // Add an entry with the plural suffix to the plural array - if ($j === $suffixLength) { - // Is there any character preceding the suffix in the plural string? - if ($j < $singularLength) { - $nextIsVocal = false !== strpos('aeiou', $lowerSingularRev[$j]); - - if (!$map[2] && $nextIsVocal) { - // suffix may not succeed a vocal but next char is one - break; - } - - if (!$map[3] && !$nextIsVocal) { - // suffix may not succeed a consonant but next char is one - break; - } - } - - $newBase = substr($singular, 0, $singularLength - $suffixLength); - $newSuffix = $map[4]; - - // Check whether the first character in the singular suffix - // is uppercased. If yes, uppercase the first character in - // the singular suffix too - $firstUpper = ctype_upper($singularRev[$j - 1]); - - if (\is_array($newSuffix)) { - $plurals = []; - - foreach ($newSuffix as $newSuffixEntry) { - $plurals[] = $newBase.($firstUpper ? ucfirst($newSuffixEntry) : $newSuffixEntry); - } - - return $plurals; - } - - return [$newBase.($firstUpper ? ucfirst($newSuffix) : $newSuffix)]; - } - - // Suffix is longer than word - if ($j === $singularLength) { - break; - } - } - } - - // Assume that plural is singular with a trailing `s` - return [$singular.'s']; - } -} diff --git a/vendor/symfony/string/Inflector/FrenchInflector.php b/vendor/symfony/string/Inflector/FrenchInflector.php deleted file mode 100644 index 42f6125aa..000000000 --- a/vendor/symfony/string/Inflector/FrenchInflector.php +++ /dev/null @@ -1,157 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String\Inflector; - -/** - * French inflector. - * - * This class does only inflect nouns; not adjectives nor composed words like "soixante-dix". - */ -final class FrenchInflector implements InflectorInterface -{ - /** - * A list of all rules for pluralise. - * - * @see https://la-conjugaison.nouvelobs.com/regles/grammaire/le-pluriel-des-noms-121.php - */ - private const PLURALIZE_REGEXP = [ - // First entry: regexp - // Second entry: replacement - - // Words finishing with "s", "x" or "z" are invariables - // Les mots finissant par "s", "x" ou "z" sont invariables - ['/(s|x|z)$/i', '\1'], - - // Words finishing with "eau" are pluralized with a "x" - // Les mots finissant par "eau" prennent tous un "x" au pluriel - ['/(eau)$/i', '\1x'], - - // Words finishing with "au" are pluralized with a "x" excepted "landau" - // Les mots finissant par "au" prennent un "x" au pluriel sauf "landau" - ['/^(landau)$/i', '\1s'], - ['/(au)$/i', '\1x'], - - // Words finishing with "eu" are pluralized with a "x" excepted "pneu", "bleu", "émeu" - // Les mots finissant en "eu" prennent un "x" au pluriel sauf "pneu", "bleu", "émeu" - ['/^(pneu|bleu|émeu)$/i', '\1s'], - ['/(eu)$/i', '\1x'], - - // Words finishing with "al" are pluralized with a "aux" excepted - // Les mots finissant en "al" se terminent en "aux" sauf - ['/^(bal|carnaval|caracal|chacal|choral|corral|étal|festival|récital|val)$/i', '\1s'], - ['/al$/i', '\1aux'], - - // Aspirail, bail, corail, émail, fermail, soupirail, travail, vantail et vitrail font leur pluriel en -aux - ['/^(aspir|b|cor|ém|ferm|soupir|trav|vant|vitr)ail$/i', '\1aux'], - - // Bijou, caillou, chou, genou, hibou, joujou et pou qui prennent un x au pluriel - ['/^(bij|caill|ch|gen|hib|jouj|p)ou$/i', '\1oux'], - - // Invariable words - ['/^(cinquante|soixante|mille)$/i', '\1'], - - // French titles - ['/^(mon|ma)(sieur|dame|demoiselle|seigneur)$/', 'mes\2s'], - ['/^(Mon|Ma)(sieur|dame|demoiselle|seigneur)$/', 'Mes\2s'], - ]; - - /** - * A list of all rules for singularize. - */ - private const SINGULARIZE_REGEXP = [ - // First entry: regexp - // Second entry: replacement - - // Aspirail, bail, corail, émail, fermail, soupirail, travail, vantail et vitrail font leur pluriel en -aux - ['/((aspir|b|cor|ém|ferm|soupir|trav|vant|vitr))aux$/i', '\1ail'], - - // Words finishing with "eau" are pluralized with a "x" - // Les mots finissant par "eau" prennent tous un "x" au pluriel - ['/(eau)x$/i', '\1'], - - // Words finishing with "al" are pluralized with a "aux" expected - // Les mots finissant en "al" se terminent en "aux" sauf - ['/(amir|anim|arsen|boc|can|capit|capor|chev|crist|génér|hopit|hôpit|idé|journ|littor|loc|m|mét|minér|princip|radic|termin)aux$/i', '\1al'], - - // Words finishing with "au" are pluralized with a "x" excepted "landau" - // Les mots finissant par "au" prennent un "x" au pluriel sauf "landau" - ['/(au)x$/i', '\1'], - - // Words finishing with "eu" are pluralized with a "x" excepted "pneu", "bleu", "émeu" - // Les mots finissant en "eu" prennent un "x" au pluriel sauf "pneu", "bleu", "émeu" - ['/(eu)x$/i', '\1'], - - // Words finishing with "ou" are pluralized with a "s" excepted bijou, caillou, chou, genou, hibou, joujou, pou - // Les mots finissant par "ou" prennent un "s" sauf bijou, caillou, chou, genou, hibou, joujou, pou - ['/(bij|caill|ch|gen|hib|jouj|p)oux$/i', '\1ou'], - - // French titles - ['/^mes(dame|demoiselle)s$/', 'ma\1'], - ['/^Mes(dame|demoiselle)s$/', 'Ma\1'], - ['/^mes(sieur|seigneur)s$/', 'mon\1'], - ['/^Mes(sieur|seigneur)s$/', 'Mon\1'], - - //Default rule - ['/s$/i', ''], - ]; - - /** - * A list of words which should not be inflected. - * This list is only used by singularize. - */ - private const UNINFLECTED = '/^(abcès|accès|abus|albatros|anchois|anglais|autobus|bois|brebis|carquois|cas|chas|colis|concours|corps|cours|cyprès|décès|devis|discours|dos|embarras|engrais|entrelacs|excès|fils|fois|gâchis|gars|glas|héros|intrus|jars|jus|kermès|lacis|legs|lilas|marais|mars|matelas|mépris|mets|mois|mors|obus|os|palais|paradis|parcours|pardessus|pays|plusieurs|poids|pois|pouls|printemps|processus|progrès|puits|pus|rabais|radis|recors|recours|refus|relais|remords|remous|rictus|rhinocéros|repas|rubis|sas|secours|sens|souris|succès|talus|tapis|tas|taudis|temps|tiers|univers|velours|verglas|vernis|virus)$/i'; - - /** - * {@inheritdoc} - */ - public function singularize(string $plural): array - { - if ($this->isInflectedWord($plural)) { - return [$plural]; - } - - foreach (self::SINGULARIZE_REGEXP as $rule) { - [$regexp, $replace] = $rule; - - if (1 === preg_match($regexp, $plural)) { - return [preg_replace($regexp, $replace, $plural)]; - } - } - - return [$plural]; - } - - /** - * {@inheritdoc} - */ - public function pluralize(string $singular): array - { - if ($this->isInflectedWord($singular)) { - return [$singular]; - } - - foreach (self::PLURALIZE_REGEXP as $rule) { - [$regexp, $replace] = $rule; - - if (1 === preg_match($regexp, $singular)) { - return [preg_replace($regexp, $replace, $singular)]; - } - } - - return [$singular.'s']; - } - - private function isInflectedWord(string $word): bool - { - return 1 === preg_match(self::UNINFLECTED, $word); - } -} diff --git a/vendor/symfony/string/Inflector/InflectorInterface.php b/vendor/symfony/string/Inflector/InflectorInterface.php deleted file mode 100644 index 67f283404..000000000 --- a/vendor/symfony/string/Inflector/InflectorInterface.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String\Inflector; - -interface InflectorInterface -{ - /** - * Returns the singular forms of a string. - * - * If the method can't determine the form with certainty, several possible singulars are returned. - * - * @return string[] - */ - public function singularize(string $plural): array; - - /** - * Returns the plural forms of a string. - * - * If the method can't determine the form with certainty, several possible plurals are returned. - * - * @return string[] - */ - public function pluralize(string $singular): array; -} diff --git a/vendor/symfony/string/LazyString.php b/vendor/symfony/string/LazyString.php deleted file mode 100644 index b3801db77..000000000 --- a/vendor/symfony/string/LazyString.php +++ /dev/null @@ -1,164 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String; - -/** - * A string whose value is computed lazily by a callback. - * - * @author Nicolas Grekas - */ -class LazyString implements \Stringable, \JsonSerializable -{ - private $value; - - /** - * @param callable|array $callback A callable or a [Closure, method] lazy-callable - * - * @return static - */ - public static function fromCallable($callback, ...$arguments): self - { - if (!\is_callable($callback) && !(\is_array($callback) && isset($callback[0]) && $callback[0] instanceof \Closure && 2 >= \count($callback))) { - throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be a callable or a [Closure, method] lazy-callable, "%s" given.', __METHOD__, get_debug_type($callback))); - } - - $lazyString = new static(); - $lazyString->value = static function () use (&$callback, &$arguments, &$value): string { - if (null !== $arguments) { - if (!\is_callable($callback)) { - $callback[0] = $callback[0](); - $callback[1] = $callback[1] ?? '__invoke'; - } - $value = $callback(...$arguments); - $callback = self::getPrettyName($callback); - $arguments = null; - } - - return $value ?? ''; - }; - - return $lazyString; - } - - /** - * @param string|int|float|bool|\Stringable $value - * - * @return static - */ - public static function fromStringable($value): self - { - if (!self::isStringable($value)) { - throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be a scalar or a stringable object, "%s" given.', __METHOD__, get_debug_type($value))); - } - - if (\is_object($value)) { - return static::fromCallable([$value, '__toString']); - } - - $lazyString = new static(); - $lazyString->value = (string) $value; - - return $lazyString; - } - - /** - * Tells whether the provided value can be cast to string. - */ - final public static function isStringable($value): bool - { - return \is_string($value) || $value instanceof self || (\is_object($value) ? method_exists($value, '__toString') : is_scalar($value)); - } - - /** - * Casts scalars and stringable objects to strings. - * - * @param object|string|int|float|bool $value - * - * @throws \TypeError When the provided value is not stringable - */ - final public static function resolve($value): string - { - return $value; - } - - /** - * @return string - */ - public function __toString() - { - if (\is_string($this->value)) { - return $this->value; - } - - try { - return $this->value = ($this->value)(); - } catch (\Throwable $e) { - if (\TypeError::class === \get_class($e) && __FILE__ === $e->getFile()) { - $type = explode(', ', $e->getMessage()); - $type = substr(array_pop($type), 0, -\strlen(' returned')); - $r = new \ReflectionFunction($this->value); - $callback = $r->getStaticVariables()['callback']; - - $e = new \TypeError(sprintf('Return value of %s() passed to %s::fromCallable() must be of the type string, %s returned.', $callback, static::class, $type)); - } - - if (\PHP_VERSION_ID < 70400) { - // leverage the ErrorHandler component with graceful fallback when it's not available - return trigger_error($e, \E_USER_ERROR); - } - - throw $e; - } - } - - public function __sleep(): array - { - $this->__toString(); - - return ['value']; - } - - public function jsonSerialize(): string - { - return $this->__toString(); - } - - private function __construct() - { - } - - private static function getPrettyName(callable $callback): string - { - if (\is_string($callback)) { - return $callback; - } - - if (\is_array($callback)) { - $class = \is_object($callback[0]) ? get_debug_type($callback[0]) : $callback[0]; - $method = $callback[1]; - } elseif ($callback instanceof \Closure) { - $r = new \ReflectionFunction($callback); - - if (false !== strpos($r->name, '{closure}') || !$class = $r->getClosureScopeClass()) { - return $r->name; - } - - $class = $class->name; - $method = $r->name; - } else { - $class = get_debug_type($callback); - $method = '__invoke'; - } - - return $class.'::'.$method; - } -} diff --git a/vendor/symfony/string/Resources/data/wcswidth_table_wide.php b/vendor/symfony/string/Resources/data/wcswidth_table_wide.php deleted file mode 100644 index 43c802d05..000000000 --- a/vendor/symfony/string/Resources/data/wcswidth_table_wide.php +++ /dev/null @@ -1,1135 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String; - -if (!\function_exists(u::class)) { - function u(?string $string = ''): UnicodeString - { - return new UnicodeString($string ?? ''); - } -} - -if (!\function_exists(b::class)) { - function b(?string $string = ''): ByteString - { - return new ByteString($string ?? ''); - } -} - -if (!\function_exists(s::class)) { - /** - * @return UnicodeString|ByteString - */ - function s(?string $string = ''): AbstractString - { - $string = $string ?? ''; - - return preg_match('//u', $string) ? new UnicodeString($string) : new ByteString($string); - } -} diff --git a/vendor/symfony/string/Slugger/AsciiSlugger.php b/vendor/symfony/string/Slugger/AsciiSlugger.php deleted file mode 100644 index 5aecfeb5f..000000000 --- a/vendor/symfony/string/Slugger/AsciiSlugger.php +++ /dev/null @@ -1,183 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String\Slugger; - -use Symfony\Component\String\AbstractUnicodeString; -use Symfony\Component\String\UnicodeString; -use Symfony\Contracts\Translation\LocaleAwareInterface; - -if (!interface_exists(LocaleAwareInterface::class)) { - throw new \LogicException('You cannot use the "Symfony\Component\String\Slugger\AsciiSlugger" as the "symfony/translation-contracts" package is not installed. Try running "composer require symfony/translation-contracts".'); -} - -/** - * @author Titouan Galopin - */ -class AsciiSlugger implements SluggerInterface, LocaleAwareInterface -{ - private const LOCALE_TO_TRANSLITERATOR_ID = [ - 'am' => 'Amharic-Latin', - 'ar' => 'Arabic-Latin', - 'az' => 'Azerbaijani-Latin', - 'be' => 'Belarusian-Latin', - 'bg' => 'Bulgarian-Latin', - 'bn' => 'Bengali-Latin', - 'de' => 'de-ASCII', - 'el' => 'Greek-Latin', - 'fa' => 'Persian-Latin', - 'he' => 'Hebrew-Latin', - 'hy' => 'Armenian-Latin', - 'ka' => 'Georgian-Latin', - 'kk' => 'Kazakh-Latin', - 'ky' => 'Kirghiz-Latin', - 'ko' => 'Korean-Latin', - 'mk' => 'Macedonian-Latin', - 'mn' => 'Mongolian-Latin', - 'or' => 'Oriya-Latin', - 'ps' => 'Pashto-Latin', - 'ru' => 'Russian-Latin', - 'sr' => 'Serbian-Latin', - 'sr_Cyrl' => 'Serbian-Latin', - 'th' => 'Thai-Latin', - 'tk' => 'Turkmen-Latin', - 'uk' => 'Ukrainian-Latin', - 'uz' => 'Uzbek-Latin', - 'zh' => 'Han-Latin', - ]; - - private $defaultLocale; - private $symbolsMap = [ - 'en' => ['@' => 'at', '&' => 'and'], - ]; - - /** - * Cache of transliterators per locale. - * - * @var \Transliterator[] - */ - private $transliterators = []; - - /** - * @param array|\Closure|null $symbolsMap - */ - public function __construct(string $defaultLocale = null, $symbolsMap = null) - { - if (null !== $symbolsMap && !\is_array($symbolsMap) && !$symbolsMap instanceof \Closure) { - throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be array, Closure or null, "%s" given.', __METHOD__, \gettype($symbolsMap))); - } - - $this->defaultLocale = $defaultLocale; - $this->symbolsMap = $symbolsMap ?? $this->symbolsMap; - } - - /** - * {@inheritdoc} - */ - public function setLocale($locale) - { - $this->defaultLocale = $locale; - } - - /** - * {@inheritdoc} - */ - public function getLocale() - { - return $this->defaultLocale; - } - - /** - * {@inheritdoc} - */ - public function slug(string $string, string $separator = '-', string $locale = null): AbstractUnicodeString - { - $locale = $locale ?? $this->defaultLocale; - - $transliterator = []; - if ($locale && ('de' === $locale || 0 === strpos($locale, 'de_'))) { - // Use the shortcut for German in UnicodeString::ascii() if possible (faster and no requirement on intl) - $transliterator = ['de-ASCII']; - } elseif (\function_exists('transliterator_transliterate') && $locale) { - $transliterator = (array) $this->createTransliterator($locale); - } - - if ($this->symbolsMap instanceof \Closure) { - // If the symbols map is passed as a closure, there is no need to fallback to the parent locale - // as the closure can just provide substitutions for all locales of interest. - $symbolsMap = $this->symbolsMap; - array_unshift($transliterator, static function ($s) use ($symbolsMap, $locale) { - return $symbolsMap($s, $locale); - }); - } - - $unicodeString = (new UnicodeString($string))->ascii($transliterator); - - if (\is_array($this->symbolsMap)) { - $map = null; - if (isset($this->symbolsMap[$locale])) { - $map = $this->symbolsMap[$locale]; - } else { - $parent = self::getParentLocale($locale); - if ($parent && isset($this->symbolsMap[$parent])) { - $map = $this->symbolsMap[$parent]; - } - } - if ($map) { - foreach ($map as $char => $replace) { - $unicodeString = $unicodeString->replace($char, ' '.$replace.' '); - } - } - } - - return $unicodeString - ->replaceMatches('/[^A-Za-z0-9]++/', $separator) - ->trim($separator) - ; - } - - private function createTransliterator(string $locale): ?\Transliterator - { - if (\array_key_exists($locale, $this->transliterators)) { - return $this->transliterators[$locale]; - } - - // Exact locale supported, cache and return - if ($id = self::LOCALE_TO_TRANSLITERATOR_ID[$locale] ?? null) { - return $this->transliterators[$locale] = \Transliterator::create($id.'/BGN') ?? \Transliterator::create($id); - } - - // Locale not supported and no parent, fallback to any-latin - if (!$parent = self::getParentLocale($locale)) { - return $this->transliterators[$locale] = null; - } - - // Try to use the parent locale (ie. try "de" for "de_AT") and cache both locales - if ($id = self::LOCALE_TO_TRANSLITERATOR_ID[$parent] ?? null) { - $transliterator = \Transliterator::create($id.'/BGN') ?? \Transliterator::create($id); - } - - return $this->transliterators[$locale] = $this->transliterators[$parent] = $transliterator ?? null; - } - - private static function getParentLocale(?string $locale): ?string - { - if (!$locale) { - return null; - } - if (false === $str = strrchr($locale, '_')) { - // no parent locale - return null; - } - - return substr($locale, 0, -\strlen($str)); - } -} diff --git a/vendor/symfony/string/Slugger/SluggerInterface.php b/vendor/symfony/string/Slugger/SluggerInterface.php deleted file mode 100644 index c679ed933..000000000 --- a/vendor/symfony/string/Slugger/SluggerInterface.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String\Slugger; - -use Symfony\Component\String\AbstractUnicodeString; - -/** - * Creates a URL-friendly slug from a given string. - * - * @author Titouan Galopin - */ -interface SluggerInterface -{ - /** - * Creates a slug for the given string and locale, using appropriate transliteration when needed. - */ - public function slug(string $string, string $separator = '-', string $locale = null): AbstractUnicodeString; -} diff --git a/vendor/symfony/string/UnicodeString.php b/vendor/symfony/string/UnicodeString.php deleted file mode 100644 index 9b906c6fc..000000000 --- a/vendor/symfony/string/UnicodeString.php +++ /dev/null @@ -1,377 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\String; - -use Symfony\Component\String\Exception\ExceptionInterface; -use Symfony\Component\String\Exception\InvalidArgumentException; - -/** - * Represents a string of Unicode grapheme clusters encoded as UTF-8. - * - * A letter followed by combining characters (accents typically) form what Unicode defines - * as a grapheme cluster: a character as humans mean it in written texts. This class knows - * about the concept and won't split a letter apart from its combining accents. It also - * ensures all string comparisons happen on their canonically-composed representation, - * ignoring e.g. the order in which accents are listed when a letter has many of them. - * - * @see https://unicode.org/reports/tr15/ - * - * @author Nicolas Grekas - * @author Hugo Hamon - * - * @throws ExceptionInterface - */ -class UnicodeString extends AbstractUnicodeString -{ - public function __construct(string $string = '') - { - $this->string = normalizer_is_normalized($string) ? $string : normalizer_normalize($string); - - if (false === $this->string) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - } - - public function append(string ...$suffix): AbstractString - { - $str = clone $this; - $str->string = $this->string.(1 >= \count($suffix) ? ($suffix[0] ?? '') : implode('', $suffix)); - normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string); - - if (false === $str->string) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - - return $str; - } - - public function chunk(int $length = 1): array - { - if (1 > $length) { - throw new InvalidArgumentException('The chunk length must be greater than zero.'); - } - - if ('' === $this->string) { - return []; - } - - $rx = '/('; - while (65535 < $length) { - $rx .= '\X{65535}'; - $length -= 65535; - } - $rx .= '\X{'.$length.'})/u'; - - $str = clone $this; - $chunks = []; - - foreach (preg_split($rx, $this->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY) as $chunk) { - $str->string = $chunk; - $chunks[] = clone $str; - } - - return $chunks; - } - - public function endsWith($suffix): bool - { - if ($suffix instanceof AbstractString) { - $suffix = $suffix->string; - } elseif (\is_array($suffix) || $suffix instanceof \Traversable) { - return parent::endsWith($suffix); - } else { - $suffix = (string) $suffix; - } - - $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; - normalizer_is_normalized($suffix, $form) ?: $suffix = normalizer_normalize($suffix, $form); - - if ('' === $suffix || false === $suffix) { - return false; - } - - if ($this->ignoreCase) { - return 0 === mb_stripos(grapheme_extract($this->string, \strlen($suffix), \GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix)), $suffix, 0, 'UTF-8'); - } - - return $suffix === grapheme_extract($this->string, \strlen($suffix), \GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix)); - } - - public function equalsTo($string): bool - { - if ($string instanceof AbstractString) { - $string = $string->string; - } elseif (\is_array($string) || $string instanceof \Traversable) { - return parent::equalsTo($string); - } else { - $string = (string) $string; - } - - $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; - normalizer_is_normalized($string, $form) ?: $string = normalizer_normalize($string, $form); - - if ('' !== $string && false !== $string && $this->ignoreCase) { - return \strlen($string) === \strlen($this->string) && 0 === mb_stripos($this->string, $string, 0, 'UTF-8'); - } - - return $string === $this->string; - } - - public function indexOf($needle, int $offset = 0): ?int - { - if ($needle instanceof AbstractString) { - $needle = $needle->string; - } elseif (\is_array($needle) || $needle instanceof \Traversable) { - return parent::indexOf($needle, $offset); - } else { - $needle = (string) $needle; - } - - $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; - normalizer_is_normalized($needle, $form) ?: $needle = normalizer_normalize($needle, $form); - - if ('' === $needle || false === $needle) { - return null; - } - - try { - $i = $this->ignoreCase ? grapheme_stripos($this->string, $needle, $offset) : grapheme_strpos($this->string, $needle, $offset); - } catch (\ValueError $e) { - return null; - } - - return false === $i ? null : $i; - } - - public function indexOfLast($needle, int $offset = 0): ?int - { - if ($needle instanceof AbstractString) { - $needle = $needle->string; - } elseif (\is_array($needle) || $needle instanceof \Traversable) { - return parent::indexOfLast($needle, $offset); - } else { - $needle = (string) $needle; - } - - $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; - normalizer_is_normalized($needle, $form) ?: $needle = normalizer_normalize($needle, $form); - - if ('' === $needle || false === $needle) { - return null; - } - - $string = $this->string; - - if (0 > $offset) { - // workaround https://bugs.php.net/74264 - if (0 > $offset += grapheme_strlen($needle)) { - $string = grapheme_substr($string, 0, $offset); - } - $offset = 0; - } - - $i = $this->ignoreCase ? grapheme_strripos($string, $needle, $offset) : grapheme_strrpos($string, $needle, $offset); - - return false === $i ? null : $i; - } - - public function join(array $strings, string $lastGlue = null): AbstractString - { - $str = parent::join($strings, $lastGlue); - normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string); - - return $str; - } - - public function length(): int - { - return grapheme_strlen($this->string); - } - - /** - * @return static - */ - public function normalize(int $form = self::NFC): parent - { - $str = clone $this; - - if (\in_array($form, [self::NFC, self::NFKC], true)) { - normalizer_is_normalized($str->string, $form) ?: $str->string = normalizer_normalize($str->string, $form); - } elseif (!\in_array($form, [self::NFD, self::NFKD], true)) { - throw new InvalidArgumentException('Unsupported normalization form.'); - } elseif (!normalizer_is_normalized($str->string, $form)) { - $str->string = normalizer_normalize($str->string, $form); - $str->ignoreCase = null; - } - - return $str; - } - - public function prepend(string ...$prefix): AbstractString - { - $str = clone $this; - $str->string = (1 >= \count($prefix) ? ($prefix[0] ?? '') : implode('', $prefix)).$this->string; - normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string); - - if (false === $str->string) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - - return $str; - } - - public function replace(string $from, string $to): AbstractString - { - $str = clone $this; - normalizer_is_normalized($from) ?: $from = normalizer_normalize($from); - - if ('' !== $from && false !== $from) { - $tail = $str->string; - $result = ''; - $indexOf = $this->ignoreCase ? 'grapheme_stripos' : 'grapheme_strpos'; - - while ('' !== $tail && false !== $i = $indexOf($tail, $from)) { - $slice = grapheme_substr($tail, 0, $i); - $result .= $slice.$to; - $tail = substr($tail, \strlen($slice) + \strlen($from)); - } - - $str->string = $result.$tail; - normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string); - - if (false === $str->string) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - } - - return $str; - } - - public function replaceMatches(string $fromRegexp, $to): AbstractString - { - $str = parent::replaceMatches($fromRegexp, $to); - normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string); - - return $str; - } - - public function slice(int $start = 0, int $length = null): AbstractString - { - $str = clone $this; - - if (\PHP_VERSION_ID < 80000 && 0 > $start && grapheme_strlen($this->string) < -$start) { - $start = 0; - } - $str->string = (string) grapheme_substr($this->string, $start, $length ?? 2147483647); - - return $str; - } - - public function splice(string $replacement, int $start = 0, int $length = null): AbstractString - { - $str = clone $this; - - if (\PHP_VERSION_ID < 80000 && 0 > $start && grapheme_strlen($this->string) < -$start) { - $start = 0; - } - $start = $start ? \strlen(grapheme_substr($this->string, 0, $start)) : 0; - $length = $length ? \strlen(grapheme_substr($this->string, $start, $length ?? 2147483647)) : $length; - $str->string = substr_replace($this->string, $replacement, $start, $length ?? 2147483647); - normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string); - - if (false === $str->string) { - throw new InvalidArgumentException('Invalid UTF-8 string.'); - } - - return $str; - } - - public function split(string $delimiter, int $limit = null, int $flags = null): array - { - if (1 > $limit = $limit ?? 2147483647) { - throw new InvalidArgumentException('Split limit must be a positive integer.'); - } - - if ('' === $delimiter) { - throw new InvalidArgumentException('Split delimiter is empty.'); - } - - if (null !== $flags) { - return parent::split($delimiter.'u', $limit, $flags); - } - - normalizer_is_normalized($delimiter) ?: $delimiter = normalizer_normalize($delimiter); - - if (false === $delimiter) { - throw new InvalidArgumentException('Split delimiter is not a valid UTF-8 string.'); - } - - $str = clone $this; - $tail = $this->string; - $chunks = []; - $indexOf = $this->ignoreCase ? 'grapheme_stripos' : 'grapheme_strpos'; - - while (1 < $limit && false !== $i = $indexOf($tail, $delimiter)) { - $str->string = grapheme_substr($tail, 0, $i); - $chunks[] = clone $str; - $tail = substr($tail, \strlen($str->string) + \strlen($delimiter)); - --$limit; - } - - $str->string = $tail; - $chunks[] = clone $str; - - return $chunks; - } - - public function startsWith($prefix): bool - { - if ($prefix instanceof AbstractString) { - $prefix = $prefix->string; - } elseif (\is_array($prefix) || $prefix instanceof \Traversable) { - return parent::startsWith($prefix); - } else { - $prefix = (string) $prefix; - } - - $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; - normalizer_is_normalized($prefix, $form) ?: $prefix = normalizer_normalize($prefix, $form); - - if ('' === $prefix || false === $prefix) { - return false; - } - - if ($this->ignoreCase) { - return 0 === mb_stripos(grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES), $prefix, 0, 'UTF-8'); - } - - return $prefix === grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES); - } - - public function __wakeup() - { - if (!\is_string($this->string)) { - throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); - } - - normalizer_is_normalized($this->string) ?: $this->string = normalizer_normalize($this->string); - } - - public function __clone() - { - if (null === $this->ignoreCase) { - normalizer_is_normalized($this->string) ?: $this->string = normalizer_normalize($this->string); - } - - $this->ignoreCase = false; - } -} diff --git a/vendor/symfony/yaml/Command/LintCommand.php b/vendor/symfony/yaml/Command/LintCommand.php deleted file mode 100644 index 3ebd570e7..000000000 --- a/vendor/symfony/yaml/Command/LintCommand.php +++ /dev/null @@ -1,289 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml\Command; - -use Symfony\Component\Console\CI\GithubActionReporter; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\RuntimeException; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\Yaml\Exception\ParseException; -use Symfony\Component\Yaml\Parser; -use Symfony\Component\Yaml\Yaml; - -/** - * Validates YAML files syntax and outputs encountered errors. - * - * @author Grégoire Pineau - * @author Robin Chalas - */ -class LintCommand extends Command -{ - protected static $defaultName = 'lint:yaml'; - protected static $defaultDescription = 'Lint a YAML file and outputs encountered errors'; - - private $parser; - private $format; - private $displayCorrectFiles; - private $directoryIteratorProvider; - private $isReadableProvider; - - public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null) - { - parent::__construct($name); - - $this->directoryIteratorProvider = $directoryIteratorProvider; - $this->isReadableProvider = $isReadableProvider; - } - - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setDescription(self::$defaultDescription) - ->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN') - ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format') - ->addOption('exclude', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Path(s) to exclude') - ->addOption('parse-tags', null, InputOption::VALUE_NEGATABLE, 'Parse custom tags', null) - ->setHelp(<<%command.name% command lints a YAML file and outputs to STDOUT -the first encountered syntax error. - -You can validates YAML contents passed from STDIN: - - cat filename | php %command.full_name% - - -You can also validate the syntax of a file: - - php %command.full_name% filename - -Or of a whole directory: - - php %command.full_name% dirname - php %command.full_name% dirname --format=json - -You can also exclude one or more specific files: - - php %command.full_name% dirname --exclude="dirname/foo.yaml" --exclude="dirname/bar.yaml" - -EOF - ) - ; - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $io = new SymfonyStyle($input, $output); - $filenames = (array) $input->getArgument('filename'); - $excludes = $input->getOption('exclude'); - $this->format = $input->getOption('format'); - $flags = $input->getOption('parse-tags'); - - if ('github' === $this->format && !class_exists(GithubActionReporter::class)) { - throw new \InvalidArgumentException('The "github" format is only available since "symfony/console" >= 5.3.'); - } - - if (null === $this->format) { - // Autodetect format according to CI environment - $this->format = class_exists(GithubActionReporter::class) && GithubActionReporter::isGithubActionEnvironment() ? 'github' : 'txt'; - } - - $flags = $flags ? Yaml::PARSE_CUSTOM_TAGS : 0; - - $this->displayCorrectFiles = $output->isVerbose(); - - if (['-'] === $filenames) { - return $this->display($io, [$this->validate(file_get_contents('php://stdin'), $flags)]); - } - - if (!$filenames) { - throw new RuntimeException('Please provide a filename or pipe file content to STDIN.'); - } - - $filesInfo = []; - foreach ($filenames as $filename) { - if (!$this->isReadable($filename)) { - throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename)); - } - - foreach ($this->getFiles($filename) as $file) { - if (!\in_array($file->getPathname(), $excludes, true)) { - $filesInfo[] = $this->validate(file_get_contents($file), $flags, $file); - } - } - } - - return $this->display($io, $filesInfo); - } - - private function validate(string $content, int $flags, string $file = null) - { - $prevErrorHandler = set_error_handler(function ($level, $message, $file, $line) use (&$prevErrorHandler) { - if (\E_USER_DEPRECATED === $level) { - throw new ParseException($message, $this->getParser()->getRealCurrentLineNb() + 1); - } - - return $prevErrorHandler ? $prevErrorHandler($level, $message, $file, $line) : false; - }); - - try { - $this->getParser()->parse($content, Yaml::PARSE_CONSTANT | $flags); - } catch (ParseException $e) { - return ['file' => $file, 'line' => $e->getParsedLine(), 'valid' => false, 'message' => $e->getMessage()]; - } finally { - restore_error_handler(); - } - - return ['file' => $file, 'valid' => true]; - } - - private function display(SymfonyStyle $io, array $files): int - { - switch ($this->format) { - case 'txt': - return $this->displayTxt($io, $files); - case 'json': - return $this->displayJson($io, $files); - case 'github': - return $this->displayTxt($io, $files, true); - default: - throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format)); - } - } - - private function displayTxt(SymfonyStyle $io, array $filesInfo, bool $errorAsGithubAnnotations = false): int - { - $countFiles = \count($filesInfo); - $erroredFiles = 0; - $suggestTagOption = false; - - if ($errorAsGithubAnnotations) { - $githubReporter = new GithubActionReporter($io); - } - - foreach ($filesInfo as $info) { - if ($info['valid'] && $this->displayCorrectFiles) { - $io->comment('OK'.($info['file'] ? sprintf(' in %s', $info['file']) : '')); - } elseif (!$info['valid']) { - ++$erroredFiles; - $io->text(' ERROR '.($info['file'] ? sprintf(' in %s', $info['file']) : '')); - $io->text(sprintf(' >> %s', $info['message'])); - - if (false !== strpos($info['message'], 'PARSE_CUSTOM_TAGS')) { - $suggestTagOption = true; - } - - if ($errorAsGithubAnnotations) { - $githubReporter->error($info['message'], $info['file'] ?? 'php://stdin', $info['line']); - } - } - } - - if (0 === $erroredFiles) { - $io->success(sprintf('All %d YAML files contain valid syntax.', $countFiles)); - } else { - $io->warning(sprintf('%d YAML files have valid syntax and %d contain errors.%s', $countFiles - $erroredFiles, $erroredFiles, $suggestTagOption ? ' Use the --parse-tags option if you want parse custom tags.' : '')); - } - - return min($erroredFiles, 1); - } - - private function displayJson(SymfonyStyle $io, array $filesInfo): int - { - $errors = 0; - - array_walk($filesInfo, function (&$v) use (&$errors) { - $v['file'] = (string) $v['file']; - if (!$v['valid']) { - ++$errors; - } - - if (isset($v['message']) && false !== strpos($v['message'], 'PARSE_CUSTOM_TAGS')) { - $v['message'] .= ' Use the --parse-tags option if you want parse custom tags.'; - } - }); - - $io->writeln(json_encode($filesInfo, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES)); - - return min($errors, 1); - } - - private function getFiles(string $fileOrDirectory): iterable - { - if (is_file($fileOrDirectory)) { - yield new \SplFileInfo($fileOrDirectory); - - return; - } - - foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) { - if (!\in_array($file->getExtension(), ['yml', 'yaml'])) { - continue; - } - - yield $file; - } - } - - private function getParser(): Parser - { - if (!$this->parser) { - $this->parser = new Parser(); - } - - return $this->parser; - } - - private function getDirectoryIterator(string $directory): iterable - { - $default = function ($directory) { - return new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS), - \RecursiveIteratorIterator::LEAVES_ONLY - ); - }; - - if (null !== $this->directoryIteratorProvider) { - return ($this->directoryIteratorProvider)($directory, $default); - } - - return $default($directory); - } - - private function isReadable(string $fileOrDirectory): bool - { - $default = function ($fileOrDirectory) { - return is_readable($fileOrDirectory); - }; - - if (null !== $this->isReadableProvider) { - return ($this->isReadableProvider)($fileOrDirectory, $default); - } - - return $default($fileOrDirectory); - } - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - if ($input->mustSuggestOptionValuesFor('format')) { - $suggestions->suggestValues(['txt', 'json', 'github']); - } - } -} diff --git a/vendor/symfony/yaml/Dumper.php b/vendor/symfony/yaml/Dumper.php deleted file mode 100644 index db3e346b1..000000000 --- a/vendor/symfony/yaml/Dumper.php +++ /dev/null @@ -1,140 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml; - -use Symfony\Component\Yaml\Tag\TaggedValue; - -/** - * Dumper dumps PHP variables to YAML strings. - * - * @author Fabien Potencier - * - * @final - */ -class Dumper -{ - /** - * The amount of spaces to use for indentation of nested nodes. - * - * @var int - */ - protected $indentation; - - public function __construct(int $indentation = 4) - { - if ($indentation < 1) { - throw new \InvalidArgumentException('The indentation must be greater than zero.'); - } - - $this->indentation = $indentation; - } - - /** - * Dumps a PHP value to YAML. - * - * @param mixed $input The PHP value - * @param int $inline The level where you switch to inline YAML - * @param int $indent The level of indentation (used internally) - * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string - */ - public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): string - { - $output = ''; - $prefix = $indent ? str_repeat(' ', $indent) : ''; - $dumpObjectAsInlineMap = true; - - if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($input instanceof \ArrayObject || $input instanceof \stdClass)) { - $dumpObjectAsInlineMap = empty((array) $input); - } - - if ($inline <= 0 || (!\is_array($input) && !$input instanceof TaggedValue && $dumpObjectAsInlineMap) || empty($input)) { - $output .= $prefix.Inline::dump($input, $flags); - } else { - $dumpAsMap = Inline::isHash($input); - - foreach ($input as $key => $value) { - if ('' !== $output && "\n" !== $output[-1]) { - $output .= "\n"; - } - - if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r")) { - // If the first line starts with a space character, the spec requires a blockIndicationIndicator - // http://www.yaml.org/spec/1.2/spec.html#id2793979 - $blockIndentationIndicator = (' ' === substr($value, 0, 1)) ? (string) $this->indentation : ''; - - if (isset($value[-2]) && "\n" === $value[-2] && "\n" === $value[-1]) { - $blockChompingIndicator = '+'; - } elseif ("\n" === $value[-1]) { - $blockChompingIndicator = ''; - } else { - $blockChompingIndicator = '-'; - } - - $output .= sprintf('%s%s%s |%s%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '', $blockIndentationIndicator, $blockChompingIndicator); - - foreach (explode("\n", $value) as $row) { - if ('' === $row) { - $output .= "\n"; - } else { - $output .= sprintf("\n%s%s%s", $prefix, str_repeat(' ', $this->indentation), $row); - } - } - - continue; - } - - if ($value instanceof TaggedValue) { - $output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag()); - - if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) { - // If the first line starts with a space character, the spec requires a blockIndicationIndicator - // http://www.yaml.org/spec/1.2/spec.html#id2793979 - $blockIndentationIndicator = (' ' === substr($value->getValue(), 0, 1)) ? (string) $this->indentation : ''; - $output .= sprintf(' |%s', $blockIndentationIndicator); - - foreach (explode("\n", $value->getValue()) as $row) { - $output .= sprintf("\n%s%s%s", $prefix, str_repeat(' ', $this->indentation), $row); - } - - continue; - } - - if ($inline - 1 <= 0 || null === $value->getValue() || is_scalar($value->getValue())) { - $output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n"; - } else { - $output .= "\n"; - $output .= $this->dump($value->getValue(), $inline - 1, $dumpAsMap ? $indent + $this->indentation : $indent + 2, $flags); - } - - continue; - } - - $dumpObjectAsInlineMap = true; - - if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) { - $dumpObjectAsInlineMap = empty((array) $value); - } - - $willBeInlined = $inline - 1 <= 0 || !\is_array($value) && $dumpObjectAsInlineMap || empty($value); - - $output .= sprintf('%s%s%s%s', - $prefix, - $dumpAsMap ? Inline::dump($key, $flags).':' : '-', - $willBeInlined ? ' ' : "\n", - $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $flags) - ).($willBeInlined ? "\n" : ''); - } - } - - return $output; - } -} diff --git a/vendor/symfony/yaml/Escaper.php b/vendor/symfony/yaml/Escaper.php deleted file mode 100644 index e8090d8c6..000000000 --- a/vendor/symfony/yaml/Escaper.php +++ /dev/null @@ -1,95 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml; - -/** - * Escaper encapsulates escaping rules for single and double-quoted - * YAML strings. - * - * @author Matthew Lewinski - * - * @internal - */ -class Escaper -{ - // Characters that would cause a dumped string to require double quoting. - public const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\x7f|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9"; - - // Mapping arrays for escaping a double quoted string. The backslash is - // first to ensure proper escaping because str_replace operates iteratively - // on the input arrays. This ordering of the characters avoids the use of strtr, - // which performs more slowly. - private const ESCAPEES = ['\\', '\\\\', '\\"', '"', - "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", - "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f", - "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", - "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f", - "\x7f", - "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9", - ]; - private const ESCAPED = ['\\\\', '\\"', '\\\\', '\\"', - '\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a', - '\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f', - '\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17', - '\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f', - '\\x7f', - '\\N', '\\_', '\\L', '\\P', - ]; - - /** - * Determines if a PHP value would require double quoting in YAML. - * - * @param string $value A PHP value - */ - public static function requiresDoubleQuoting(string $value): bool - { - return 0 < preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value); - } - - /** - * Escapes and surrounds a PHP value with double quotes. - * - * @param string $value A PHP value - */ - public static function escapeWithDoubleQuotes(string $value): string - { - return sprintf('"%s"', str_replace(self::ESCAPEES, self::ESCAPED, $value)); - } - - /** - * Determines if a PHP value would require single quoting in YAML. - * - * @param string $value A PHP value - */ - public static function requiresSingleQuoting(string $value): bool - { - // Determines if a PHP value is entirely composed of a value that would - // require single quoting in YAML. - if (\in_array(strtolower($value), ['null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'])) { - return true; - } - - // Determines if the PHP value contains any single characters that would - // cause it to require single quoting in YAML. - return 0 < preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` \p{Zs}]/xu', $value); - } - - /** - * Escapes and surrounds a PHP value with single quotes. - * - * @param string $value A PHP value - */ - public static function escapeWithSingleQuotes(string $value): string - { - return sprintf("'%s'", str_replace('\'', '\'\'', $value)); - } -} diff --git a/vendor/symfony/yaml/Exception/DumpException.php b/vendor/symfony/yaml/Exception/DumpException.php deleted file mode 100644 index cce972f24..000000000 --- a/vendor/symfony/yaml/Exception/DumpException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml\Exception; - -/** - * Exception class thrown when an error occurs during dumping. - * - * @author Fabien Potencier - */ -class DumpException extends RuntimeException -{ -} diff --git a/vendor/symfony/yaml/Exception/ExceptionInterface.php b/vendor/symfony/yaml/Exception/ExceptionInterface.php deleted file mode 100644 index 909131684..000000000 --- a/vendor/symfony/yaml/Exception/ExceptionInterface.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml\Exception; - -/** - * Exception interface for all exceptions thrown by the component. - * - * @author Fabien Potencier - */ -interface ExceptionInterface extends \Throwable -{ -} diff --git a/vendor/symfony/yaml/Exception/ParseException.php b/vendor/symfony/yaml/Exception/ParseException.php deleted file mode 100644 index 8748d2b22..000000000 --- a/vendor/symfony/yaml/Exception/ParseException.php +++ /dev/null @@ -1,132 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml\Exception; - -/** - * Exception class thrown when an error occurs during parsing. - * - * @author Fabien Potencier - */ -class ParseException extends RuntimeException -{ - private $parsedFile; - private $parsedLine; - private $snippet; - private $rawMessage; - - /** - * @param string $message The error message - * @param int $parsedLine The line where the error occurred - * @param string|null $snippet The snippet of code near the problem - * @param string|null $parsedFile The file name where the error occurred - */ - public function __construct(string $message, int $parsedLine = -1, string $snippet = null, string $parsedFile = null, \Throwable $previous = null) - { - $this->parsedFile = $parsedFile; - $this->parsedLine = $parsedLine; - $this->snippet = $snippet; - $this->rawMessage = $message; - - $this->updateRepr(); - - parent::__construct($this->message, 0, $previous); - } - - /** - * Gets the snippet of code near the error. - * - * @return string - */ - public function getSnippet() - { - return $this->snippet; - } - - /** - * Sets the snippet of code near the error. - */ - public function setSnippet(string $snippet) - { - $this->snippet = $snippet; - - $this->updateRepr(); - } - - /** - * Gets the filename where the error occurred. - * - * This method returns null if a string is parsed. - * - * @return string - */ - public function getParsedFile() - { - return $this->parsedFile; - } - - /** - * Sets the filename where the error occurred. - */ - public function setParsedFile(string $parsedFile) - { - $this->parsedFile = $parsedFile; - - $this->updateRepr(); - } - - /** - * Gets the line where the error occurred. - * - * @return int - */ - public function getParsedLine() - { - return $this->parsedLine; - } - - /** - * Sets the line where the error occurred. - */ - public function setParsedLine(int $parsedLine) - { - $this->parsedLine = $parsedLine; - - $this->updateRepr(); - } - - private function updateRepr() - { - $this->message = $this->rawMessage; - - $dot = false; - if ('.' === substr($this->message, -1)) { - $this->message = substr($this->message, 0, -1); - $dot = true; - } - - if (null !== $this->parsedFile) { - $this->message .= sprintf(' in %s', json_encode($this->parsedFile, \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE)); - } - - if ($this->parsedLine >= 0) { - $this->message .= sprintf(' at line %d', $this->parsedLine); - } - - if ($this->snippet) { - $this->message .= sprintf(' (near "%s")', $this->snippet); - } - - if ($dot) { - $this->message .= '.'; - } - } -} diff --git a/vendor/symfony/yaml/Exception/RuntimeException.php b/vendor/symfony/yaml/Exception/RuntimeException.php deleted file mode 100644 index 3f36b73be..000000000 --- a/vendor/symfony/yaml/Exception/RuntimeException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml\Exception; - -/** - * Exception class thrown when an error occurs during parsing. - * - * @author Romain Neutron - */ -class RuntimeException extends \RuntimeException implements ExceptionInterface -{ -} diff --git a/vendor/symfony/yaml/Inline.php b/vendor/symfony/yaml/Inline.php deleted file mode 100644 index 3d64b1ada..000000000 --- a/vendor/symfony/yaml/Inline.php +++ /dev/null @@ -1,812 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml; - -use Symfony\Component\Yaml\Exception\DumpException; -use Symfony\Component\Yaml\Exception\ParseException; -use Symfony\Component\Yaml\Tag\TaggedValue; - -/** - * Inline implements a YAML parser/dumper for the YAML inline syntax. - * - * @author Fabien Potencier - * - * @internal - */ -class Inline -{ - public const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+)"|\'([^\']*+(?:\'\'[^\']*+)*+)\')'; - - public static $parsedLineNumber = -1; - public static $parsedFilename; - - private static $exceptionOnInvalidType = false; - private static $objectSupport = false; - private static $objectForMap = false; - private static $constantSupport = false; - - public static function initialize(int $flags, int $parsedLineNumber = null, string $parsedFilename = null) - { - self::$exceptionOnInvalidType = (bool) (Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE & $flags); - self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags); - self::$objectForMap = (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags); - self::$constantSupport = (bool) (Yaml::PARSE_CONSTANT & $flags); - self::$parsedFilename = $parsedFilename; - - if (null !== $parsedLineNumber) { - self::$parsedLineNumber = $parsedLineNumber; - } - } - - /** - * Converts a YAML string to a PHP value. - * - * @param string $value A YAML string - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior - * @param array $references Mapping of variable names to values - * - * @return mixed - * - * @throws ParseException - */ - public static function parse(string $value = null, int $flags = 0, array &$references = []) - { - self::initialize($flags); - - $value = trim($value); - - if ('' === $value) { - return ''; - } - - if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { - $mbEncoding = mb_internal_encoding(); - mb_internal_encoding('ASCII'); - } - - try { - $i = 0; - $tag = self::parseTag($value, $i, $flags); - switch ($value[$i]) { - case '[': - $result = self::parseSequence($value, $flags, $i, $references); - ++$i; - break; - case '{': - $result = self::parseMapping($value, $flags, $i, $references); - ++$i; - break; - default: - $result = self::parseScalar($value, $flags, null, $i, null === $tag, $references); - } - - // some comments are allowed at the end - if (preg_replace('/\s*#.*$/A', '', substr($value, $i))) { - throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)), self::$parsedLineNumber + 1, $value, self::$parsedFilename); - } - - if (null !== $tag && '' !== $tag) { - return new TaggedValue($tag, $result); - } - - return $result; - } finally { - if (isset($mbEncoding)) { - mb_internal_encoding($mbEncoding); - } - } - } - - /** - * Dumps a given PHP variable to a YAML string. - * - * @param mixed $value The PHP variable to convert - * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string - * - * @throws DumpException When trying to dump PHP resource - */ - public static function dump($value, int $flags = 0): string - { - switch (true) { - case \is_resource($value): - if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) { - throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value))); - } - - return self::dumpNull($flags); - case $value instanceof \DateTimeInterface: - return $value->format('c'); - case $value instanceof \UnitEnum: - return sprintf('!php/const %s::%s', \get_class($value), $value->name); - case \is_object($value): - if ($value instanceof TaggedValue) { - return '!'.$value->getTag().' '.self::dump($value->getValue(), $flags); - } - - if (Yaml::DUMP_OBJECT & $flags) { - return '!php/object '.self::dump(serialize($value)); - } - - if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \stdClass || $value instanceof \ArrayObject)) { - $output = []; - - foreach ($value as $key => $val) { - $output[] = sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags)); - } - - return sprintf('{ %s }', implode(', ', $output)); - } - - if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) { - throw new DumpException('Object support when dumping a YAML file has been disabled.'); - } - - return self::dumpNull($flags); - case \is_array($value): - return self::dumpArray($value, $flags); - case null === $value: - return self::dumpNull($flags); - case true === $value: - return 'true'; - case false === $value: - return 'false'; - case \is_int($value): - return $value; - case is_numeric($value) && false === strpbrk($value, "\f\n\r\t\v"): - $locale = setlocale(\LC_NUMERIC, 0); - if (false !== $locale) { - setlocale(\LC_NUMERIC, 'C'); - } - if (\is_float($value)) { - $repr = (string) $value; - if (is_infinite($value)) { - $repr = str_ireplace('INF', '.Inf', $repr); - } elseif (floor($value) == $value && $repr == $value) { - // Preserve float data type since storing a whole number will result in integer value. - if (false === strpos($repr, 'E')) { - $repr = $repr.'.0'; - } - } - } else { - $repr = \is_string($value) ? "'$value'" : (string) $value; - } - if (false !== $locale) { - setlocale(\LC_NUMERIC, $locale); - } - - return $repr; - case '' == $value: - return "''"; - case self::isBinaryString($value): - return '!!binary '.base64_encode($value); - case Escaper::requiresDoubleQuoting($value): - return Escaper::escapeWithDoubleQuotes($value); - case Escaper::requiresSingleQuoting($value): - case Parser::preg_match('{^[0-9]+[_0-9]*$}', $value): - case Parser::preg_match(self::getHexRegex(), $value): - case Parser::preg_match(self::getTimestampRegex(), $value): - return Escaper::escapeWithSingleQuotes($value); - default: - return $value; - } - } - - /** - * Check if given array is hash or just normal indexed array. - * - * @param array|\ArrayObject|\stdClass $value The PHP array or array-like object to check - */ - public static function isHash($value): bool - { - if ($value instanceof \stdClass || $value instanceof \ArrayObject) { - return true; - } - - $expectedKey = 0; - - foreach ($value as $key => $val) { - if ($key !== $expectedKey++) { - return true; - } - } - - return false; - } - - /** - * Dumps a PHP array to a YAML string. - * - * @param array $value The PHP array to dump - * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string - */ - private static function dumpArray(array $value, int $flags): string - { - // array - if (($value || Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE & $flags) && !self::isHash($value)) { - $output = []; - foreach ($value as $val) { - $output[] = self::dump($val, $flags); - } - - return sprintf('[%s]', implode(', ', $output)); - } - - // hash - $output = []; - foreach ($value as $key => $val) { - $output[] = sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags)); - } - - return sprintf('{ %s }', implode(', ', $output)); - } - - private static function dumpNull(int $flags): string - { - if (Yaml::DUMP_NULL_AS_TILDE & $flags) { - return '~'; - } - - return 'null'; - } - - /** - * Parses a YAML scalar. - * - * @return mixed - * - * @throws ParseException When malformed inline YAML string is parsed - */ - public static function parseScalar(string $scalar, int $flags = 0, array $delimiters = null, int &$i = 0, bool $evaluate = true, array &$references = [], bool &$isQuoted = null) - { - if (\in_array($scalar[$i], ['"', "'"], true)) { - // quoted scalar - $isQuoted = true; - $output = self::parseQuotedScalar($scalar, $i); - - if (null !== $delimiters) { - $tmp = ltrim(substr($scalar, $i), " \n"); - if ('' === $tmp) { - throw new ParseException(sprintf('Unexpected end of line, expected one of "%s".', implode('', $delimiters)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); - } - if (!\in_array($tmp[0], $delimiters)) { - throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); - } - } - } else { - // "normal" string - $isQuoted = false; - - if (!$delimiters) { - $output = substr($scalar, $i); - $i += \strlen($output); - - // remove comments - if (Parser::preg_match('/[ \t]+#/', $output, $match, \PREG_OFFSET_CAPTURE)) { - $output = substr($output, 0, $match[0][1]); - } - } elseif (Parser::preg_match('/^(.*?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) { - $output = $match[1]; - $i += \strlen($output); - $output = trim($output); - } else { - throw new ParseException(sprintf('Malformed inline YAML string: "%s".', $scalar), self::$parsedLineNumber + 1, null, self::$parsedFilename); - } - - // a non-quoted string cannot start with @ or ` (reserved) nor with a scalar indicator (| or >) - if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0] || '%' === $output[0])) { - throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0]), self::$parsedLineNumber + 1, $output, self::$parsedFilename); - } - - if ($evaluate) { - $output = self::evaluateScalar($output, $flags, $references, $isQuoted); - } - } - - return $output; - } - - /** - * Parses a YAML quoted scalar. - * - * @throws ParseException When malformed inline YAML string is parsed - */ - private static function parseQuotedScalar(string $scalar, int &$i = 0): string - { - if (!Parser::preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) { - throw new ParseException(sprintf('Malformed inline YAML string: "%s".', substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); - } - - $output = substr($match[0], 1, -1); - - $unescaper = new Unescaper(); - if ('"' == $scalar[$i]) { - $output = $unescaper->unescapeDoubleQuotedString($output); - } else { - $output = $unescaper->unescapeSingleQuotedString($output); - } - - $i += \strlen($match[0]); - - return $output; - } - - /** - * Parses a YAML sequence. - * - * @throws ParseException When malformed inline YAML string is parsed - */ - private static function parseSequence(string $sequence, int $flags, int &$i = 0, array &$references = []): array - { - $output = []; - $len = \strlen($sequence); - ++$i; - - // [foo, bar, ...] - while ($i < $len) { - if (']' === $sequence[$i]) { - return $output; - } - if (',' === $sequence[$i] || ' ' === $sequence[$i]) { - ++$i; - - continue; - } - - $tag = self::parseTag($sequence, $i, $flags); - switch ($sequence[$i]) { - case '[': - // nested sequence - $value = self::parseSequence($sequence, $flags, $i, $references); - break; - case '{': - // nested mapping - $value = self::parseMapping($sequence, $flags, $i, $references); - break; - default: - $value = self::parseScalar($sequence, $flags, [',', ']'], $i, null === $tag, $references, $isQuoted); - - // the value can be an array if a reference has been resolved to an array var - if (\is_string($value) && !$isQuoted && false !== strpos($value, ': ')) { - // embedded mapping? - try { - $pos = 0; - $value = self::parseMapping('{'.$value.'}', $flags, $pos, $references); - } catch (\InvalidArgumentException $e) { - // no, it's not - } - } - - if (!$isQuoted && \is_string($value) && '' !== $value && '&' === $value[0] && Parser::preg_match(Parser::REFERENCE_PATTERN, $value, $matches)) { - $references[$matches['ref']] = $matches['value']; - $value = $matches['value']; - } - - --$i; - } - - if (null !== $tag && '' !== $tag) { - $value = new TaggedValue($tag, $value); - } - - $output[] = $value; - - ++$i; - } - - throw new ParseException(sprintf('Malformed inline YAML string: "%s".', $sequence), self::$parsedLineNumber + 1, null, self::$parsedFilename); - } - - /** - * Parses a YAML mapping. - * - * @return array|\stdClass - * - * @throws ParseException When malformed inline YAML string is parsed - */ - private static function parseMapping(string $mapping, int $flags, int &$i = 0, array &$references = []) - { - $output = []; - $len = \strlen($mapping); - ++$i; - $allowOverwrite = false; - - // {foo: bar, bar:foo, ...} - while ($i < $len) { - switch ($mapping[$i]) { - case ' ': - case ',': - case "\n": - ++$i; - continue 2; - case '}': - if (self::$objectForMap) { - return (object) $output; - } - - return $output; - } - - // key - $offsetBeforeKeyParsing = $i; - $isKeyQuoted = \in_array($mapping[$i], ['"', "'"], true); - $key = self::parseScalar($mapping, $flags, [':', ' '], $i, false); - - if ($offsetBeforeKeyParsing === $i) { - throw new ParseException('Missing mapping key.', self::$parsedLineNumber + 1, $mapping); - } - - if ('!php/const' === $key) { - $key .= ' '.self::parseScalar($mapping, $flags, [':'], $i, false); - $key = self::evaluateScalar($key, $flags); - } - - if (false === $i = strpos($mapping, ':', $i)) { - break; - } - - if (!$isKeyQuoted) { - $evaluatedKey = self::evaluateScalar($key, $flags, $references); - - if ('' !== $key && $evaluatedKey !== $key && !\is_string($evaluatedKey) && !\is_int($evaluatedKey)) { - throw new ParseException('Implicit casting of incompatible mapping keys to strings is not supported. Quote your evaluable mapping keys instead.', self::$parsedLineNumber + 1, $mapping); - } - } - - if (!$isKeyQuoted && (!isset($mapping[$i + 1]) || !\in_array($mapping[$i + 1], [' ', ',', '[', ']', '{', '}', "\n"], true))) { - throw new ParseException('Colons must be followed by a space or an indication character (i.e. " ", ",", "[", "]", "{", "}").', self::$parsedLineNumber + 1, $mapping); - } - - if ('<<' === $key) { - $allowOverwrite = true; - } - - while ($i < $len) { - if (':' === $mapping[$i] || ' ' === $mapping[$i] || "\n" === $mapping[$i]) { - ++$i; - - continue; - } - - $tag = self::parseTag($mapping, $i, $flags); - switch ($mapping[$i]) { - case '[': - // nested sequence - $value = self::parseSequence($mapping, $flags, $i, $references); - // Spec: Keys MUST be unique; first one wins. - // Parser cannot abort this mapping earlier, since lines - // are processed sequentially. - // But overwriting is allowed when a merge node is used in current block. - if ('<<' === $key) { - foreach ($value as $parsedValue) { - $output += $parsedValue; - } - } elseif ($allowOverwrite || !isset($output[$key])) { - if (null !== $tag) { - $output[$key] = new TaggedValue($tag, $value); - } else { - $output[$key] = $value; - } - } elseif (isset($output[$key])) { - throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping); - } - break; - case '{': - // nested mapping - $value = self::parseMapping($mapping, $flags, $i, $references); - // Spec: Keys MUST be unique; first one wins. - // Parser cannot abort this mapping earlier, since lines - // are processed sequentially. - // But overwriting is allowed when a merge node is used in current block. - if ('<<' === $key) { - $output += $value; - } elseif ($allowOverwrite || !isset($output[$key])) { - if (null !== $tag) { - $output[$key] = new TaggedValue($tag, $value); - } else { - $output[$key] = $value; - } - } elseif (isset($output[$key])) { - throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping); - } - break; - default: - $value = self::parseScalar($mapping, $flags, [',', '}', "\n"], $i, null === $tag, $references, $isValueQuoted); - // Spec: Keys MUST be unique; first one wins. - // Parser cannot abort this mapping earlier, since lines - // are processed sequentially. - // But overwriting is allowed when a merge node is used in current block. - if ('<<' === $key) { - $output += $value; - } elseif ($allowOverwrite || !isset($output[$key])) { - if (!$isValueQuoted && \is_string($value) && '' !== $value && '&' === $value[0] && Parser::preg_match(Parser::REFERENCE_PATTERN, $value, $matches)) { - $references[$matches['ref']] = $matches['value']; - $value = $matches['value']; - } - - if (null !== $tag) { - $output[$key] = new TaggedValue($tag, $value); - } else { - $output[$key] = $value; - } - } elseif (isset($output[$key])) { - throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping); - } - --$i; - } - ++$i; - - continue 2; - } - } - - throw new ParseException(sprintf('Malformed inline YAML string: "%s".', $mapping), self::$parsedLineNumber + 1, null, self::$parsedFilename); - } - - /** - * Evaluates scalars and replaces magic values. - * - * @return mixed - * - * @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved - */ - private static function evaluateScalar(string $scalar, int $flags, array &$references = [], bool &$isQuotedString = null) - { - $isQuotedString = false; - $scalar = trim($scalar); - - if (0 === strpos($scalar, '*')) { - if (false !== $pos = strpos($scalar, '#')) { - $value = substr($scalar, 1, $pos - 2); - } else { - $value = substr($scalar, 1); - } - - // an unquoted * - if (false === $value || '' === $value) { - throw new ParseException('A reference must contain at least one character.', self::$parsedLineNumber + 1, $value, self::$parsedFilename); - } - - if (!\array_key_exists($value, $references)) { - throw new ParseException(sprintf('Reference "%s" does not exist.', $value), self::$parsedLineNumber + 1, $value, self::$parsedFilename); - } - - return $references[$value]; - } - - $scalarLower = strtolower($scalar); - - switch (true) { - case 'null' === $scalarLower: - case '' === $scalar: - case '~' === $scalar: - return null; - case 'true' === $scalarLower: - return true; - case 'false' === $scalarLower: - return false; - case '!' === $scalar[0]: - switch (true) { - case 0 === strpos($scalar, '!!str '): - $s = (string) substr($scalar, 6); - - if (\in_array($s[0] ?? '', ['"', "'"], true)) { - $isQuotedString = true; - $s = self::parseQuotedScalar($s); - } - - return $s; - case 0 === strpos($scalar, '! '): - return substr($scalar, 2); - case 0 === strpos($scalar, '!php/object'): - if (self::$objectSupport) { - if (!isset($scalar[12])) { - trigger_deprecation('symfony/yaml', '5.1', 'Using the !php/object tag without a value is deprecated.'); - - return false; - } - - return unserialize(self::parseScalar(substr($scalar, 12))); - } - - if (self::$exceptionOnInvalidType) { - throw new ParseException('Object support when parsing a YAML file has been disabled.', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); - } - - return null; - case 0 === strpos($scalar, '!php/const'): - if (self::$constantSupport) { - if (!isset($scalar[11])) { - trigger_deprecation('symfony/yaml', '5.1', 'Using the !php/const tag without a value is deprecated.'); - - return ''; - } - - $i = 0; - if (\defined($const = self::parseScalar(substr($scalar, 11), 0, null, $i, false))) { - return \constant($const); - } - - throw new ParseException(sprintf('The constant "%s" is not defined.', $const), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); - } - if (self::$exceptionOnInvalidType) { - throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Did you forget to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); - } - - return null; - case 0 === strpos($scalar, '!!float '): - return (float) substr($scalar, 8); - case 0 === strpos($scalar, '!!binary '): - return self::evaluateBinaryScalar(substr($scalar, 9)); - } - - throw new ParseException(sprintf('The string "%s" could not be parsed as it uses an unsupported built-in tag.', $scalar), self::$parsedLineNumber, $scalar, self::$parsedFilename); - case preg_match('/^(?:\+|-)?0o(?P[0-7_]++)$/', $scalar, $matches): - $value = str_replace('_', '', $matches['value']); - - if ('-' === $scalar[0]) { - return -octdec($value); - } - - return octdec($value); - // Optimize for returning strings. - case \in_array($scalar[0], ['+', '-', '.'], true) || is_numeric($scalar[0]): - if (Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar)) { - $scalar = str_replace('_', '', $scalar); - } - - switch (true) { - case ctype_digit($scalar): - if (preg_match('/^0[0-7]+$/', $scalar)) { - trigger_deprecation('symfony/yaml', '5.1', 'Support for parsing numbers prefixed with 0 as octal numbers. They will be parsed as strings as of 6.0. Use "%s" to represent the octal number.', '0o'.substr($scalar, 1)); - - return octdec($scalar); - } - - $cast = (int) $scalar; - - return ($scalar === (string) $cast) ? $cast : $scalar; - case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)): - if (preg_match('/^-0[0-7]+$/', $scalar)) { - trigger_deprecation('symfony/yaml', '5.1', 'Support for parsing numbers prefixed with 0 as octal numbers. They will be parsed as strings as of 6.0. Use "%s" to represent the octal number.', '-0o'.substr($scalar, 2)); - - return -octdec(substr($scalar, 1)); - } - - $cast = (int) $scalar; - - return ($scalar === (string) $cast) ? $cast : $scalar; - case is_numeric($scalar): - case Parser::preg_match(self::getHexRegex(), $scalar): - $scalar = str_replace('_', '', $scalar); - - return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar; - case '.inf' === $scalarLower: - case '.nan' === $scalarLower: - return -log(0); - case '-.inf' === $scalarLower: - return log(0); - case Parser::preg_match('/^(-|\+)?[0-9][0-9_]*(\.[0-9_]+)?$/', $scalar): - return (float) str_replace('_', '', $scalar); - case Parser::preg_match(self::getTimestampRegex(), $scalar): - // When no timezone is provided in the parsed date, YAML spec says we must assume UTC. - $time = new \DateTime($scalar, new \DateTimeZone('UTC')); - - if (Yaml::PARSE_DATETIME & $flags) { - return $time; - } - - try { - if (false !== $scalar = $time->getTimestamp()) { - return $scalar; - } - } catch (\ValueError $e) { - // no-op - } - - return $time->format('U'); - } - } - - return (string) $scalar; - } - - private static function parseTag(string $value, int &$i, int $flags): ?string - { - if ('!' !== $value[$i]) { - return null; - } - - $tagLength = strcspn($value, " \t\n[]{},", $i + 1); - $tag = substr($value, $i + 1, $tagLength); - - $nextOffset = $i + $tagLength + 1; - $nextOffset += strspn($value, ' ', $nextOffset); - - if ('' === $tag && (!isset($value[$nextOffset]) || \in_array($value[$nextOffset], [']', '}', ','], true))) { - throw new ParseException('Using the unquoted scalar value "!" is not supported. You must quote it.', self::$parsedLineNumber + 1, $value, self::$parsedFilename); - } - - // Is followed by a scalar and is a built-in tag - if ('' !== $tag && (!isset($value[$nextOffset]) || !\in_array($value[$nextOffset], ['[', '{'], true)) && ('!' === $tag[0] || 'str' === $tag || 'php/const' === $tag || 'php/object' === $tag)) { - // Manage in {@link self::evaluateScalar()} - return null; - } - - $i = $nextOffset; - - // Built-in tags - if ('' !== $tag && '!' === $tag[0]) { - throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename); - } - - if ('' !== $tag && !isset($value[$i])) { - throw new ParseException(sprintf('Missing value for tag "%s".', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename); - } - - if ('' === $tag || Yaml::PARSE_CUSTOM_TAGS & $flags) { - return $tag; - } - - throw new ParseException(sprintf('Tags support is not enabled. Enable the "Yaml::PARSE_CUSTOM_TAGS" flag to use "!%s".', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename); - } - - public static function evaluateBinaryScalar(string $scalar): string - { - $parsedBinaryData = self::parseScalar(preg_replace('/\s/', '', $scalar)); - - if (0 !== (\strlen($parsedBinaryData) % 4)) { - throw new ParseException(sprintf('The normalized base64 encoded data (data without whitespace characters) length must be a multiple of four (%d bytes given).', \strlen($parsedBinaryData)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); - } - - if (!Parser::preg_match('#^[A-Z0-9+/]+={0,2}$#i', $parsedBinaryData)) { - throw new ParseException(sprintf('The base64 encoded data (%s) contains invalid characters.', $parsedBinaryData), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); - } - - return base64_decode($parsedBinaryData, true); - } - - private static function isBinaryString(string $value): bool - { - return !preg_match('//u', $value) || preg_match('/[^\x00\x07-\x0d\x1B\x20-\xff]/', $value); - } - - /** - * Gets a regex that matches a YAML date. - * - * @see http://www.yaml.org/spec/1.2/spec.html#id2761573 - */ - private static function getTimestampRegex(): string - { - return <<[0-9][0-9][0-9][0-9]) - -(?P[0-9][0-9]?) - -(?P[0-9][0-9]?) - (?:(?:[Tt]|[ \t]+) - (?P[0-9][0-9]?) - :(?P[0-9][0-9]) - :(?P[0-9][0-9]) - (?:\.(?P[0-9]*))? - (?:[ \t]*(?PZ|(?P[-+])(?P[0-9][0-9]?) - (?::(?P[0-9][0-9]))?))?)? - $~x -EOF; - } - - /** - * Gets a regex that matches a YAML number in hexadecimal notation. - */ - private static function getHexRegex(): string - { - return '~^0x[0-9a-f_]++$~i'; - } -} diff --git a/vendor/symfony/yaml/Parser.php b/vendor/symfony/yaml/Parser.php deleted file mode 100644 index 2701a4418..000000000 --- a/vendor/symfony/yaml/Parser.php +++ /dev/null @@ -1,1305 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml; - -use Symfony\Component\Yaml\Exception\ParseException; -use Symfony\Component\Yaml\Tag\TaggedValue; - -/** - * Parser parses YAML strings to convert them to PHP arrays. - * - * @author Fabien Potencier - * - * @final - */ -class Parser -{ - public const TAG_PATTERN = '(?P![\w!.\/:-]+)'; - public const BLOCK_SCALAR_HEADER_PATTERN = '(?P\||>)(?P\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P +#.*)?'; - public const REFERENCE_PATTERN = '#^&(?P[^ ]++) *+(?P.*)#u'; - - private $filename; - private $offset = 0; - private $numberOfParsedLines = 0; - private $totalNumberOfLines; - private $lines = []; - private $currentLineNb = -1; - private $currentLine = ''; - private $refs = []; - private $skippedLineNumbers = []; - private $locallySkippedLineNumbers = []; - private $refsBeingParsed = []; - - /** - * Parses a YAML file into a PHP value. - * - * @param string $filename The path to the YAML file to be parsed - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior - * - * @return mixed - * - * @throws ParseException If the file could not be read or the YAML is not valid - */ - public function parseFile(string $filename, int $flags = 0) - { - if (!is_file($filename)) { - throw new ParseException(sprintf('File "%s" does not exist.', $filename)); - } - - if (!is_readable($filename)) { - throw new ParseException(sprintf('File "%s" cannot be read.', $filename)); - } - - $this->filename = $filename; - - try { - return $this->parse(file_get_contents($filename), $flags); - } finally { - $this->filename = null; - } - } - - /** - * Parses a YAML string to a PHP value. - * - * @param string $value A YAML string - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior - * - * @return mixed - * - * @throws ParseException If the YAML is not valid - */ - public function parse(string $value, int $flags = 0) - { - if (false === preg_match('//u', $value)) { - throw new ParseException('The YAML value does not appear to be valid UTF-8.', -1, null, $this->filename); - } - - $this->refs = []; - - $mbEncoding = null; - - if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { - $mbEncoding = mb_internal_encoding(); - mb_internal_encoding('UTF-8'); - } - - try { - $data = $this->doParse($value, $flags); - } finally { - if (null !== $mbEncoding) { - mb_internal_encoding($mbEncoding); - } - $this->refsBeingParsed = []; - $this->offset = 0; - $this->lines = []; - $this->currentLine = ''; - $this->numberOfParsedLines = 0; - $this->refs = []; - $this->skippedLineNumbers = []; - $this->locallySkippedLineNumbers = []; - $this->totalNumberOfLines = null; - } - - return $data; - } - - private function doParse(string $value, int $flags) - { - $this->currentLineNb = -1; - $this->currentLine = ''; - $value = $this->cleanup($value); - $this->lines = explode("\n", $value); - $this->numberOfParsedLines = \count($this->lines); - $this->locallySkippedLineNumbers = []; - - if (null === $this->totalNumberOfLines) { - $this->totalNumberOfLines = $this->numberOfParsedLines; - } - - if (!$this->moveToNextLine()) { - return null; - } - - $data = []; - $context = null; - $allowOverwrite = false; - - while ($this->isCurrentLineEmpty()) { - if (!$this->moveToNextLine()) { - return null; - } - } - - // Resolves the tag and returns if end of the document - if (null !== ($tag = $this->getLineTag($this->currentLine, $flags, false)) && !$this->moveToNextLine()) { - return new TaggedValue($tag, ''); - } - - do { - if ($this->isCurrentLineEmpty()) { - continue; - } - - // tab? - if ("\t" === $this->currentLine[0]) { - throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - - Inline::initialize($flags, $this->getRealCurrentLineNb(), $this->filename); - - $isRef = $mergeNode = false; - if ('-' === $this->currentLine[0] && self::preg_match('#^\-((?P\s+)(?P.+))?$#u', rtrim($this->currentLine), $values)) { - if ($context && 'mapping' == $context) { - throw new ParseException('You cannot define a sequence item when in a mapping.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - $context = 'sequence'; - - if (isset($values['value']) && '&' === $values['value'][0] && self::preg_match(self::REFERENCE_PATTERN, $values['value'], $matches)) { - $isRef = $matches['ref']; - $this->refsBeingParsed[] = $isRef; - $values['value'] = $matches['value']; - } - - if (isset($values['value'][1]) && '?' === $values['value'][0] && ' ' === $values['value'][1]) { - throw new ParseException('Complex mappings are not supported.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - - // array - if (isset($values['value']) && 0 === strpos(ltrim($values['value'], ' '), '-')) { - // Inline first child - $currentLineNumber = $this->getRealCurrentLineNb(); - - $sequenceIndentation = \strlen($values['leadspaces']) + 1; - $sequenceYaml = substr($this->currentLine, $sequenceIndentation); - $sequenceYaml .= "\n".$this->getNextEmbedBlock($sequenceIndentation, true); - - $data[] = $this->parseBlock($currentLineNumber, rtrim($sequenceYaml), $flags); - } elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { - $data[] = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true) ?? '', $flags); - } elseif (null !== $subTag = $this->getLineTag(ltrim($values['value'], ' '), $flags)) { - $data[] = new TaggedValue( - $subTag, - $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $flags) - ); - } else { - if ( - isset($values['leadspaces']) - && ( - '!' === $values['value'][0] - || self::preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P.+?))?\s*$#u', $this->trimTag($values['value']), $matches) - ) - ) { - // this is a compact notation element, add to next block and parse - $block = $values['value']; - if ($this->isNextLineIndented()) { - $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + \strlen($values['leadspaces']) + 1); - } - - $data[] = $this->parseBlock($this->getRealCurrentLineNb(), $block, $flags); - } else { - $data[] = $this->parseValue($values['value'], $flags, $context); - } - } - if ($isRef) { - $this->refs[$isRef] = end($data); - array_pop($this->refsBeingParsed); - } - } elseif ( - self::preg_match('#^(?P(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:(( |\t)++(?P.+))?$#u', rtrim($this->currentLine), $values) - && (false === strpos($values['key'], ' #') || \in_array($values['key'][0], ['"', "'"])) - ) { - if ($context && 'sequence' == $context) { - throw new ParseException('You cannot define a mapping item when in a sequence.', $this->currentLineNb + 1, $this->currentLine, $this->filename); - } - $context = 'mapping'; - - try { - $key = Inline::parseScalar($values['key']); - } catch (ParseException $e) { - $e->setParsedLine($this->getRealCurrentLineNb() + 1); - $e->setSnippet($this->currentLine); - - throw $e; - } - - if (!\is_string($key) && !\is_int($key)) { - throw new ParseException((is_numeric($key) ? 'Numeric' : 'Non-string').' keys are not supported. Quote your evaluable mapping keys instead.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - - // Convert float keys to strings, to avoid being converted to integers by PHP - if (\is_float($key)) { - $key = (string) $key; - } - - if ('<<' === $key && (!isset($values['value']) || '&' !== $values['value'][0] || !self::preg_match('#^&(?P[^ ]+)#u', $values['value'], $refMatches))) { - $mergeNode = true; - $allowOverwrite = true; - if (isset($values['value'][0]) && '*' === $values['value'][0]) { - $refName = substr(rtrim($values['value']), 1); - if (!\array_key_exists($refName, $this->refs)) { - if (false !== $pos = array_search($refName, $this->refsBeingParsed, true)) { - throw new ParseException(sprintf('Circular reference [%s] detected for reference "%s".', implode(', ', array_merge(\array_slice($this->refsBeingParsed, $pos), [$refName])), $refName), $this->currentLineNb + 1, $this->currentLine, $this->filename); - } - - throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - - $refValue = $this->refs[$refName]; - - if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $refValue instanceof \stdClass) { - $refValue = (array) $refValue; - } - - if (!\is_array($refValue)) { - throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - - $data += $refValue; // array union - } else { - if (isset($values['value']) && '' !== $values['value']) { - $value = $values['value']; - } else { - $value = $this->getNextEmbedBlock(); - } - $parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $flags); - - if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsed instanceof \stdClass) { - $parsed = (array) $parsed; - } - - if (!\is_array($parsed)) { - throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - - if (isset($parsed[0])) { - // If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes - // and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier - // in the sequence override keys specified in later mapping nodes. - foreach ($parsed as $parsedItem) { - if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsedItem instanceof \stdClass) { - $parsedItem = (array) $parsedItem; - } - - if (!\is_array($parsedItem)) { - throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem, $this->filename); - } - - $data += $parsedItem; // array union - } - } else { - // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the - // current mapping, unless the key already exists in it. - $data += $parsed; // array union - } - } - } elseif ('<<' !== $key && isset($values['value']) && '&' === $values['value'][0] && self::preg_match(self::REFERENCE_PATTERN, $values['value'], $matches)) { - $isRef = $matches['ref']; - $this->refsBeingParsed[] = $isRef; - $values['value'] = $matches['value']; - } - - $subTag = null; - if ($mergeNode) { - // Merge keys - } elseif (!isset($values['value']) || '' === $values['value'] || 0 === strpos($values['value'], '#') || (null !== $subTag = $this->getLineTag($values['value'], $flags)) || '<<' === $key) { - // hash - // if next line is less indented or equal, then it means that the current value is null - if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) { - // Spec: Keys MUST be unique; first one wins. - // But overwriting is allowed when a merge node is used in current block. - if ($allowOverwrite || !isset($data[$key])) { - if (null !== $subTag) { - $data[$key] = new TaggedValue($subTag, ''); - } else { - $data[$key] = null; - } - } else { - throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - } else { - // remember the parsed line number here in case we need it to provide some contexts in error messages below - $realCurrentLineNbKey = $this->getRealCurrentLineNb(); - $value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags); - if ('<<' === $key) { - $this->refs[$refMatches['ref']] = $value; - - if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $value instanceof \stdClass) { - $value = (array) $value; - } - - $data += $value; - } elseif ($allowOverwrite || !isset($data[$key])) { - // Spec: Keys MUST be unique; first one wins. - // But overwriting is allowed when a merge node is used in current block. - if (null !== $subTag) { - $data[$key] = new TaggedValue($subTag, $value); - } else { - $data[$key] = $value; - } - } else { - throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), $realCurrentLineNbKey + 1, $this->currentLine); - } - } - } else { - $value = $this->parseValue(rtrim($values['value']), $flags, $context); - // Spec: Keys MUST be unique; first one wins. - // But overwriting is allowed when a merge node is used in current block. - if ($allowOverwrite || !isset($data[$key])) { - $data[$key] = $value; - } else { - throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - } - if ($isRef) { - $this->refs[$isRef] = $data[$key]; - array_pop($this->refsBeingParsed); - } - } elseif ('"' === $this->currentLine[0] || "'" === $this->currentLine[0]) { - if (null !== $context) { - throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - - try { - return Inline::parse($this->lexInlineQuotedString(), $flags, $this->refs); - } catch (ParseException $e) { - $e->setParsedLine($this->getRealCurrentLineNb() + 1); - $e->setSnippet($this->currentLine); - - throw $e; - } - } elseif ('{' === $this->currentLine[0]) { - if (null !== $context) { - throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - - try { - $parsedMapping = Inline::parse($this->lexInlineMapping(), $flags, $this->refs); - - while ($this->moveToNextLine()) { - if (!$this->isCurrentLineEmpty()) { - throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - } - - return $parsedMapping; - } catch (ParseException $e) { - $e->setParsedLine($this->getRealCurrentLineNb() + 1); - $e->setSnippet($this->currentLine); - - throw $e; - } - } elseif ('[' === $this->currentLine[0]) { - if (null !== $context) { - throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - - try { - $parsedSequence = Inline::parse($this->lexInlineSequence(), $flags, $this->refs); - - while ($this->moveToNextLine()) { - if (!$this->isCurrentLineEmpty()) { - throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - } - - return $parsedSequence; - } catch (ParseException $e) { - $e->setParsedLine($this->getRealCurrentLineNb() + 1); - $e->setSnippet($this->currentLine); - - throw $e; - } - } else { - // multiple documents are not supported - if ('---' === $this->currentLine) { - throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine, $this->filename); - } - - if ($deprecatedUsage = (isset($this->currentLine[1]) && '?' === $this->currentLine[0] && ' ' === $this->currentLine[1])) { - throw new ParseException('Complex mappings are not supported.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - - // 1-liner optionally followed by newline(s) - if (\is_string($value) && $this->lines[0] === trim($value)) { - try { - $value = Inline::parse($this->lines[0], $flags, $this->refs); - } catch (ParseException $e) { - $e->setParsedLine($this->getRealCurrentLineNb() + 1); - $e->setSnippet($this->currentLine); - - throw $e; - } - - return $value; - } - - // try to parse the value as a multi-line string as a last resort - if (0 === $this->currentLineNb) { - $previousLineWasNewline = false; - $previousLineWasTerminatedWithBackslash = false; - $value = ''; - - foreach ($this->lines as $line) { - $trimmedLine = trim($line); - if ('#' === ($trimmedLine[0] ?? '')) { - continue; - } - // If the indentation is not consistent at offset 0, it is to be considered as a ParseError - if (0 === $this->offset && !$deprecatedUsage && isset($line[0]) && ' ' === $line[0]) { - throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - - if (false !== strpos($line, ': ')) { - throw new ParseException('Mapping values are not allowed in multi-line blocks.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - - if ('' === $trimmedLine) { - $value .= "\n"; - } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) { - $value .= ' '; - } - - if ('' !== $trimmedLine && '\\' === substr($line, -1)) { - $value .= ltrim(substr($line, 0, -1)); - } elseif ('' !== $trimmedLine) { - $value .= $trimmedLine; - } - - if ('' === $trimmedLine) { - $previousLineWasNewline = true; - $previousLineWasTerminatedWithBackslash = false; - } elseif ('\\' === substr($line, -1)) { - $previousLineWasNewline = false; - $previousLineWasTerminatedWithBackslash = true; - } else { - $previousLineWasNewline = false; - $previousLineWasTerminatedWithBackslash = false; - } - } - - try { - return Inline::parse(trim($value)); - } catch (ParseException $e) { - // fall-through to the ParseException thrown below - } - } - - throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - } while ($this->moveToNextLine()); - - if (null !== $tag) { - $data = new TaggedValue($tag, $data); - } - - if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && 'mapping' === $context && !\is_object($data)) { - $object = new \stdClass(); - - foreach ($data as $key => $value) { - $object->$key = $value; - } - - $data = $object; - } - - return empty($data) ? null : $data; - } - - private function parseBlock(int $offset, string $yaml, int $flags) - { - $skippedLineNumbers = $this->skippedLineNumbers; - - foreach ($this->locallySkippedLineNumbers as $lineNumber) { - if ($lineNumber < $offset) { - continue; - } - - $skippedLineNumbers[] = $lineNumber; - } - - $parser = new self(); - $parser->offset = $offset; - $parser->totalNumberOfLines = $this->totalNumberOfLines; - $parser->skippedLineNumbers = $skippedLineNumbers; - $parser->refs = &$this->refs; - $parser->refsBeingParsed = $this->refsBeingParsed; - - return $parser->doParse($yaml, $flags); - } - - /** - * Returns the current line number (takes the offset into account). - * - * @internal - */ - public function getRealCurrentLineNb(): int - { - $realCurrentLineNumber = $this->currentLineNb + $this->offset; - - foreach ($this->skippedLineNumbers as $skippedLineNumber) { - if ($skippedLineNumber > $realCurrentLineNumber) { - break; - } - - ++$realCurrentLineNumber; - } - - return $realCurrentLineNumber; - } - - /** - * Returns the current line indentation. - */ - private function getCurrentLineIndentation(): int - { - if (' ' !== ($this->currentLine[0] ?? '')) { - return 0; - } - - return \strlen($this->currentLine) - \strlen(ltrim($this->currentLine, ' ')); - } - - /** - * Returns the next embed block of YAML. - * - * @param int|null $indentation The indent level at which the block is to be read, or null for default - * @param bool $inSequence True if the enclosing data structure is a sequence - * - * @throws ParseException When indentation problem are detected - */ - private function getNextEmbedBlock(int $indentation = null, bool $inSequence = false): string - { - $oldLineIndentation = $this->getCurrentLineIndentation(); - - if (!$this->moveToNextLine()) { - return ''; - } - - if (null === $indentation) { - $newIndent = null; - $movements = 0; - - do { - $EOF = false; - - // empty and comment-like lines do not influence the indentation depth - if ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()) { - $EOF = !$this->moveToNextLine(); - - if (!$EOF) { - ++$movements; - } - } else { - $newIndent = $this->getCurrentLineIndentation(); - } - } while (!$EOF && null === $newIndent); - - for ($i = 0; $i < $movements; ++$i) { - $this->moveToPreviousLine(); - } - - $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem(); - - if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) { - throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - } else { - $newIndent = $indentation; - } - - $data = []; - - if ($this->getCurrentLineIndentation() >= $newIndent) { - $data[] = substr($this->currentLine, $newIndent ?? 0); - } elseif ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()) { - $data[] = $this->currentLine; - } else { - $this->moveToPreviousLine(); - - return ''; - } - - if ($inSequence && $oldLineIndentation === $newIndent && isset($data[0][0]) && '-' === $data[0][0]) { - // the previous line contained a dash but no item content, this line is a sequence item with the same indentation - // and therefore no nested list or mapping - $this->moveToPreviousLine(); - - return ''; - } - - $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem(); - $isItComment = $this->isCurrentLineComment(); - - while ($this->moveToNextLine()) { - if ($isItComment && !$isItUnindentedCollection) { - $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem(); - $isItComment = $this->isCurrentLineComment(); - } - - $indent = $this->getCurrentLineIndentation(); - - if ($isItUnindentedCollection && !$this->isCurrentLineEmpty() && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) { - $this->moveToPreviousLine(); - break; - } - - if ($this->isCurrentLineBlank()) { - $data[] = substr($this->currentLine, $newIndent); - continue; - } - - if ($indent >= $newIndent) { - $data[] = substr($this->currentLine, $newIndent); - } elseif ($this->isCurrentLineComment()) { - $data[] = $this->currentLine; - } elseif (0 == $indent) { - $this->moveToPreviousLine(); - - break; - } else { - throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); - } - } - - return implode("\n", $data); - } - - private function hasMoreLines(): bool - { - return (\count($this->lines) - 1) > $this->currentLineNb; - } - - /** - * Moves the parser to the next line. - */ - private function moveToNextLine(): bool - { - if ($this->currentLineNb >= $this->numberOfParsedLines - 1) { - return false; - } - - $this->currentLine = $this->lines[++$this->currentLineNb]; - - return true; - } - - /** - * Moves the parser to the previous line. - */ - private function moveToPreviousLine(): bool - { - if ($this->currentLineNb < 1) { - return false; - } - - $this->currentLine = $this->lines[--$this->currentLineNb]; - - return true; - } - - /** - * Parses a YAML value. - * - * @param string $value A YAML value - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior - * @param string $context The parser context (either sequence or mapping) - * - * @return mixed - * - * @throws ParseException When reference does not exist - */ - private function parseValue(string $value, int $flags, string $context) - { - if (0 === strpos($value, '*')) { - if (false !== $pos = strpos($value, '#')) { - $value = substr($value, 1, $pos - 2); - } else { - $value = substr($value, 1); - } - - if (!\array_key_exists($value, $this->refs)) { - if (false !== $pos = array_search($value, $this->refsBeingParsed, true)) { - throw new ParseException(sprintf('Circular reference [%s] detected for reference "%s".', implode(', ', array_merge(\array_slice($this->refsBeingParsed, $pos), [$value])), $value), $this->currentLineNb + 1, $this->currentLine, $this->filename); - } - - throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine, $this->filename); - } - - return $this->refs[$value]; - } - - if (\in_array($value[0], ['!', '|', '>'], true) && self::preg_match('/^(?:'.self::TAG_PATTERN.' +)?'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) { - $modifiers = $matches['modifiers'] ?? ''; - - $data = $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), abs((int) $modifiers)); - - if ('' !== $matches['tag'] && '!' !== $matches['tag']) { - if ('!!binary' === $matches['tag']) { - return Inline::evaluateBinaryScalar($data); - } - - return new TaggedValue(substr($matches['tag'], 1), $data); - } - - return $data; - } - - try { - if ('' !== $value && '{' === $value[0]) { - $cursor = \strlen(rtrim($this->currentLine)) - \strlen(rtrim($value)); - - return Inline::parse($this->lexInlineMapping($cursor), $flags, $this->refs); - } elseif ('' !== $value && '[' === $value[0]) { - $cursor = \strlen(rtrim($this->currentLine)) - \strlen(rtrim($value)); - - return Inline::parse($this->lexInlineSequence($cursor), $flags, $this->refs); - } - - switch ($value[0] ?? '') { - case '"': - case "'": - $cursor = \strlen(rtrim($this->currentLine)) - \strlen(rtrim($value)); - $parsedValue = Inline::parse($this->lexInlineQuotedString($cursor), $flags, $this->refs); - - if (isset($this->currentLine[$cursor]) && preg_replace('/\s*(#.*)?$/A', '', substr($this->currentLine, $cursor))) { - throw new ParseException(sprintf('Unexpected characters near "%s".', substr($this->currentLine, $cursor))); - } - - return $parsedValue; - default: - $lines = []; - - while ($this->moveToNextLine()) { - // unquoted strings end before the first unindented line - if (0 === $this->getCurrentLineIndentation()) { - $this->moveToPreviousLine(); - - break; - } - - $lines[] = trim($this->currentLine); - } - - for ($i = 0, $linesCount = \count($lines), $previousLineBlank = false; $i < $linesCount; ++$i) { - if ('' === $lines[$i]) { - $value .= "\n"; - $previousLineBlank = true; - } elseif ($previousLineBlank) { - $value .= $lines[$i]; - $previousLineBlank = false; - } else { - $value .= ' '.$lines[$i]; - $previousLineBlank = false; - } - } - - Inline::$parsedLineNumber = $this->getRealCurrentLineNb(); - - $parsedValue = Inline::parse($value, $flags, $this->refs); - - if ('mapping' === $context && \is_string($parsedValue) && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) { - throw new ParseException('A colon cannot be used in an unquoted mapping value.', $this->getRealCurrentLineNb() + 1, $value, $this->filename); - } - - return $parsedValue; - } - } catch (ParseException $e) { - $e->setParsedLine($this->getRealCurrentLineNb() + 1); - $e->setSnippet($this->currentLine); - - throw $e; - } - } - - /** - * Parses a block scalar. - * - * @param string $style The style indicator that was used to begin this block scalar (| or >) - * @param string $chomping The chomping indicator that was used to begin this block scalar (+ or -) - * @param int $indentation The indentation indicator that was used to begin this block scalar - */ - private function parseBlockScalar(string $style, string $chomping = '', int $indentation = 0): string - { - $notEOF = $this->moveToNextLine(); - if (!$notEOF) { - return ''; - } - - $isCurrentLineBlank = $this->isCurrentLineBlank(); - $blockLines = []; - - // leading blank lines are consumed before determining indentation - while ($notEOF && $isCurrentLineBlank) { - // newline only if not EOF - if ($notEOF = $this->moveToNextLine()) { - $blockLines[] = ''; - $isCurrentLineBlank = $this->isCurrentLineBlank(); - } - } - - // determine indentation if not specified - if (0 === $indentation) { - $currentLineLength = \strlen($this->currentLine); - - for ($i = 0; $i < $currentLineLength && ' ' === $this->currentLine[$i]; ++$i) { - ++$indentation; - } - } - - if ($indentation > 0) { - $pattern = sprintf('/^ {%d}(.*)$/', $indentation); - - while ( - $notEOF && ( - $isCurrentLineBlank || - self::preg_match($pattern, $this->currentLine, $matches) - ) - ) { - if ($isCurrentLineBlank && \strlen($this->currentLine) > $indentation) { - $blockLines[] = substr($this->currentLine, $indentation); - } elseif ($isCurrentLineBlank) { - $blockLines[] = ''; - } else { - $blockLines[] = $matches[1]; - } - - // newline only if not EOF - if ($notEOF = $this->moveToNextLine()) { - $isCurrentLineBlank = $this->isCurrentLineBlank(); - } - } - } elseif ($notEOF) { - $blockLines[] = ''; - } - - if ($notEOF) { - $blockLines[] = ''; - $this->moveToPreviousLine(); - } elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) { - $blockLines[] = ''; - } - - // folded style - if ('>' === $style) { - $text = ''; - $previousLineIndented = false; - $previousLineBlank = false; - - for ($i = 0, $blockLinesCount = \count($blockLines); $i < $blockLinesCount; ++$i) { - if ('' === $blockLines[$i]) { - $text .= "\n"; - $previousLineIndented = false; - $previousLineBlank = true; - } elseif (' ' === $blockLines[$i][0]) { - $text .= "\n".$blockLines[$i]; - $previousLineIndented = true; - $previousLineBlank = false; - } elseif ($previousLineIndented) { - $text .= "\n".$blockLines[$i]; - $previousLineIndented = false; - $previousLineBlank = false; - } elseif ($previousLineBlank || 0 === $i) { - $text .= $blockLines[$i]; - $previousLineIndented = false; - $previousLineBlank = false; - } else { - $text .= ' '.$blockLines[$i]; - $previousLineIndented = false; - $previousLineBlank = false; - } - } - } else { - $text = implode("\n", $blockLines); - } - - // deal with trailing newlines - if ('' === $chomping) { - $text = preg_replace('/\n+$/', "\n", $text); - } elseif ('-' === $chomping) { - $text = preg_replace('/\n+$/', '', $text); - } - - return $text; - } - - /** - * Returns true if the next line is indented. - */ - private function isNextLineIndented(): bool - { - $currentIndentation = $this->getCurrentLineIndentation(); - $movements = 0; - - do { - $EOF = !$this->moveToNextLine(); - - if (!$EOF) { - ++$movements; - } - } while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment())); - - if ($EOF) { - return false; - } - - $ret = $this->getCurrentLineIndentation() > $currentIndentation; - - for ($i = 0; $i < $movements; ++$i) { - $this->moveToPreviousLine(); - } - - return $ret; - } - - /** - * Returns true if the current line is blank or if it is a comment line. - */ - private function isCurrentLineEmpty(): bool - { - return $this->isCurrentLineBlank() || $this->isCurrentLineComment(); - } - - /** - * Returns true if the current line is blank. - */ - private function isCurrentLineBlank(): bool - { - return '' === $this->currentLine || '' === trim($this->currentLine, ' '); - } - - /** - * Returns true if the current line is a comment line. - */ - private function isCurrentLineComment(): bool - { - //checking explicitly the first char of the trim is faster than loops or strpos - $ltrimmedLine = '' !== $this->currentLine && ' ' === $this->currentLine[0] ? ltrim($this->currentLine, ' ') : $this->currentLine; - - return '' !== $ltrimmedLine && '#' === $ltrimmedLine[0]; - } - - private function isCurrentLineLastLineInDocument(): bool - { - return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1); - } - - /** - * Cleanups a YAML string to be parsed. - * - * @param string $value The input YAML string - */ - private function cleanup(string $value): string - { - $value = str_replace(["\r\n", "\r"], "\n", $value); - - // strip YAML header - $count = 0; - $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count); - $this->offset += $count; - - // remove leading comments - $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count); - if (1 === $count) { - // items have been removed, update the offset - $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n"); - $value = $trimmedValue; - } - - // remove start of the document marker (---) - $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count); - if (1 === $count) { - // items have been removed, update the offset - $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n"); - $value = $trimmedValue; - - // remove end of the document marker (...) - $value = preg_replace('#\.\.\.\s*$#', '', $value); - } - - return $value; - } - - /** - * Returns true if the next line starts unindented collection. - */ - private function isNextLineUnIndentedCollection(): bool - { - $currentIndentation = $this->getCurrentLineIndentation(); - $movements = 0; - - do { - $EOF = !$this->moveToNextLine(); - - if (!$EOF) { - ++$movements; - } - } while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment())); - - if ($EOF) { - return false; - } - - $ret = $this->getCurrentLineIndentation() === $currentIndentation && $this->isStringUnIndentedCollectionItem(); - - for ($i = 0; $i < $movements; ++$i) { - $this->moveToPreviousLine(); - } - - return $ret; - } - - /** - * Returns true if the string is un-indented collection item. - */ - private function isStringUnIndentedCollectionItem(): bool - { - return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- '); - } - - /** - * A local wrapper for "preg_match" which will throw a ParseException if there - * is an internal error in the PCRE engine. - * - * This avoids us needing to check for "false" every time PCRE is used - * in the YAML engine - * - * @throws ParseException on a PCRE internal error - * - * @see preg_last_error() - * - * @internal - */ - public static function preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0): int - { - if (false === $ret = preg_match($pattern, $subject, $matches, $flags, $offset)) { - switch (preg_last_error()) { - case \PREG_INTERNAL_ERROR: - $error = 'Internal PCRE error.'; - break; - case \PREG_BACKTRACK_LIMIT_ERROR: - $error = 'pcre.backtrack_limit reached.'; - break; - case \PREG_RECURSION_LIMIT_ERROR: - $error = 'pcre.recursion_limit reached.'; - break; - case \PREG_BAD_UTF8_ERROR: - $error = 'Malformed UTF-8 data.'; - break; - case \PREG_BAD_UTF8_OFFSET_ERROR: - $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.'; - break; - default: - $error = 'Error.'; - } - - throw new ParseException($error); - } - - return $ret; - } - - /** - * Trim the tag on top of the value. - * - * Prevent values such as "!foo {quz: bar}" to be considered as - * a mapping block. - */ - private function trimTag(string $value): string - { - if ('!' === $value[0]) { - return ltrim(substr($value, 1, strcspn($value, " \r\n", 1)), ' '); - } - - return $value; - } - - private function getLineTag(string $value, int $flags, bool $nextLineCheck = true): ?string - { - if ('' === $value || '!' !== $value[0] || 1 !== self::preg_match('/^'.self::TAG_PATTERN.' *( +#.*)?$/', $value, $matches)) { - return null; - } - - if ($nextLineCheck && !$this->isNextLineIndented()) { - return null; - } - - $tag = substr($matches['tag'], 1); - - // Built-in tags - if ($tag && '!' === $tag[0]) { - throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag), $this->getRealCurrentLineNb() + 1, $value, $this->filename); - } - - if (Yaml::PARSE_CUSTOM_TAGS & $flags) { - return $tag; - } - - throw new ParseException(sprintf('Tags support is not enabled. You must use the flag "Yaml::PARSE_CUSTOM_TAGS" to use "%s".', $matches['tag']), $this->getRealCurrentLineNb() + 1, $value, $this->filename); - } - - private function lexInlineQuotedString(int &$cursor = 0): string - { - $quotation = $this->currentLine[$cursor]; - $value = $quotation; - ++$cursor; - - $previousLineWasNewline = true; - $previousLineWasTerminatedWithBackslash = false; - $lineNumber = 0; - - do { - if (++$lineNumber > 1) { - $cursor += strspn($this->currentLine, ' ', $cursor); - } - - if ($this->isCurrentLineBlank()) { - $value .= "\n"; - } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) { - $value .= ' '; - } - - for (; \strlen($this->currentLine) > $cursor; ++$cursor) { - switch ($this->currentLine[$cursor]) { - case '\\': - if ("'" === $quotation) { - $value .= '\\'; - } elseif (isset($this->currentLine[++$cursor])) { - $value .= '\\'.$this->currentLine[$cursor]; - } - - break; - case $quotation: - ++$cursor; - - if ("'" === $quotation && isset($this->currentLine[$cursor]) && "'" === $this->currentLine[$cursor]) { - $value .= "''"; - break; - } - - return $value.$quotation; - default: - $value .= $this->currentLine[$cursor]; - } - } - - if ($this->isCurrentLineBlank()) { - $previousLineWasNewline = true; - $previousLineWasTerminatedWithBackslash = false; - } elseif ('\\' === $this->currentLine[-1]) { - $previousLineWasNewline = false; - $previousLineWasTerminatedWithBackslash = true; - } else { - $previousLineWasNewline = false; - $previousLineWasTerminatedWithBackslash = false; - } - - if ($this->hasMoreLines()) { - $cursor = 0; - } - } while ($this->moveToNextLine()); - - throw new ParseException('Malformed inline YAML string.'); - } - - private function lexUnquotedString(int &$cursor): string - { - $offset = $cursor; - $cursor += strcspn($this->currentLine, '[]{},: ', $cursor); - - if ($cursor === $offset) { - throw new ParseException('Malformed unquoted YAML string.'); - } - - return substr($this->currentLine, $offset, $cursor - $offset); - } - - private function lexInlineMapping(int &$cursor = 0): string - { - return $this->lexInlineStructure($cursor, '}'); - } - - private function lexInlineSequence(int &$cursor = 0): string - { - return $this->lexInlineStructure($cursor, ']'); - } - - private function lexInlineStructure(int &$cursor, string $closingTag): string - { - $value = $this->currentLine[$cursor]; - ++$cursor; - - do { - $this->consumeWhitespaces($cursor); - - while (isset($this->currentLine[$cursor])) { - switch ($this->currentLine[$cursor]) { - case '"': - case "'": - $value .= $this->lexInlineQuotedString($cursor); - break; - case ':': - case ',': - $value .= $this->currentLine[$cursor]; - ++$cursor; - break; - case '{': - $value .= $this->lexInlineMapping($cursor); - break; - case '[': - $value .= $this->lexInlineSequence($cursor); - break; - case $closingTag: - $value .= $this->currentLine[$cursor]; - ++$cursor; - - return $value; - case '#': - break 2; - default: - $value .= $this->lexUnquotedString($cursor); - } - - if ($this->consumeWhitespaces($cursor)) { - $value .= ' '; - } - } - - if ($this->hasMoreLines()) { - $cursor = 0; - } - } while ($this->moveToNextLine()); - - throw new ParseException('Malformed inline YAML string.'); - } - - private function consumeWhitespaces(int &$cursor): bool - { - $whitespacesConsumed = 0; - - do { - $whitespaceOnlyTokenLength = strspn($this->currentLine, ' ', $cursor); - $whitespacesConsumed += $whitespaceOnlyTokenLength; - $cursor += $whitespaceOnlyTokenLength; - - if (isset($this->currentLine[$cursor])) { - return 0 < $whitespacesConsumed; - } - - if ($this->hasMoreLines()) { - $cursor = 0; - } - } while ($this->moveToNextLine()); - - return 0 < $whitespacesConsumed; - } -} diff --git a/vendor/symfony/yaml/Tag/TaggedValue.php b/vendor/symfony/yaml/Tag/TaggedValue.php deleted file mode 100644 index 4ea340613..000000000 --- a/vendor/symfony/yaml/Tag/TaggedValue.php +++ /dev/null @@ -1,38 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml\Tag; - -/** - * @author Nicolas Grekas - * @author Guilhem N. - */ -final class TaggedValue -{ - private $tag; - private $value; - - public function __construct(string $tag, $value) - { - $this->tag = $tag; - $this->value = $value; - } - - public function getTag(): string - { - return $this->tag; - } - - public function getValue() - { - return $this->value; - } -} diff --git a/vendor/symfony/yaml/Unescaper.php b/vendor/symfony/yaml/Unescaper.php deleted file mode 100644 index d1ef04123..000000000 --- a/vendor/symfony/yaml/Unescaper.php +++ /dev/null @@ -1,132 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml; - -use Symfony\Component\Yaml\Exception\ParseException; - -/** - * Unescaper encapsulates unescaping rules for single and double-quoted - * YAML strings. - * - * @author Matthew Lewinski - * - * @internal - */ -class Unescaper -{ - /** - * Regex fragment that matches an escaped character in a double quoted string. - */ - public const REGEX_ESCAPED_CHARACTER = '\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)'; - - /** - * Unescapes a single quoted string. - * - * @param string $value A single quoted string - */ - public function unescapeSingleQuotedString(string $value): string - { - return str_replace('\'\'', '\'', $value); - } - - /** - * Unescapes a double quoted string. - * - * @param string $value A double quoted string - */ - public function unescapeDoubleQuotedString(string $value): string - { - $callback = function ($match) { - return $this->unescapeCharacter($match[0]); - }; - - // evaluate the string - return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value); - } - - /** - * Unescapes a character that was found in a double-quoted string. - * - * @param string $value An escaped character - */ - private function unescapeCharacter(string $value): string - { - switch ($value[1]) { - case '0': - return "\x0"; - case 'a': - return "\x7"; - case 'b': - return "\x8"; - case 't': - return "\t"; - case "\t": - return "\t"; - case 'n': - return "\n"; - case 'v': - return "\xB"; - case 'f': - return "\xC"; - case 'r': - return "\r"; - case 'e': - return "\x1B"; - case ' ': - return ' '; - case '"': - return '"'; - case '/': - return '/'; - case '\\': - return '\\'; - case 'N': - // U+0085 NEXT LINE - return "\xC2\x85"; - case '_': - // U+00A0 NO-BREAK SPACE - return "\xC2\xA0"; - case 'L': - // U+2028 LINE SEPARATOR - return "\xE2\x80\xA8"; - case 'P': - // U+2029 PARAGRAPH SEPARATOR - return "\xE2\x80\xA9"; - case 'x': - return self::utf8chr(hexdec(substr($value, 2, 2))); - case 'u': - return self::utf8chr(hexdec(substr($value, 2, 4))); - case 'U': - return self::utf8chr(hexdec(substr($value, 2, 8))); - default: - throw new ParseException(sprintf('Found unknown escape character "%s".', $value)); - } - } - - /** - * Get the UTF-8 character for the given code point. - */ - private static function utf8chr(int $c): string - { - if (0x80 > $c %= 0x200000) { - return \chr($c); - } - if (0x800 > $c) { - return \chr(0xC0 | $c >> 6).\chr(0x80 | $c & 0x3F); - } - if (0x10000 > $c) { - return \chr(0xE0 | $c >> 12).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F); - } - - return \chr(0xF0 | $c >> 18).\chr(0x80 | $c >> 12 & 0x3F).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F); - } -} diff --git a/vendor/symfony/yaml/Yaml.php b/vendor/symfony/yaml/Yaml.php deleted file mode 100644 index ea1304528..000000000 --- a/vendor/symfony/yaml/Yaml.php +++ /dev/null @@ -1,100 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Yaml; - -use Symfony\Component\Yaml\Exception\ParseException; - -/** - * Yaml offers convenience methods to load and dump YAML. - * - * @author Fabien Potencier - * - * @final - */ -class Yaml -{ - public const DUMP_OBJECT = 1; - public const PARSE_EXCEPTION_ON_INVALID_TYPE = 2; - public const PARSE_OBJECT = 4; - public const PARSE_OBJECT_FOR_MAP = 8; - public const DUMP_EXCEPTION_ON_INVALID_TYPE = 16; - public const PARSE_DATETIME = 32; - public const DUMP_OBJECT_AS_MAP = 64; - public const DUMP_MULTI_LINE_LITERAL_BLOCK = 128; - public const PARSE_CONSTANT = 256; - public const PARSE_CUSTOM_TAGS = 512; - public const DUMP_EMPTY_ARRAY_AS_SEQUENCE = 1024; - public const DUMP_NULL_AS_TILDE = 2048; - - /** - * Parses a YAML file into a PHP value. - * - * Usage: - * - * $array = Yaml::parseFile('config.yml'); - * print_r($array); - * - * @param string $filename The path to the YAML file to be parsed - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior - * - * @return mixed - * - * @throws ParseException If the file could not be read or the YAML is not valid - */ - public static function parseFile(string $filename, int $flags = 0) - { - $yaml = new Parser(); - - return $yaml->parseFile($filename, $flags); - } - - /** - * Parses YAML into a PHP value. - * - * Usage: - * - * $array = Yaml::parse(file_get_contents('config.yml')); - * print_r($array); - * - * - * @param string $input A string containing YAML - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior - * - * @return mixed - * - * @throws ParseException If the YAML is not valid - */ - public static function parse(string $input, int $flags = 0) - { - $yaml = new Parser(); - - return $yaml->parse($input, $flags); - } - - /** - * Dumps a PHP value to a YAML string. - * - * The dump method, when supplied with an array, will do its best - * to convert the array into friendly YAML. - * - * @param mixed $input The PHP value - * @param int $inline The level where you switch to inline YAML - * @param int $indent The amount of spaces to use for indentation of nested nodes - * @param int $flags A bit field of DUMP_* constants to customize the dumped YAML string - */ - public static function dump($input, int $inline = 2, int $indent = 4, int $flags = 0): string - { - $yaml = new Dumper($indent); - - return $yaml->dump($input, $inline, 0, $flags); - } -}