summaryrefslogtreecommitdiff
path: root/vendor/sebastian
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2022-03-22 12:24:31 +0300
committerAndrew Dolgov <[email protected]>2022-03-22 12:24:31 +0300
commit1c4f7ab3b838b23afb2ee4dab14acbf75956e952 (patch)
tree0a19274107d717efe92d2c0376cd3105fead5a11 /vendor/sebastian
parent711662948768492e8d05b778a7d80eacaec368d2 (diff)
* add phpunit as a dev dependency
* add some basic tests for UrlHelper::rewrite_relative() * fix UrlHelper::rewrite_relative() to work better on non-absolute relative URL paths
Diffstat (limited to 'vendor/sebastian')
-rw-r--r--vendor/sebastian/cli-parser/ChangeLog.md15
-rw-r--r--vendor/sebastian/cli-parser/LICENSE33
-rw-r--r--vendor/sebastian/cli-parser/README.md17
-rw-r--r--vendor/sebastian/cli-parser/composer.json41
-rw-r--r--vendor/sebastian/cli-parser/infection.json12
-rw-r--r--vendor/sebastian/cli-parser/src/Parser.php204
-rw-r--r--vendor/sebastian/cli-parser/src/exceptions/AmbiguousOptionException.php26
-rw-r--r--vendor/sebastian/cli-parser/src/exceptions/Exception.php16
-rw-r--r--vendor/sebastian/cli-parser/src/exceptions/OptionDoesNotAllowArgumentException.php26
-rw-r--r--vendor/sebastian/cli-parser/src/exceptions/RequiredOptionArgumentMissingException.php26
-rw-r--r--vendor/sebastian/cli-parser/src/exceptions/UnknownOptionException.php26
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/ChangeLog.md38
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/LICENSE33
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/README.md20
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/composer.json36
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/src/Wizard.php125
-rw-r--r--vendor/sebastian/code-unit/.psalm/baseline.xml23
-rw-r--r--vendor/sebastian/code-unit/.psalm/config.xml16
-rw-r--r--vendor/sebastian/code-unit/ChangeLog.md65
-rw-r--r--vendor/sebastian/code-unit/LICENSE33
-rw-r--r--vendor/sebastian/code-unit/README.md17
-rw-r--r--vendor/sebastian/code-unit/composer.json50
-rw-r--r--vendor/sebastian/code-unit/src/ClassMethodUnit.php24
-rw-r--r--vendor/sebastian/code-unit/src/ClassUnit.php24
-rw-r--r--vendor/sebastian/code-unit/src/CodeUnit.php445
-rw-r--r--vendor/sebastian/code-unit/src/CodeUnitCollection.php84
-rw-r--r--vendor/sebastian/code-unit/src/CodeUnitCollectionIterator.php55
-rw-r--r--vendor/sebastian/code-unit/src/FunctionUnit.php24
-rw-r--r--vendor/sebastian/code-unit/src/InterfaceMethodUnit.php24
-rw-r--r--vendor/sebastian/code-unit/src/InterfaceUnit.php24
-rw-r--r--vendor/sebastian/code-unit/src/Mapper.php414
-rw-r--r--vendor/sebastian/code-unit/src/TraitMethodUnit.php24
-rw-r--r--vendor/sebastian/code-unit/src/TraitUnit.php24
-rw-r--r--vendor/sebastian/code-unit/src/exceptions/Exception.php16
-rw-r--r--vendor/sebastian/code-unit/src/exceptions/InvalidCodeUnitException.php16
-rw-r--r--vendor/sebastian/code-unit/src/exceptions/NoTraitException.php16
-rw-r--r--vendor/sebastian/code-unit/src/exceptions/ReflectionException.php16
-rw-r--r--vendor/sebastian/comparator/ChangeLog.md108
-rw-r--r--vendor/sebastian/comparator/LICENSE33
-rw-r--r--vendor/sebastian/comparator/README.md41
-rw-r--r--vendor/sebastian/comparator/composer.json57
-rw-r--r--vendor/sebastian/comparator/src/ArrayComparator.php141
-rw-r--r--vendor/sebastian/comparator/src/Comparator.php61
-rw-r--r--vendor/sebastian/comparator/src/ComparisonFailure.php129
-rw-r--r--vendor/sebastian/comparator/src/DOMNodeComparator.php93
-rw-r--r--vendor/sebastian/comparator/src/DateTimeComparator.php95
-rw-r--r--vendor/sebastian/comparator/src/DoubleComparator.php59
-rw-r--r--vendor/sebastian/comparator/src/ExceptionComparator.php54
-rw-r--r--vendor/sebastian/comparator/src/Factory.php142
-rw-r--r--vendor/sebastian/comparator/src/MockObjectComparator.php48
-rw-r--r--vendor/sebastian/comparator/src/NumericComparator.php86
-rw-r--r--vendor/sebastian/comparator/src/ObjectComparator.php112
-rw-r--r--vendor/sebastian/comparator/src/ResourceComparator.php54
-rw-r--r--vendor/sebastian/comparator/src/ScalarComparator.php98
-rw-r--r--vendor/sebastian/comparator/src/SplObjectStorageComparator.php71
-rw-r--r--vendor/sebastian/comparator/src/TypeComparator.php62
-rw-r--r--vendor/sebastian/comparator/src/exceptions/Exception.php16
-rw-r--r--vendor/sebastian/comparator/src/exceptions/RuntimeException.php14
-rw-r--r--vendor/sebastian/complexity/.psalm/baseline.xml2
-rw-r--r--vendor/sebastian/complexity/.psalm/config.xml16
-rw-r--r--vendor/sebastian/complexity/ChangeLog.md30
-rw-r--r--vendor/sebastian/complexity/LICENSE33
-rw-r--r--vendor/sebastian/complexity/README.md22
-rw-r--r--vendor/sebastian/complexity/composer.json41
-rw-r--r--vendor/sebastian/complexity/src/Calculator.php88
-rw-r--r--vendor/sebastian/complexity/src/Complexity/Complexity.php42
-rw-r--r--vendor/sebastian/complexity/src/Complexity/ComplexityCollection.php72
-rw-r--r--vendor/sebastian/complexity/src/Complexity/ComplexityCollectionIterator.php55
-rw-r--r--vendor/sebastian/complexity/src/Exception/Exception.php16
-rw-r--r--vendor/sebastian/complexity/src/Exception/RuntimeException.php14
-rw-r--r--vendor/sebastian/complexity/src/Visitor/ComplexityCalculatingVisitor.php109
-rw-r--r--vendor/sebastian/complexity/src/Visitor/CyclomaticComplexityCalculatingVisitor.php59
-rw-r--r--vendor/sebastian/diff/ChangeLog.md88
-rw-r--r--vendor/sebastian/diff/LICENSE33
-rw-r--r--vendor/sebastian/diff/README.md202
-rw-r--r--vendor/sebastian/diff/composer.json47
-rw-r--r--vendor/sebastian/diff/src/Chunk.php89
-rw-r--r--vendor/sebastian/diff/src/Diff.php64
-rw-r--r--vendor/sebastian/diff/src/Differ.php327
-rw-r--r--vendor/sebastian/diff/src/Exception/ConfigurationException.php38
-rw-r--r--vendor/sebastian/diff/src/Exception/Exception.php16
-rw-r--r--vendor/sebastian/diff/src/Exception/InvalidArgumentException.php14
-rw-r--r--vendor/sebastian/diff/src/Line.php45
-rw-r--r--vendor/sebastian/diff/src/LongestCommonSubsequenceCalculator.php18
-rw-r--r--vendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php88
-rw-r--r--vendor/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php52
-rw-r--r--vendor/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php72
-rw-r--r--vendor/sebastian/diff/src/Output/DiffOutputBuilderInterface.php19
-rw-r--r--vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php338
-rw-r--r--vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php272
-rw-r--r--vendor/sebastian/diff/src/Parser.php110
-rw-r--r--vendor/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php70
-rw-r--r--vendor/sebastian/environment/ChangeLog.md169
-rw-r--r--vendor/sebastian/environment/LICENSE33
-rw-r--r--vendor/sebastian/environment/README.md22
-rw-r--r--vendor/sebastian/environment/composer.json40
-rw-r--r--vendor/sebastian/environment/src/Console.php189
-rw-r--r--vendor/sebastian/environment/src/OperatingSystem.php53
-rw-r--r--vendor/sebastian/environment/src/Runtime.php317
-rw-r--r--vendor/sebastian/exporter/ChangeLog.md64
-rw-r--r--vendor/sebastian/exporter/LICENSE33
-rw-r--r--vendor/sebastian/exporter/README.md174
-rw-r--r--vendor/sebastian/exporter/composer.json56
-rw-r--r--vendor/sebastian/exporter/src/Exporter.php330
-rw-r--r--vendor/sebastian/global-state/ChangeLog.md79
-rw-r--r--vendor/sebastian/global-state/LICENSE33
-rw-r--r--vendor/sebastian/global-state/README.md20
-rw-r--r--vendor/sebastian/global-state/composer.json51
-rw-r--r--vendor/sebastian/global-state/src/CodeExporter.php109
-rw-r--r--vendor/sebastian/global-state/src/ExcludeList.php119
-rw-r--r--vendor/sebastian/global-state/src/Restorer.php143
-rw-r--r--vendor/sebastian/global-state/src/Snapshot.php443
-rw-r--r--vendor/sebastian/global-state/src/exceptions/Exception.php16
-rw-r--r--vendor/sebastian/global-state/src/exceptions/RuntimeException.php14
-rw-r--r--vendor/sebastian/lines-of-code/.psalm/baseline.xml2
-rw-r--r--vendor/sebastian/lines-of-code/.psalm/config.xml16
-rw-r--r--vendor/sebastian/lines-of-code/ChangeLog.md34
-rw-r--r--vendor/sebastian/lines-of-code/LICENSE33
-rw-r--r--vendor/sebastian/lines-of-code/README.md22
-rw-r--r--vendor/sebastian/lines-of-code/composer.json42
-rw-r--r--vendor/sebastian/lines-of-code/src/Counter.php91
-rw-r--r--vendor/sebastian/lines-of-code/src/Exception/Exception.php16
-rw-r--r--vendor/sebastian/lines-of-code/src/Exception/IllogicalValuesException.php16
-rw-r--r--vendor/sebastian/lines-of-code/src/Exception/NegativeValueException.php16
-rw-r--r--vendor/sebastian/lines-of-code/src/Exception/RuntimeException.php14
-rw-r--r--vendor/sebastian/lines-of-code/src/LineCountingVisitor.php82
-rw-r--r--vendor/sebastian/lines-of-code/src/LinesOfCode.php98
-rw-r--r--vendor/sebastian/object-enumerator/.psalm/baseline.xml9
-rw-r--r--vendor/sebastian/object-enumerator/.psalm/config.xml16
-rw-r--r--vendor/sebastian/object-enumerator/ChangeLog.md88
-rw-r--r--vendor/sebastian/object-enumerator/LICENSE33
-rw-r--r--vendor/sebastian/object-enumerator/README.md20
-rw-r--r--vendor/sebastian/object-enumerator/composer.json43
-rw-r--r--vendor/sebastian/object-enumerator/phpunit.xml24
-rw-r--r--vendor/sebastian/object-enumerator/src/Enumerator.php88
-rw-r--r--vendor/sebastian/object-enumerator/src/Exception.php16
-rw-r--r--vendor/sebastian/object-enumerator/src/InvalidArgumentException.php14
-rw-r--r--vendor/sebastian/object-reflector/.psalm/baseline.xml8
-rw-r--r--vendor/sebastian/object-reflector/.psalm/config.xml16
-rw-r--r--vendor/sebastian/object-reflector/ChangeLog.md55
-rw-r--r--vendor/sebastian/object-reflector/LICENSE33
-rw-r--r--vendor/sebastian/object-reflector/README.md20
-rw-r--r--vendor/sebastian/object-reflector/composer.json41
-rw-r--r--vendor/sebastian/object-reflector/src/Exception.php16
-rw-r--r--vendor/sebastian/object-reflector/src/InvalidArgumentException.php14
-rw-r--r--vendor/sebastian/object-reflector/src/ObjectReflector.php51
-rw-r--r--vendor/sebastian/recursion-context/.psalm/baseline.xml8
-rw-r--r--vendor/sebastian/recursion-context/.psalm/config.xml16
-rw-r--r--vendor/sebastian/recursion-context/ChangeLog.md33
-rw-r--r--vendor/sebastian/recursion-context/LICENSE33
-rw-r--r--vendor/sebastian/recursion-context/README.md18
-rw-r--r--vendor/sebastian/recursion-context/composer.json44
-rw-r--r--vendor/sebastian/recursion-context/src/Context.php186
-rw-r--r--vendor/sebastian/recursion-context/src/Exception.php16
-rw-r--r--vendor/sebastian/recursion-context/src/InvalidArgumentException.php14
-rw-r--r--vendor/sebastian/resource-operations/.gitattributes7
-rw-r--r--vendor/sebastian/resource-operations/.gitignore6
-rw-r--r--vendor/sebastian/resource-operations/ChangeLog.md54
-rw-r--r--vendor/sebastian/resource-operations/LICENSE33
-rw-r--r--vendor/sebastian/resource-operations/README.md14
-rw-r--r--vendor/sebastian/resource-operations/build/generate.php65
-rw-r--r--vendor/sebastian/resource-operations/composer.json37
-rw-r--r--vendor/sebastian/resource-operations/src/ResourceOperations.php2232
-rw-r--r--vendor/sebastian/type/ChangeLog.md123
-rw-r--r--vendor/sebastian/type/LICENSE33
-rw-r--r--vendor/sebastian/type/README.md20
-rw-r--r--vendor/sebastian/type/composer.json49
-rw-r--r--vendor/sebastian/type/src/CallableType.php197
-rw-r--r--vendor/sebastian/type/src/FalseType.php46
-rw-r--r--vendor/sebastian/type/src/GenericObjectType.php46
-rw-r--r--vendor/sebastian/type/src/IterableType.php76
-rw-r--r--vendor/sebastian/type/src/MixedType.php33
-rw-r--r--vendor/sebastian/type/src/NullType.php43
-rw-r--r--vendor/sebastian/type/src/ObjectType.php66
-rw-r--r--vendor/sebastian/type/src/ReflectionMapper.php123
-rw-r--r--vendor/sebastian/type/src/SimpleType.php92
-rw-r--r--vendor/sebastian/type/src/StaticType.php60
-rw-r--r--vendor/sebastian/type/src/Type.php101
-rw-r--r--vendor/sebastian/type/src/TypeName.php113
-rw-r--r--vendor/sebastian/type/src/UnionType.php115
-rw-r--r--vendor/sebastian/type/src/UnknownType.php43
-rw-r--r--vendor/sebastian/type/src/VoidType.php28
-rw-r--r--vendor/sebastian/type/src/exception/Exception.php16
-rw-r--r--vendor/sebastian/type/src/exception/LogicException.php14
-rw-r--r--vendor/sebastian/type/src/exception/RuntimeException.php14
-rw-r--r--vendor/sebastian/version/.gitattributes4
-rw-r--r--vendor/sebastian/version/.gitignore2
-rw-r--r--vendor/sebastian/version/ChangeLog.md25
-rw-r--r--vendor/sebastian/version/LICENSE33
-rw-r--r--vendor/sebastian/version/README.md43
-rw-r--r--vendor/sebastian/version/composer.json37
-rw-r--r--vendor/sebastian/version/src/Version.php97
192 files changed, 14405 insertions, 0 deletions
diff --git a/vendor/sebastian/cli-parser/ChangeLog.md b/vendor/sebastian/cli-parser/ChangeLog.md
new file mode 100644
index 000000000..9431ec594
--- /dev/null
+++ b/vendor/sebastian/cli-parser/ChangeLog.md
@@ -0,0 +1,15 @@
+# ChangeLog
+
+All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
+
+## [1.0.1] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [1.0.0] - 2020-08-12
+
+* Initial release
+
+[1.0.0]: https://github.com/sebastianbergmann/cli-parser/compare/bb7bb3297957927962b0a3335befe7b66f7462e9...1.0.0
diff --git a/vendor/sebastian/cli-parser/LICENSE b/vendor/sebastian/cli-parser/LICENSE
new file mode 100644
index 000000000..0e33c0591
--- /dev/null
+++ b/vendor/sebastian/cli-parser/LICENSE
@@ -0,0 +1,33 @@
+sebastian/cli-parser
+
+Copyright (c) 2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/cli-parser/README.md b/vendor/sebastian/cli-parser/README.md
new file mode 100644
index 000000000..39c17a72c
--- /dev/null
+++ b/vendor/sebastian/cli-parser/README.md
@@ -0,0 +1,17 @@
+# sebastian/cli-parser
+
+Library for parsing `$_SERVER['argv']`, extracted from `phpunit/phpunit`.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/cli-parser
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/cli-parser
+```
diff --git a/vendor/sebastian/cli-parser/composer.json b/vendor/sebastian/cli-parser/composer.json
new file mode 100644
index 000000000..34c376f91
--- /dev/null
+++ b/vendor/sebastian/cli-parser/composer.json
@@ -0,0 +1,41 @@
+{
+ "name": "sebastian/cli-parser",
+ "description": "Library for parsing CLI options",
+ "type": "library",
+ "homepage": "https://github.com/sebastianbergmann/cli-parser",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/cli-parser/issues"
+ },
+ "prefer-stable": true,
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/cli-parser/infection.json b/vendor/sebastian/cli-parser/infection.json
new file mode 100644
index 000000000..09546514f
--- /dev/null
+++ b/vendor/sebastian/cli-parser/infection.json
@@ -0,0 +1,12 @@
+{
+ "source": {
+ "directories": [
+ "src"
+ ]
+ },
+ "mutators": {
+ "@default": true
+ },
+ "minMsi": 100,
+ "minCoveredMsi": 100
+}
diff --git a/vendor/sebastian/cli-parser/src/Parser.php b/vendor/sebastian/cli-parser/src/Parser.php
new file mode 100644
index 000000000..a4f728bc6
--- /dev/null
+++ b/vendor/sebastian/cli-parser/src/Parser.php
@@ -0,0 +1,204 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/cli-parser.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CliParser;
+
+use function array_map;
+use function array_merge;
+use function array_shift;
+use function array_slice;
+use function assert;
+use function count;
+use function current;
+use function explode;
+use function is_array;
+use function is_int;
+use function is_string;
+use function key;
+use function next;
+use function preg_replace;
+use function reset;
+use function sort;
+use function strlen;
+use function strpos;
+use function strstr;
+use function substr;
+
+final class Parser
+{
+ /**
+ * @psalm-param list<string> $argv
+ * @psalm-param list<string> $longOptions
+ *
+ * @throws AmbiguousOptionException
+ * @throws RequiredOptionArgumentMissingException
+ * @throws OptionDoesNotAllowArgumentException
+ * @throws UnknownOptionException
+ */
+ public function parse(array $argv, string $shortOptions, array $longOptions = null): array
+ {
+ if (empty($argv)) {
+ return [[], []];
+ }
+
+ $options = [];
+ $nonOptions = [];
+
+ if ($longOptions) {
+ sort($longOptions);
+ }
+
+ if (isset($argv[0][0]) && $argv[0][0] !== '-') {
+ array_shift($argv);
+ }
+
+ reset($argv);
+
+ $argv = array_map('trim', $argv);
+
+ while (false !== $arg = current($argv)) {
+ $i = key($argv);
+
+ assert(is_int($i));
+
+ next($argv);
+
+ if ($arg === '') {
+ continue;
+ }
+
+ if ($arg === '--') {
+ $nonOptions = array_merge($nonOptions, array_slice($argv, $i + 1));
+
+ break;
+ }
+
+ if ($arg[0] !== '-' || (strlen($arg) > 1 && $arg[1] === '-' && !$longOptions)) {
+ $nonOptions[] = $arg;
+
+ continue;
+ }
+
+ if (strlen($arg) > 1 && $arg[1] === '-' && is_array($longOptions)) {
+ $this->parseLongOption(
+ substr($arg, 2),
+ $longOptions,
+ $options,
+ $argv
+ );
+ } else {
+ $this->parseShortOption(
+ substr($arg, 1),
+ $shortOptions,
+ $options,
+ $argv
+ );
+ }
+ }
+
+ return [$options, $nonOptions];
+ }
+
+ /**
+ * @throws RequiredOptionArgumentMissingException
+ */
+ private function parseShortOption(string $arg, string $shortOptions, array &$opts, array &$args): void
+ {
+ $argLength = strlen($arg);
+
+ for ($i = 0; $i < $argLength; $i++) {
+ $option = $arg[$i];
+ $optionArgument = null;
+
+ if ($arg[$i] === ':' || ($spec = strstr($shortOptions, $option)) === false) {
+ throw new UnknownOptionException('-' . $option);
+ }
+
+ assert(is_string($spec));
+
+ if (strlen($spec) > 1 && $spec[1] === ':') {
+ if ($i + 1 < $argLength) {
+ $opts[] = [$option, substr($arg, $i + 1)];
+
+ break;
+ }
+
+ if (!(strlen($spec) > 2 && $spec[2] === ':')) {
+ $optionArgument = current($args);
+
+ if (!$optionArgument) {
+ throw new RequiredOptionArgumentMissingException('-' . $option);
+ }
+
+ assert(is_string($optionArgument));
+
+ next($args);
+ }
+ }
+
+ $opts[] = [$option, $optionArgument];
+ }
+ }
+
+ /**
+ * @psalm-param list<string> $longOptions
+ *
+ * @throws AmbiguousOptionException
+ * @throws RequiredOptionArgumentMissingException
+ * @throws OptionDoesNotAllowArgumentException
+ * @throws UnknownOptionException
+ */
+ private function parseLongOption(string $arg, array $longOptions, array &$opts, array &$args): void
+ {
+ $count = count($longOptions);
+ $list = explode('=', $arg);
+ $option = $list[0];
+ $optionArgument = null;
+
+ if (count($list) > 1) {
+ $optionArgument = $list[1];
+ }
+
+ $optionLength = strlen($option);
+
+ foreach ($longOptions as $i => $longOption) {
+ $opt_start = substr($longOption, 0, $optionLength);
+
+ if ($opt_start !== $option) {
+ continue;
+ }
+
+ $opt_rest = substr($longOption, $optionLength);
+
+ if ($opt_rest !== '' && $i + 1 < $count && $option[0] !== '=' && strpos($longOptions[$i + 1], $option) === 0) {
+ throw new AmbiguousOptionException('--' . $option);
+ }
+
+ if (substr($longOption, -1) === '=') {
+ /* @noinspection StrlenInEmptyStringCheckContextInspection */
+ if (substr($longOption, -2) !== '==' && !strlen((string) $optionArgument)) {
+ if (false === $optionArgument = current($args)) {
+ throw new RequiredOptionArgumentMissingException('--' . $option);
+ }
+
+ next($args);
+ }
+ } elseif ($optionArgument) {
+ throw new OptionDoesNotAllowArgumentException('--' . $option);
+ }
+
+ $fullOption = '--' . preg_replace('/={1,2}$/', '', $longOption);
+ $opts[] = [$fullOption, $optionArgument];
+
+ return;
+ }
+
+ throw new UnknownOptionException('--' . $option);
+ }
+}
diff --git a/vendor/sebastian/cli-parser/src/exceptions/AmbiguousOptionException.php b/vendor/sebastian/cli-parser/src/exceptions/AmbiguousOptionException.php
new file mode 100644
index 000000000..a99f63697
--- /dev/null
+++ b/vendor/sebastian/cli-parser/src/exceptions/AmbiguousOptionException.php
@@ -0,0 +1,26 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/cli-parser.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CliParser;
+
+use function sprintf;
+use RuntimeException;
+
+final class AmbiguousOptionException extends RuntimeException implements Exception
+{
+ public function __construct(string $option)
+ {
+ parent::__construct(
+ sprintf(
+ 'Option "%s" is ambiguous',
+ $option
+ )
+ );
+ }
+}
diff --git a/vendor/sebastian/cli-parser/src/exceptions/Exception.php b/vendor/sebastian/cli-parser/src/exceptions/Exception.php
new file mode 100644
index 000000000..f35ad2457
--- /dev/null
+++ b/vendor/sebastian/cli-parser/src/exceptions/Exception.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/cli-parser.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CliParser;
+
+use Throwable;
+
+interface Exception extends Throwable
+{
+}
diff --git a/vendor/sebastian/cli-parser/src/exceptions/OptionDoesNotAllowArgumentException.php b/vendor/sebastian/cli-parser/src/exceptions/OptionDoesNotAllowArgumentException.php
new file mode 100644
index 000000000..0aad29ac0
--- /dev/null
+++ b/vendor/sebastian/cli-parser/src/exceptions/OptionDoesNotAllowArgumentException.php
@@ -0,0 +1,26 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/cli-parser.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CliParser;
+
+use function sprintf;
+use RuntimeException;
+
+final class OptionDoesNotAllowArgumentException extends RuntimeException implements Exception
+{
+ public function __construct(string $option)
+ {
+ parent::__construct(
+ sprintf(
+ 'Option "%s" does not allow an argument',
+ $option
+ )
+ );
+ }
+}
diff --git a/vendor/sebastian/cli-parser/src/exceptions/RequiredOptionArgumentMissingException.php b/vendor/sebastian/cli-parser/src/exceptions/RequiredOptionArgumentMissingException.php
new file mode 100644
index 000000000..d2a930b62
--- /dev/null
+++ b/vendor/sebastian/cli-parser/src/exceptions/RequiredOptionArgumentMissingException.php
@@ -0,0 +1,26 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/cli-parser.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CliParser;
+
+use function sprintf;
+use RuntimeException;
+
+final class RequiredOptionArgumentMissingException extends RuntimeException implements Exception
+{
+ public function __construct(string $option)
+ {
+ parent::__construct(
+ sprintf(
+ 'Required argument for option "%s" is missing',
+ $option
+ )
+ );
+ }
+}
diff --git a/vendor/sebastian/cli-parser/src/exceptions/UnknownOptionException.php b/vendor/sebastian/cli-parser/src/exceptions/UnknownOptionException.php
new file mode 100644
index 000000000..e98d9fd02
--- /dev/null
+++ b/vendor/sebastian/cli-parser/src/exceptions/UnknownOptionException.php
@@ -0,0 +1,26 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/cli-parser.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CliParser;
+
+use function sprintf;
+use RuntimeException;
+
+final class UnknownOptionException extends RuntimeException implements Exception
+{
+ public function __construct(string $option)
+ {
+ parent::__construct(
+ sprintf(
+ 'Unknown option "%s"',
+ $option
+ )
+ );
+ }
+}
diff --git a/vendor/sebastian/code-unit-reverse-lookup/ChangeLog.md b/vendor/sebastian/code-unit-reverse-lookup/ChangeLog.md
new file mode 100644
index 000000000..43a5db90d
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/ChangeLog.md
@@ -0,0 +1,38 @@
+# Change Log
+
+All notable changes to `sebastianbergmann/code-unit-reverse-lookup` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [2.0.3] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [2.0.2] - 2020-06-26
+
+### Added
+
+* This component is now supported on PHP 8
+
+## [2.0.1] - 2020-06-15
+
+### Changed
+
+* Tests etc. are now ignored for archive exports
+
+## 2.0.0 - 2020-02-07
+
+### Removed
+
+* This component is no longer supported on PHP 5.6, PHP 7.0, PHP 7.1, and PHP 7.2
+
+## 1.0.0 - 2016-02-13
+
+### Added
+
+* Initial release
+
+[2.0.3]: https://github.com/sebastianbergmann/code-unit-reverse-lookup/compare/2.0.2...2.0.3
+[2.0.2]: https://github.com/sebastianbergmann/code-unit-reverse-lookup/compare/2.0.1...2.0.2
+[2.0.1]: https://github.com/sebastianbergmann/code-unit-reverse-lookup/compare/2.0.0...2.0.1
+[2.0.0]: https://github.com/sebastianbergmann/code-unit-reverse-lookup/compare/1.0.0...2.0.0
diff --git a/vendor/sebastian/code-unit-reverse-lookup/LICENSE b/vendor/sebastian/code-unit-reverse-lookup/LICENSE
new file mode 100644
index 000000000..dc4bf7019
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/LICENSE
@@ -0,0 +1,33 @@
+code-unit-reverse-lookup
+
+Copyright (c) 2016-2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/code-unit-reverse-lookup/README.md b/vendor/sebastian/code-unit-reverse-lookup/README.md
new file mode 100644
index 000000000..1c0ca235e
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/README.md
@@ -0,0 +1,20 @@
+# sebastian/code-unit-reverse-lookup
+
+[![CI Status](https://github.com/sebastianbergmann/code-unit-reverse-lookup/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/code-unit-reverse-lookup/actions)
+[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/code-unit-reverse-lookup/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/code-unit-reverse-lookup)
+
+Looks up which function or method a line of code belongs to.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/code-unit-reverse-lookup
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/code-unit-reverse-lookup
+```
diff --git a/vendor/sebastian/code-unit-reverse-lookup/composer.json b/vendor/sebastian/code-unit-reverse-lookup/composer.json
new file mode 100644
index 000000000..cff96167a
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/composer.json
@@ -0,0 +1,36 @@
+{
+ "name": "sebastian/code-unit-reverse-lookup",
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]"
+ }
+ ],
+ "prefer-stable": true,
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/code-unit-reverse-lookup/src/Wizard.php b/vendor/sebastian/code-unit-reverse-lookup/src/Wizard.php
new file mode 100644
index 000000000..35de53981
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/src/Wizard.php
@@ -0,0 +1,125 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit-reverse-lookup.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnitReverseLookup;
+
+use function array_merge;
+use function assert;
+use function get_declared_classes;
+use function get_declared_traits;
+use function get_defined_functions;
+use function is_array;
+use function range;
+use ReflectionClass;
+use ReflectionFunction;
+use ReflectionFunctionAbstract;
+use ReflectionMethod;
+
+/**
+ * @since Class available since Release 1.0.0
+ */
+class Wizard
+{
+ /**
+ * @var array
+ */
+ private $lookupTable = [];
+
+ /**
+ * @var array
+ */
+ private $processedClasses = [];
+
+ /**
+ * @var array
+ */
+ private $processedFunctions = [];
+
+ /**
+ * @param string $filename
+ * @param int $lineNumber
+ *
+ * @return string
+ */
+ public function lookup($filename, $lineNumber)
+ {
+ if (!isset($this->lookupTable[$filename][$lineNumber])) {
+ $this->updateLookupTable();
+ }
+
+ if (isset($this->lookupTable[$filename][$lineNumber])) {
+ return $this->lookupTable[$filename][$lineNumber];
+ }
+
+ return $filename . ':' . $lineNumber;
+ }
+
+ private function updateLookupTable(): void
+ {
+ $this->processClassesAndTraits();
+ $this->processFunctions();
+ }
+
+ private function processClassesAndTraits(): void
+ {
+ $classes = get_declared_classes();
+ $traits = get_declared_traits();
+
+ assert(is_array($classes));
+ assert(is_array($traits));
+
+ foreach (array_merge($classes, $traits) as $classOrTrait) {
+ if (isset($this->processedClasses[$classOrTrait])) {
+ continue;
+ }
+
+ $reflector = new ReflectionClass($classOrTrait);
+
+ foreach ($reflector->getMethods() as $method) {
+ $this->processFunctionOrMethod($method);
+ }
+
+ $this->processedClasses[$classOrTrait] = true;
+ }
+ }
+
+ private function processFunctions(): void
+ {
+ foreach (get_defined_functions()['user'] as $function) {
+ if (isset($this->processedFunctions[$function])) {
+ continue;
+ }
+
+ $this->processFunctionOrMethod(new ReflectionFunction($function));
+
+ $this->processedFunctions[$function] = true;
+ }
+ }
+
+ private function processFunctionOrMethod(ReflectionFunctionAbstract $functionOrMethod): void
+ {
+ if ($functionOrMethod->isInternal()) {
+ return;
+ }
+
+ $name = $functionOrMethod->getName();
+
+ if ($functionOrMethod instanceof ReflectionMethod) {
+ $name = $functionOrMethod->getDeclaringClass()->getName() . '::' . $name;
+ }
+
+ if (!isset($this->lookupTable[$functionOrMethod->getFileName()])) {
+ $this->lookupTable[$functionOrMethod->getFileName()] = [];
+ }
+
+ foreach (range($functionOrMethod->getStartLine(), $functionOrMethod->getEndLine()) as $line) {
+ $this->lookupTable[$functionOrMethod->getFileName()][$line] = $name;
+ }
+ }
+}
diff --git a/vendor/sebastian/code-unit/.psalm/baseline.xml b/vendor/sebastian/code-unit/.psalm/baseline.xml
new file mode 100644
index 000000000..e44889190
--- /dev/null
+++ b/vendor/sebastian/code-unit/.psalm/baseline.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44">
+ <file src="src/Mapper.php">
+ <ArgumentTypeCoercion occurrences="16">
+ <code>$firstPart</code>
+ <code>$firstPart</code>
+ <code>$firstPart</code>
+ <code>$firstPart</code>
+ <code>$firstPart</code>
+ <code>$firstPart</code>
+ <code>$firstPart</code>
+ <code>$firstPart</code>
+ <code>$firstPart</code>
+ <code>$secondPart</code>
+ <code>$unit</code>
+ <code>$unit</code>
+ <code>$unit</code>
+ <code>$unit</code>
+ <code>$unit</code>
+ <code>$unit</code>
+ </ArgumentTypeCoercion>
+ </file>
+</files>
diff --git a/vendor/sebastian/code-unit/.psalm/config.xml b/vendor/sebastian/code-unit/.psalm/config.xml
new file mode 100644
index 000000000..a39e9a4c3
--- /dev/null
+++ b/vendor/sebastian/code-unit/.psalm/config.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<psalm
+ totallyTyped="true"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="https://getpsalm.org/schema/config"
+ xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
+ resolveFromConfigFile="false"
+ errorBaseline=".psalm/baseline.xml"
+>
+ <projectFiles>
+ <directory name="src" />
+ <ignoreFiles>
+ <directory name="vendor" />
+ </ignoreFiles>
+ </projectFiles>
+</psalm>
diff --git a/vendor/sebastian/code-unit/ChangeLog.md b/vendor/sebastian/code-unit/ChangeLog.md
new file mode 100644
index 000000000..0978e651e
--- /dev/null
+++ b/vendor/sebastian/code-unit/ChangeLog.md
@@ -0,0 +1,65 @@
+# ChangeLog
+
+All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [1.0.8] - 2020-10-26
+
+### Fixed
+
+* `SebastianBergmann\CodeUnit\Exception` now correctly extends `\Throwable`
+
+## [1.0.7] - 2020-10-02
+
+### Fixed
+
+* `SebastianBergmann\CodeUnit\Mapper::stringToCodeUnits()` no longer attempts to create `CodeUnit` objects for code units that are not declared in userland
+
+## [1.0.6] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [1.0.5] - 2020-06-26
+
+### Fixed
+
+* [#3](https://github.com/sebastianbergmann/code-unit/issues/3): Regression in 1.0.4
+
+## [1.0.4] - 2020-06-26
+
+### Added
+
+* This component is now supported on PHP 8
+
+## [1.0.3] - 2020-06-15
+
+### Changed
+
+* Tests etc. are now ignored for archive exports
+
+## [1.0.2] - 2020-04-30
+
+### Fixed
+
+* `Mapper::stringToCodeUnits()` raised the wrong exception for `Class::method` when a class named `Class` exists but does not have a method named `method`
+
+## [1.0.1] - 2020-04-27
+
+### Fixed
+
+* [#2](https://github.com/sebastianbergmann/code-unit/issues/2): `Mapper::stringToCodeUnits()` breaks when `ClassName<extended>` is used for class that extends built-in class
+
+## [1.0.0] - 2020-03-30
+
+* Initial release
+
+[1.0.8]: https://github.com/sebastianbergmann/code-unit/compare/1.0.7...1.0.8
+[1.0.7]: https://github.com/sebastianbergmann/code-unit/compare/1.0.6...1.0.7
+[1.0.6]: https://github.com/sebastianbergmann/code-unit/compare/1.0.5...1.0.6
+[1.0.5]: https://github.com/sebastianbergmann/code-unit/compare/1.0.4...1.0.5
+[1.0.4]: https://github.com/sebastianbergmann/code-unit/compare/1.0.3...1.0.4
+[1.0.3]: https://github.com/sebastianbergmann/code-unit/compare/1.0.2...1.0.3
+[1.0.2]: https://github.com/sebastianbergmann/code-unit/compare/1.0.1...1.0.2
+[1.0.1]: https://github.com/sebastianbergmann/code-unit/compare/1.0.0...1.0.1
+[1.0.0]: https://github.com/sebastianbergmann/code-unit/compare/530c3900e5db9bcb8516da545bef0d62536cedaa...1.0.0
diff --git a/vendor/sebastian/code-unit/LICENSE b/vendor/sebastian/code-unit/LICENSE
new file mode 100644
index 000000000..b99bc8ac4
--- /dev/null
+++ b/vendor/sebastian/code-unit/LICENSE
@@ -0,0 +1,33 @@
+sebastian/code-unit
+
+Copyright (c) 2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/code-unit/README.md b/vendor/sebastian/code-unit/README.md
new file mode 100644
index 000000000..d20227a9b
--- /dev/null
+++ b/vendor/sebastian/code-unit/README.md
@@ -0,0 +1,17 @@
+# sebastian/code-unit
+
+Collection of value objects that represent the PHP code units.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/code-unit
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/code-unit
+```
diff --git a/vendor/sebastian/code-unit/composer.json b/vendor/sebastian/code-unit/composer.json
new file mode 100644
index 000000000..5b86ec589
--- /dev/null
+++ b/vendor/sebastian/code-unit/composer.json
@@ -0,0 +1,50 @@
+{
+ "name": "sebastian/code-unit",
+ "description": "Collection of value objects that represent the PHP code units",
+ "type": "library",
+ "homepage": "https://github.com/sebastianbergmann/code-unit",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit/issues"
+ },
+ "prefer-stable": true,
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "autoload-dev": {
+ "classmap": [
+ "tests/_fixture"
+ ],
+ "files": [
+ "tests/_fixture/file_with_multiple_code_units.php",
+ "tests/_fixture/function.php"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/code-unit/src/ClassMethodUnit.php b/vendor/sebastian/code-unit/src/ClassMethodUnit.php
new file mode 100644
index 000000000..f9ddac29e
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/ClassMethodUnit.php
@@ -0,0 +1,24 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+/**
+ * @psalm-immutable
+ */
+final class ClassMethodUnit extends CodeUnit
+{
+ /**
+ * @psalm-assert-if-true ClassMethodUnit $this
+ */
+ public function isClassMethod(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/sebastian/code-unit/src/ClassUnit.php b/vendor/sebastian/code-unit/src/ClassUnit.php
new file mode 100644
index 000000000..3ba0ee661
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/ClassUnit.php
@@ -0,0 +1,24 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+/**
+ * @psalm-immutable
+ */
+final class ClassUnit extends CodeUnit
+{
+ /**
+ * @psalm-assert-if-true ClassUnit $this
+ */
+ public function isClass(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/sebastian/code-unit/src/CodeUnit.php b/vendor/sebastian/code-unit/src/CodeUnit.php
new file mode 100644
index 000000000..9e5cceb35
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/CodeUnit.php
@@ -0,0 +1,445 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+use function range;
+use function sprintf;
+use ReflectionClass;
+use ReflectionFunction;
+use ReflectionMethod;
+
+/**
+ * @psalm-immutable
+ */
+abstract class CodeUnit
+{
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @var string
+ */
+ private $sourceFileName;
+
+ /**
+ * @var array
+ * @psalm-var list<int>
+ */
+ private $sourceLines;
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws InvalidCodeUnitException
+ * @throws ReflectionException
+ */
+ public static function forClass(string $className): ClassUnit
+ {
+ self::ensureUserDefinedClass($className);
+
+ $reflector = self::reflectorForClass($className);
+
+ return new ClassUnit(
+ $className,
+ $reflector->getFileName(),
+ range(
+ $reflector->getStartLine(),
+ $reflector->getEndLine()
+ )
+ );
+ }
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws InvalidCodeUnitException
+ * @throws ReflectionException
+ */
+ public static function forClassMethod(string $className, string $methodName): ClassMethodUnit
+ {
+ self::ensureUserDefinedClass($className);
+
+ $reflector = self::reflectorForClassMethod($className, $methodName);
+
+ return new ClassMethodUnit(
+ $className . '::' . $methodName,
+ $reflector->getFileName(),
+ range(
+ $reflector->getStartLine(),
+ $reflector->getEndLine()
+ )
+ );
+ }
+
+ /**
+ * @psalm-param class-string $interfaceName
+ *
+ * @throws InvalidCodeUnitException
+ * @throws ReflectionException
+ */
+ public static function forInterface(string $interfaceName): InterfaceUnit
+ {
+ self::ensureUserDefinedInterface($interfaceName);
+
+ $reflector = self::reflectorForClass($interfaceName);
+
+ return new InterfaceUnit(
+ $interfaceName,
+ $reflector->getFileName(),
+ range(
+ $reflector->getStartLine(),
+ $reflector->getEndLine()
+ )
+ );
+ }
+
+ /**
+ * @psalm-param class-string $interfaceName
+ *
+ * @throws InvalidCodeUnitException
+ * @throws ReflectionException
+ */
+ public static function forInterfaceMethod(string $interfaceName, string $methodName): InterfaceMethodUnit
+ {
+ self::ensureUserDefinedInterface($interfaceName);
+
+ $reflector = self::reflectorForClassMethod($interfaceName, $methodName);
+
+ return new InterfaceMethodUnit(
+ $interfaceName . '::' . $methodName,
+ $reflector->getFileName(),
+ range(
+ $reflector->getStartLine(),
+ $reflector->getEndLine()
+ )
+ );
+ }
+
+ /**
+ * @psalm-param class-string $traitName
+ *
+ * @throws InvalidCodeUnitException
+ * @throws ReflectionException
+ */
+ public static function forTrait(string $traitName): TraitUnit
+ {
+ self::ensureUserDefinedTrait($traitName);
+
+ $reflector = self::reflectorForClass($traitName);
+
+ return new TraitUnit(
+ $traitName,
+ $reflector->getFileName(),
+ range(
+ $reflector->getStartLine(),
+ $reflector->getEndLine()
+ )
+ );
+ }
+
+ /**
+ * @psalm-param class-string $traitName
+ *
+ * @throws InvalidCodeUnitException
+ * @throws ReflectionException
+ */
+ public static function forTraitMethod(string $traitName, string $methodName): TraitMethodUnit
+ {
+ self::ensureUserDefinedTrait($traitName);
+
+ $reflector = self::reflectorForClassMethod($traitName, $methodName);
+
+ return new TraitMethodUnit(
+ $traitName . '::' . $methodName,
+ $reflector->getFileName(),
+ range(
+ $reflector->getStartLine(),
+ $reflector->getEndLine()
+ )
+ );
+ }
+
+ /**
+ * @psalm-param callable-string $functionName
+ *
+ * @throws InvalidCodeUnitException
+ * @throws ReflectionException
+ */
+ public static function forFunction(string $functionName): FunctionUnit
+ {
+ $reflector = self::reflectorForFunction($functionName);
+
+ if (!$reflector->isUserDefined()) {
+ throw new InvalidCodeUnitException(
+ sprintf(
+ '"%s" is not a user-defined function',
+ $functionName
+ )
+ );
+ }
+
+ return new FunctionUnit(
+ $functionName,
+ $reflector->getFileName(),
+ range(
+ $reflector->getStartLine(),
+ $reflector->getEndLine()
+ )
+ );
+ }
+
+ /**
+ * @psalm-param list<int> $sourceLines
+ */
+ private function __construct(string $name, string $sourceFileName, array $sourceLines)
+ {
+ $this->name = $name;
+ $this->sourceFileName = $sourceFileName;
+ $this->sourceLines = $sourceLines;
+ }
+
+ public function name(): string
+ {
+ return $this->name;
+ }
+
+ public function sourceFileName(): string
+ {
+ return $this->sourceFileName;
+ }
+
+ /**
+ * @psalm-return list<int>
+ */
+ public function sourceLines(): array
+ {
+ return $this->sourceLines;
+ }
+
+ public function isClass(): bool
+ {
+ return false;
+ }
+
+ public function isClassMethod(): bool
+ {
+ return false;
+ }
+
+ public function isInterface(): bool
+ {
+ return false;
+ }
+
+ public function isInterfaceMethod(): bool
+ {
+ return false;
+ }
+
+ public function isTrait(): bool
+ {
+ return false;
+ }
+
+ public function isTraitMethod(): bool
+ {
+ return false;
+ }
+
+ public function isFunction(): bool
+ {
+ return false;
+ }
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws InvalidCodeUnitException
+ */
+ private static function ensureUserDefinedClass(string $className): void
+ {
+ try {
+ $reflector = new ReflectionClass($className);
+
+ if ($reflector->isInterface()) {
+ throw new InvalidCodeUnitException(
+ sprintf(
+ '"%s" is an interface and not a class',
+ $className
+ )
+ );
+ }
+
+ if ($reflector->isTrait()) {
+ throw new InvalidCodeUnitException(
+ sprintf(
+ '"%s" is a trait and not a class',
+ $className
+ )
+ );
+ }
+
+ if (!$reflector->isUserDefined()) {
+ throw new InvalidCodeUnitException(
+ sprintf(
+ '"%s" is not a user-defined class',
+ $className
+ )
+ );
+ }
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @psalm-param class-string $interfaceName
+ *
+ * @throws InvalidCodeUnitException
+ */
+ private static function ensureUserDefinedInterface(string $interfaceName): void
+ {
+ try {
+ $reflector = new ReflectionClass($interfaceName);
+
+ if (!$reflector->isInterface()) {
+ throw new InvalidCodeUnitException(
+ sprintf(
+ '"%s" is not an interface',
+ $interfaceName
+ )
+ );
+ }
+
+ if (!$reflector->isUserDefined()) {
+ throw new InvalidCodeUnitException(
+ sprintf(
+ '"%s" is not a user-defined interface',
+ $interfaceName
+ )
+ );
+ }
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @psalm-param class-string $traitName
+ *
+ * @throws InvalidCodeUnitException
+ */
+ private static function ensureUserDefinedTrait(string $traitName): void
+ {
+ try {
+ $reflector = new ReflectionClass($traitName);
+
+ if (!$reflector->isTrait()) {
+ throw new InvalidCodeUnitException(
+ sprintf(
+ '"%s" is not a trait',
+ $traitName
+ )
+ );
+ }
+
+ // @codeCoverageIgnoreStart
+ if (!$reflector->isUserDefined()) {
+ throw new InvalidCodeUnitException(
+ sprintf(
+ '"%s" is not a user-defined trait',
+ $traitName
+ )
+ );
+ }
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws ReflectionException
+ */
+ private static function reflectorForClass(string $className): ReflectionClass
+ {
+ try {
+ return new ReflectionClass($className);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws ReflectionException
+ */
+ private static function reflectorForClassMethod(string $className, string $methodName): ReflectionMethod
+ {
+ try {
+ return new ReflectionMethod($className, $methodName);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @psalm-param callable-string $functionName
+ *
+ * @throws ReflectionException
+ */
+ private static function reflectorForFunction(string $functionName): ReflectionFunction
+ {
+ try {
+ return new ReflectionFunction($functionName);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+}
diff --git a/vendor/sebastian/code-unit/src/CodeUnitCollection.php b/vendor/sebastian/code-unit/src/CodeUnitCollection.php
new file mode 100644
index 000000000..f53db8a12
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/CodeUnitCollection.php
@@ -0,0 +1,84 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+use function array_merge;
+use function count;
+use Countable;
+use IteratorAggregate;
+
+final class CodeUnitCollection implements Countable, IteratorAggregate
+{
+ /**
+ * @psalm-var list<CodeUnit>
+ */
+ private $codeUnits = [];
+
+ /**
+ * @psalm-param list<CodeUnit> $items
+ */
+ public static function fromArray(array $items): self
+ {
+ $collection = new self;
+
+ foreach ($items as $item) {
+ $collection->add($item);
+ }
+
+ return $collection;
+ }
+
+ public static function fromList(CodeUnit ...$items): self
+ {
+ return self::fromArray($items);
+ }
+
+ private function __construct()
+ {
+ }
+
+ /**
+ * @psalm-return list<CodeUnit>
+ */
+ public function asArray(): array
+ {
+ return $this->codeUnits;
+ }
+
+ public function getIterator(): CodeUnitCollectionIterator
+ {
+ return new CodeUnitCollectionIterator($this);
+ }
+
+ public function count(): int
+ {
+ return count($this->codeUnits);
+ }
+
+ public function isEmpty(): bool
+ {
+ return empty($this->codeUnits);
+ }
+
+ public function mergeWith(self $other): self
+ {
+ return self::fromArray(
+ array_merge(
+ $this->asArray(),
+ $other->asArray()
+ )
+ );
+ }
+
+ private function add(CodeUnit $item): void
+ {
+ $this->codeUnits[] = $item;
+ }
+}
diff --git a/vendor/sebastian/code-unit/src/CodeUnitCollectionIterator.php b/vendor/sebastian/code-unit/src/CodeUnitCollectionIterator.php
new file mode 100644
index 000000000..bdc86d888
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/CodeUnitCollectionIterator.php
@@ -0,0 +1,55 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+use Iterator;
+
+final class CodeUnitCollectionIterator implements Iterator
+{
+ /**
+ * @psalm-var list<CodeUnit>
+ */
+ private $codeUnits;
+
+ /**
+ * @var int
+ */
+ private $position = 0;
+
+ public function __construct(CodeUnitCollection $collection)
+ {
+ $this->codeUnits = $collection->asArray();
+ }
+
+ public function rewind(): void
+ {
+ $this->position = 0;
+ }
+
+ public function valid(): bool
+ {
+ return isset($this->codeUnits[$this->position]);
+ }
+
+ public function key(): int
+ {
+ return $this->position;
+ }
+
+ public function current(): CodeUnit
+ {
+ return $this->codeUnits[$this->position];
+ }
+
+ public function next(): void
+ {
+ $this->position++;
+ }
+}
diff --git a/vendor/sebastian/code-unit/src/FunctionUnit.php b/vendor/sebastian/code-unit/src/FunctionUnit.php
new file mode 100644
index 000000000..df76cf195
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/FunctionUnit.php
@@ -0,0 +1,24 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+/**
+ * @psalm-immutable
+ */
+final class FunctionUnit extends CodeUnit
+{
+ /**
+ * @psalm-assert-if-true FunctionUnit $this
+ */
+ public function isFunction(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/sebastian/code-unit/src/InterfaceMethodUnit.php b/vendor/sebastian/code-unit/src/InterfaceMethodUnit.php
new file mode 100644
index 000000000..fcd44f41a
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/InterfaceMethodUnit.php
@@ -0,0 +1,24 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+/**
+ * @psalm-immutable
+ */
+final class InterfaceMethodUnit extends CodeUnit
+{
+ /**
+ * @psalm-assert-if-true InterfaceMethod $this
+ */
+ public function isInterfaceMethod(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/sebastian/code-unit/src/InterfaceUnit.php b/vendor/sebastian/code-unit/src/InterfaceUnit.php
new file mode 100644
index 000000000..5cf585bfd
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/InterfaceUnit.php
@@ -0,0 +1,24 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+/**
+ * @psalm-immutable
+ */
+final class InterfaceUnit extends CodeUnit
+{
+ /**
+ * @psalm-assert-if-true InterfaceUnit $this
+ */
+ public function isInterface(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/sebastian/code-unit/src/Mapper.php b/vendor/sebastian/code-unit/src/Mapper.php
new file mode 100644
index 000000000..a72b3b0dd
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/Mapper.php
@@ -0,0 +1,414 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+use function array_keys;
+use function array_merge;
+use function array_unique;
+use function array_values;
+use function class_exists;
+use function explode;
+use function function_exists;
+use function interface_exists;
+use function ksort;
+use function method_exists;
+use function sort;
+use function sprintf;
+use function str_replace;
+use function strpos;
+use function trait_exists;
+use ReflectionClass;
+use ReflectionFunction;
+use ReflectionMethod;
+
+final class Mapper
+{
+ /**
+ * @psalm-return array<string,list<int>>
+ */
+ public function codeUnitsToSourceLines(CodeUnitCollection $codeUnits): array
+ {
+ $result = [];
+
+ foreach ($codeUnits as $codeUnit) {
+ $sourceFileName = $codeUnit->sourceFileName();
+
+ if (!isset($result[$sourceFileName])) {
+ $result[$sourceFileName] = [];
+ }
+
+ $result[$sourceFileName] = array_merge($result[$sourceFileName], $codeUnit->sourceLines());
+ }
+
+ foreach (array_keys($result) as $sourceFileName) {
+ $result[$sourceFileName] = array_values(array_unique($result[$sourceFileName]));
+
+ sort($result[$sourceFileName]);
+ }
+
+ ksort($result);
+
+ return $result;
+ }
+
+ /**
+ * @throws InvalidCodeUnitException
+ * @throws ReflectionException
+ */
+ public function stringToCodeUnits(string $unit): CodeUnitCollection
+ {
+ if (strpos($unit, '::') !== false) {
+ [$firstPart, $secondPart] = explode('::', $unit);
+
+ if (empty($firstPart) && $this->isUserDefinedFunction($secondPart)) {
+ return CodeUnitCollection::fromList(CodeUnit::forFunction($secondPart));
+ }
+
+ if ($this->isUserDefinedClass($firstPart)) {
+ if ($secondPart === '<public>') {
+ return $this->publicMethodsOfClass($firstPart);
+ }
+
+ if ($secondPart === '<!public>') {
+ return $this->protectedAndPrivateMethodsOfClass($firstPart);
+ }
+
+ if ($secondPart === '<protected>') {
+ return $this->protectedMethodsOfClass($firstPart);
+ }
+
+ if ($secondPart === '<!protected>') {
+ return $this->publicAndPrivateMethodsOfClass($firstPart);
+ }
+
+ if ($secondPart === '<private>') {
+ return $this->privateMethodsOfClass($firstPart);
+ }
+
+ if ($secondPart === '<!private>') {
+ return $this->publicAndProtectedMethodsOfClass($firstPart);
+ }
+
+ if ($this->isUserDefinedMethod($firstPart, $secondPart)) {
+ return CodeUnitCollection::fromList(CodeUnit::forClassMethod($firstPart, $secondPart));
+ }
+ }
+
+ if ($this->isUserDefinedInterface($firstPart)) {
+ return CodeUnitCollection::fromList(CodeUnit::forInterfaceMethod($firstPart, $secondPart));
+ }
+
+ if ($this->isUserDefinedTrait($firstPart)) {
+ return CodeUnitCollection::fromList(CodeUnit::forTraitMethod($firstPart, $secondPart));
+ }
+ } else {
+ if ($this->isUserDefinedClass($unit)) {
+ $units = [CodeUnit::forClass($unit)];
+
+ foreach ($this->reflectorForClass($unit)->getTraits() as $trait) {
+ if (!$trait->isUserDefined()) {
+ // @codeCoverageIgnoreStart
+ continue;
+ // @codeCoverageIgnoreEnd
+ }
+
+ $units[] = CodeUnit::forTrait($trait->getName());
+ }
+
+ return CodeUnitCollection::fromArray($units);
+ }
+
+ if ($this->isUserDefinedInterface($unit)) {
+ return CodeUnitCollection::fromList(CodeUnit::forInterface($unit));
+ }
+
+ if ($this->isUserDefinedTrait($unit)) {
+ return CodeUnitCollection::fromList(CodeUnit::forTrait($unit));
+ }
+
+ if ($this->isUserDefinedFunction($unit)) {
+ return CodeUnitCollection::fromList(CodeUnit::forFunction($unit));
+ }
+
+ $unit = str_replace('<extended>', '', $unit);
+
+ if ($this->isUserDefinedClass($unit)) {
+ return $this->classAndParentClassesAndTraits($unit);
+ }
+ }
+
+ throw new InvalidCodeUnitException(
+ sprintf(
+ '"%s" is not a valid code unit',
+ $unit
+ )
+ );
+ }
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws ReflectionException
+ */
+ private function publicMethodsOfClass(string $className): CodeUnitCollection
+ {
+ return $this->methodsOfClass($className, ReflectionMethod::IS_PUBLIC);
+ }
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws ReflectionException
+ */
+ private function publicAndProtectedMethodsOfClass(string $className): CodeUnitCollection
+ {
+ return $this->methodsOfClass($className, ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED);
+ }
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws ReflectionException
+ */
+ private function publicAndPrivateMethodsOfClass(string $className): CodeUnitCollection
+ {
+ return $this->methodsOfClass($className, ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PRIVATE);
+ }
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws ReflectionException
+ */
+ private function protectedMethodsOfClass(string $className): CodeUnitCollection
+ {
+ return $this->methodsOfClass($className, ReflectionMethod::IS_PROTECTED);
+ }
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws ReflectionException
+ */
+ private function protectedAndPrivateMethodsOfClass(string $className): CodeUnitCollection
+ {
+ return $this->methodsOfClass($className, ReflectionMethod::IS_PROTECTED | ReflectionMethod::IS_PRIVATE);
+ }
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws ReflectionException
+ */
+ private function privateMethodsOfClass(string $className): CodeUnitCollection
+ {
+ return $this->methodsOfClass($className, ReflectionMethod::IS_PRIVATE);
+ }
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws ReflectionException
+ */
+ private function methodsOfClass(string $className, int $filter): CodeUnitCollection
+ {
+ $units = [];
+
+ foreach ($this->reflectorForClass($className)->getMethods($filter) as $method) {
+ if (!$method->isUserDefined()) {
+ continue;
+ }
+
+ $units[] = CodeUnit::forClassMethod($className, $method->getName());
+ }
+
+ return CodeUnitCollection::fromArray($units);
+ }
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws ReflectionException
+ */
+ private function classAndParentClassesAndTraits(string $className): CodeUnitCollection
+ {
+ $units = [CodeUnit::forClass($className)];
+
+ $reflector = $this->reflectorForClass($className);
+
+ foreach ($this->reflectorForClass($className)->getTraits() as $trait) {
+ if (!$trait->isUserDefined()) {
+ // @codeCoverageIgnoreStart
+ continue;
+ // @codeCoverageIgnoreEnd
+ }
+
+ $units[] = CodeUnit::forTrait($trait->getName());
+ }
+
+ while ($reflector = $reflector->getParentClass()) {
+ if (!$reflector->isUserDefined()) {
+ break;
+ }
+
+ $units[] = CodeUnit::forClass($reflector->getName());
+
+ foreach ($reflector->getTraits() as $trait) {
+ if (!$trait->isUserDefined()) {
+ // @codeCoverageIgnoreStart
+ continue;
+ // @codeCoverageIgnoreEnd
+ }
+
+ $units[] = CodeUnit::forTrait($trait->getName());
+ }
+ }
+
+ return CodeUnitCollection::fromArray($units);
+ }
+
+ /**
+ * @psalm-param class-string $className
+ *
+ * @throws ReflectionException
+ */
+ private function reflectorForClass(string $className): ReflectionClass
+ {
+ try {
+ return new ReflectionClass($className);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @throws ReflectionException
+ */
+ private function isUserDefinedFunction(string $functionName): bool
+ {
+ if (!function_exists($functionName)) {
+ return false;
+ }
+
+ try {
+ return (new ReflectionFunction($functionName))->isUserDefined();
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @throws ReflectionException
+ */
+ private function isUserDefinedClass(string $className): bool
+ {
+ if (!class_exists($className)) {
+ return false;
+ }
+
+ try {
+ return (new ReflectionClass($className))->isUserDefined();
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @throws ReflectionException
+ */
+ private function isUserDefinedInterface(string $interfaceName): bool
+ {
+ if (!interface_exists($interfaceName)) {
+ return false;
+ }
+
+ try {
+ return (new ReflectionClass($interfaceName))->isUserDefined();
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @throws ReflectionException
+ */
+ private function isUserDefinedTrait(string $traitName): bool
+ {
+ if (!trait_exists($traitName)) {
+ return false;
+ }
+
+ try {
+ return (new ReflectionClass($traitName))->isUserDefined();
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @throws ReflectionException
+ */
+ private function isUserDefinedMethod(string $className, string $methodName): bool
+ {
+ if (!class_exists($className)) {
+ // @codeCoverageIgnoreStart
+ return false;
+ // @codeCoverageIgnoreEnd
+ }
+
+ if (!method_exists($className, $methodName)) {
+ // @codeCoverageIgnoreStart
+ return false;
+ // @codeCoverageIgnoreEnd
+ }
+
+ try {
+ return (new ReflectionMethod($className, $methodName))->isUserDefined();
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+}
diff --git a/vendor/sebastian/code-unit/src/TraitMethodUnit.php b/vendor/sebastian/code-unit/src/TraitMethodUnit.php
new file mode 100644
index 000000000..a58f7249f
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/TraitMethodUnit.php
@@ -0,0 +1,24 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+/**
+ * @psalm-immutable
+ */
+final class TraitMethodUnit extends CodeUnit
+{
+ /**
+ * @psalm-assert-if-true TraitMethodUnit $this
+ */
+ public function isTraitMethod(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/sebastian/code-unit/src/TraitUnit.php b/vendor/sebastian/code-unit/src/TraitUnit.php
new file mode 100644
index 000000000..abddfc112
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/TraitUnit.php
@@ -0,0 +1,24 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+/**
+ * @psalm-immutable
+ */
+final class TraitUnit extends CodeUnit
+{
+ /**
+ * @psalm-assert-if-true TraitUnit $this
+ */
+ public function isTrait(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/sebastian/code-unit/src/exceptions/Exception.php b/vendor/sebastian/code-unit/src/exceptions/Exception.php
new file mode 100644
index 000000000..74d0eeef8
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/exceptions/Exception.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+use Throwable;
+
+interface Exception extends Throwable
+{
+}
diff --git a/vendor/sebastian/code-unit/src/exceptions/InvalidCodeUnitException.php b/vendor/sebastian/code-unit/src/exceptions/InvalidCodeUnitException.php
new file mode 100644
index 000000000..60a3da82b
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/exceptions/InvalidCodeUnitException.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+use RuntimeException;
+
+final class InvalidCodeUnitException extends RuntimeException implements Exception
+{
+}
diff --git a/vendor/sebastian/code-unit/src/exceptions/NoTraitException.php b/vendor/sebastian/code-unit/src/exceptions/NoTraitException.php
new file mode 100644
index 000000000..e9b9b9c7a
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/exceptions/NoTraitException.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+use RuntimeException;
+
+final class NoTraitException extends RuntimeException implements Exception
+{
+}
diff --git a/vendor/sebastian/code-unit/src/exceptions/ReflectionException.php b/vendor/sebastian/code-unit/src/exceptions/ReflectionException.php
new file mode 100644
index 000000000..232012783
--- /dev/null
+++ b/vendor/sebastian/code-unit/src/exceptions/ReflectionException.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/code-unit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\CodeUnit;
+
+use RuntimeException;
+
+final class ReflectionException extends RuntimeException implements Exception
+{
+}
diff --git a/vendor/sebastian/comparator/ChangeLog.md b/vendor/sebastian/comparator/ChangeLog.md
new file mode 100644
index 000000000..64c0251c1
--- /dev/null
+++ b/vendor/sebastian/comparator/ChangeLog.md
@@ -0,0 +1,108 @@
+# ChangeLog
+
+All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [4.0.6] - 2020-10-26
+
+### Fixed
+
+* `SebastianBergmann\Comparator\Exception` now correctly extends `\Throwable`
+
+## [4.0.5] - 2020-09-30
+
+### Fixed
+
+* [#89](https://github.com/sebastianbergmann/comparator/pull/89): Handle PHP 8 `ValueError`
+
+## [4.0.4] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [4.0.3] - 2020-06-26
+
+### Added
+
+* This component is now supported on PHP 8
+
+## [4.0.2] - 2020-06-15
+
+### Fixed
+
+* [#85](https://github.com/sebastianbergmann/comparator/issues/85): Version 4.0.1 breaks backward compatibility
+
+## [4.0.1] - 2020-06-15
+
+### Changed
+
+* Tests etc. are now ignored for archive exports
+
+## [4.0.0] - 2020-02-07
+
+### Removed
+
+* Removed support for PHP 7.1 and PHP 7.2
+
+## [3.0.2] - 2018-07-12
+
+### Changed
+
+* By default, `MockObjectComparator` is now tried before all other (default) comparators
+
+## [3.0.1] - 2018-06-14
+
+### Fixed
+
+* [#53](https://github.com/sebastianbergmann/comparator/pull/53): `DOMNodeComparator` ignores `$ignoreCase` parameter
+* [#58](https://github.com/sebastianbergmann/comparator/pull/58): `ScalarComparator` does not handle extremely ugly string comparison edge cases
+
+## [3.0.0] - 2018-04-18
+
+### Fixed
+
+* Fixed [#48](https://github.com/sebastianbergmann/comparator/issues/48): `DateTimeComparator` does not support fractional second deltas
+
+### Removed
+
+* Removed support for PHP 7.0
+
+## [2.1.3] - 2018-02-01
+
+### Changed
+
+* This component is now compatible with version 3 of `sebastian/diff`
+
+## [2.1.2] - 2018-01-12
+
+### Fixed
+
+* Fix comparison of `DateTimeImmutable` objects
+
+## [2.1.1] - 2017-12-22
+
+### Fixed
+
+* Fixed [phpunit/#2923](https://github.com/sebastianbergmann/phpunit/issues/2923): Unexpected failed date matching
+
+## [2.1.0] - 2017-11-03
+
+### Added
+
+* Added `SebastianBergmann\Comparator\Factory::reset()` to unregister all non-default comparators
+* Added support for `phpunit/phpunit-mock-objects` version `^5.0`
+
+[4.0.6]: https://github.com/sebastianbergmann/comparator/compare/4.0.5...4.0.6
+[4.0.5]: https://github.com/sebastianbergmann/comparator/compare/4.0.4...4.0.5
+[4.0.4]: https://github.com/sebastianbergmann/comparator/compare/4.0.3...4.0.4
+[4.0.3]: https://github.com/sebastianbergmann/comparator/compare/4.0.2...4.0.3
+[4.0.2]: https://github.com/sebastianbergmann/comparator/compare/4.0.1...4.0.2
+[4.0.1]: https://github.com/sebastianbergmann/comparator/compare/4.0.0...4.0.1
+[4.0.0]: https://github.com/sebastianbergmann/comparator/compare/3.0.2...4.0.0
+[3.0.2]: https://github.com/sebastianbergmann/comparator/compare/3.0.1...3.0.2
+[3.0.1]: https://github.com/sebastianbergmann/comparator/compare/3.0.0...3.0.1
+[3.0.0]: https://github.com/sebastianbergmann/comparator/compare/2.1.3...3.0.0
+[2.1.3]: https://github.com/sebastianbergmann/comparator/compare/2.1.2...2.1.3
+[2.1.2]: https://github.com/sebastianbergmann/comparator/compare/2.1.1...2.1.2
+[2.1.1]: https://github.com/sebastianbergmann/comparator/compare/2.1.0...2.1.1
+[2.1.0]: https://github.com/sebastianbergmann/comparator/compare/2.0.2...2.1.0
diff --git a/vendor/sebastian/comparator/LICENSE b/vendor/sebastian/comparator/LICENSE
new file mode 100644
index 000000000..6ad70cbaf
--- /dev/null
+++ b/vendor/sebastian/comparator/LICENSE
@@ -0,0 +1,33 @@
+Comparator
+
+Copyright (c) 2002-2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/comparator/README.md b/vendor/sebastian/comparator/README.md
new file mode 100644
index 000000000..f6002db65
--- /dev/null
+++ b/vendor/sebastian/comparator/README.md
@@ -0,0 +1,41 @@
+# sebastian/comparator
+
+[![CI Status](https://github.com/sebastianbergmann/comparator/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/comparator/actions)
+[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/comparator/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/comparator)
+
+This component provides the functionality to compare PHP values for equality.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/comparator
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/comparator
+```
+
+## Usage
+
+```php
+<?php
+use SebastianBergmann\Comparator\Factory;
+use SebastianBergmann\Comparator\ComparisonFailure;
+
+$date1 = new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York'));
+$date2 = new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/Chicago'));
+
+$factory = new Factory;
+$comparator = $factory->getComparatorFor($date1, $date2);
+
+try {
+ $comparator->assertEquals($date1, $date2);
+ print "Dates match";
+} catch (ComparisonFailure $failure) {
+ print "Dates don't match";
+}
+```
diff --git a/vendor/sebastian/comparator/composer.json b/vendor/sebastian/comparator/composer.json
new file mode 100644
index 000000000..b758e03c9
--- /dev/null
+++ b/vendor/sebastian/comparator/composer.json
@@ -0,0 +1,57 @@
+{
+ "name": "sebastian/comparator",
+ "description": "Provides the functionality to compare PHP values for equality",
+ "keywords": ["comparator","compare","equality"],
+ "homepage": "https://github.com/sebastianbergmann/comparator",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "[email protected]"
+ }
+ ],
+ "prefer-stable": true,
+ "require": {
+ "php": ">=7.3",
+ "sebastian/diff": "^4.0",
+ "sebastian/exporter": "^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "autoload-dev": {
+ "classmap": [
+ "tests/_fixture"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ }
+}
+
diff --git a/vendor/sebastian/comparator/src/ArrayComparator.php b/vendor/sebastian/comparator/src/ArrayComparator.php
new file mode 100644
index 000000000..5d9fbce6e
--- /dev/null
+++ b/vendor/sebastian/comparator/src/ArrayComparator.php
@@ -0,0 +1,141 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use function array_key_exists;
+use function is_array;
+use function sort;
+use function sprintf;
+use function str_replace;
+use function trim;
+
+/**
+ * Compares arrays for equality.
+ *
+ * Arrays are equal if they contain the same key-value pairs.
+ * The order of the keys does not matter.
+ * The types of key-value pairs do not matter.
+ */
+class ArrayComparator extends Comparator
+{
+ /**
+ * Returns whether the comparator can compare two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return bool
+ */
+ public function accepts($expected, $actual)
+ {
+ return is_array($expected) && is_array($actual);
+ }
+
+ /**
+ * Asserts that two arrays are equal.
+ *
+ * @param mixed $expected First value to compare
+ * @param mixed $actual Second value to compare
+ * @param float $delta Allowed numerical distance between two values to consider them equal
+ * @param bool $canonicalize Arrays are sorted before comparison when set to true
+ * @param bool $ignoreCase Case is ignored when set to true
+ * @param array $processed List of already processed elements (used to prevent infinite recursion)
+ *
+ * @throws ComparisonFailure
+ */
+ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = [])/*: void*/
+ {
+ if ($canonicalize) {
+ sort($expected);
+ sort($actual);
+ }
+
+ $remaining = $actual;
+ $actualAsString = "Array (\n";
+ $expectedAsString = "Array (\n";
+ $equal = true;
+
+ foreach ($expected as $key => $value) {
+ unset($remaining[$key]);
+
+ if (!array_key_exists($key, $actual)) {
+ $expectedAsString .= sprintf(
+ " %s => %s\n",
+ $this->exporter->export($key),
+ $this->exporter->shortenedExport($value)
+ );
+
+ $equal = false;
+
+ continue;
+ }
+
+ try {
+ $comparator = $this->factory->getComparatorFor($value, $actual[$key]);
+ $comparator->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed);
+
+ $expectedAsString .= sprintf(
+ " %s => %s\n",
+ $this->exporter->export($key),
+ $this->exporter->shortenedExport($value)
+ );
+
+ $actualAsString .= sprintf(
+ " %s => %s\n",
+ $this->exporter->export($key),
+ $this->exporter->shortenedExport($actual[$key])
+ );
+ } catch (ComparisonFailure $e) {
+ $expectedAsString .= sprintf(
+ " %s => %s\n",
+ $this->exporter->export($key),
+ $e->getExpectedAsString() ? $this->indent($e->getExpectedAsString()) : $this->exporter->shortenedExport($e->getExpected())
+ );
+
+ $actualAsString .= sprintf(
+ " %s => %s\n",
+ $this->exporter->export($key),
+ $e->getActualAsString() ? $this->indent($e->getActualAsString()) : $this->exporter->shortenedExport($e->getActual())
+ );
+
+ $equal = false;
+ }
+ }
+
+ foreach ($remaining as $key => $value) {
+ $actualAsString .= sprintf(
+ " %s => %s\n",
+ $this->exporter->export($key),
+ $this->exporter->shortenedExport($value)
+ );
+
+ $equal = false;
+ }
+
+ $expectedAsString .= ')';
+ $actualAsString .= ')';
+
+ if (!$equal) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $expectedAsString,
+ $actualAsString,
+ false,
+ 'Failed asserting that two arrays are equal.'
+ );
+ }
+ }
+
+ protected function indent($lines)
+ {
+ return trim(str_replace("\n", "\n ", $lines));
+ }
+}
diff --git a/vendor/sebastian/comparator/src/Comparator.php b/vendor/sebastian/comparator/src/Comparator.php
new file mode 100644
index 000000000..e1906c167
--- /dev/null
+++ b/vendor/sebastian/comparator/src/Comparator.php
@@ -0,0 +1,61 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use SebastianBergmann\Exporter\Exporter;
+
+/**
+ * Abstract base class for comparators which compare values for equality.
+ */
+abstract class Comparator
+{
+ /**
+ * @var Factory
+ */
+ protected $factory;
+
+ /**
+ * @var Exporter
+ */
+ protected $exporter;
+
+ public function __construct()
+ {
+ $this->exporter = new Exporter;
+ }
+
+ public function setFactory(Factory $factory)/*: void*/
+ {
+ $this->factory = $factory;
+ }
+
+ /**
+ * Returns whether the comparator can compare two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return bool
+ */
+ abstract public function accepts($expected, $actual);
+
+ /**
+ * Asserts that two values are equal.
+ *
+ * @param mixed $expected First value to compare
+ * @param mixed $actual Second value to compare
+ * @param float $delta Allowed numerical distance between two values to consider them equal
+ * @param bool $canonicalize Arrays are sorted before comparison when set to true
+ * @param bool $ignoreCase Case is ignored when set to true
+ *
+ * @throws ComparisonFailure
+ */
+ abstract public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false);
+}
diff --git a/vendor/sebastian/comparator/src/ComparisonFailure.php b/vendor/sebastian/comparator/src/ComparisonFailure.php
new file mode 100644
index 000000000..857314daa
--- /dev/null
+++ b/vendor/sebastian/comparator/src/ComparisonFailure.php
@@ -0,0 +1,129 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use RuntimeException;
+use SebastianBergmann\Diff\Differ;
+use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
+
+/**
+ * Thrown when an assertion for string equality failed.
+ */
+class ComparisonFailure extends RuntimeException
+{
+ /**
+ * Expected value of the retrieval which does not match $actual.
+ *
+ * @var mixed
+ */
+ protected $expected;
+
+ /**
+ * Actually retrieved value which does not match $expected.
+ *
+ * @var mixed
+ */
+ protected $actual;
+
+ /**
+ * The string representation of the expected value.
+ *
+ * @var string
+ */
+ protected $expectedAsString;
+
+ /**
+ * The string representation of the actual value.
+ *
+ * @var string
+ */
+ protected $actualAsString;
+
+ /**
+ * @var bool
+ */
+ protected $identical;
+
+ /**
+ * Optional message which is placed in front of the first line
+ * returned by toString().
+ *
+ * @var string
+ */
+ protected $message;
+
+ /**
+ * Initialises with the expected value and the actual value.
+ *
+ * @param mixed $expected expected value retrieved
+ * @param mixed $actual actual value retrieved
+ * @param string $expectedAsString
+ * @param string $actualAsString
+ * @param bool $identical
+ * @param string $message a string which is prefixed on all returned lines
+ * in the difference output
+ */
+ public function __construct($expected, $actual, $expectedAsString, $actualAsString, $identical = false, $message = '')
+ {
+ $this->expected = $expected;
+ $this->actual = $actual;
+ $this->expectedAsString = $expectedAsString;
+ $this->actualAsString = $actualAsString;
+ $this->message = $message;
+ }
+
+ public function getActual()
+ {
+ return $this->actual;
+ }
+
+ public function getExpected()
+ {
+ return $this->expected;
+ }
+
+ /**
+ * @return string
+ */
+ public function getActualAsString()
+ {
+ return $this->actualAsString;
+ }
+
+ /**
+ * @return string
+ */
+ public function getExpectedAsString()
+ {
+ return $this->expectedAsString;
+ }
+
+ /**
+ * @return string
+ */
+ public function getDiff()
+ {
+ if (!$this->actualAsString && !$this->expectedAsString) {
+ return '';
+ }
+
+ $differ = new Differ(new UnifiedDiffOutputBuilder("\n--- Expected\n+++ Actual\n"));
+
+ return $differ->diff($this->expectedAsString, $this->actualAsString);
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ return $this->message . $this->getDiff();
+ }
+}
diff --git a/vendor/sebastian/comparator/src/DOMNodeComparator.php b/vendor/sebastian/comparator/src/DOMNodeComparator.php
new file mode 100644
index 000000000..5bf854eae
--- /dev/null
+++ b/vendor/sebastian/comparator/src/DOMNodeComparator.php
@@ -0,0 +1,93 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use function sprintf;
+use function strtolower;
+use DOMDocument;
+use DOMNode;
+use ValueError;
+
+/**
+ * Compares DOMNode instances for equality.
+ */
+class DOMNodeComparator extends ObjectComparator
+{
+ /**
+ * Returns whether the comparator can compare two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return bool
+ */
+ public function accepts($expected, $actual)
+ {
+ return $expected instanceof DOMNode && $actual instanceof DOMNode;
+ }
+
+ /**
+ * Asserts that two values are equal.
+ *
+ * @param mixed $expected First value to compare
+ * @param mixed $actual Second value to compare
+ * @param float $delta Allowed numerical distance between two values to consider them equal
+ * @param bool $canonicalize Arrays are sorted before comparison when set to true
+ * @param bool $ignoreCase Case is ignored when set to true
+ * @param array $processed List of already processed elements (used to prevent infinite recursion)
+ *
+ * @throws ComparisonFailure
+ */
+ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = [])/*: void*/
+ {
+ $expectedAsString = $this->nodeToText($expected, true, $ignoreCase);
+ $actualAsString = $this->nodeToText($actual, true, $ignoreCase);
+
+ if ($expectedAsString !== $actualAsString) {
+ $type = $expected instanceof DOMDocument ? 'documents' : 'nodes';
+
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $expectedAsString,
+ $actualAsString,
+ false,
+ sprintf("Failed asserting that two DOM %s are equal.\n", $type)
+ );
+ }
+ }
+
+ /**
+ * Returns the normalized, whitespace-cleaned, and indented textual
+ * representation of a DOMNode.
+ */
+ private function nodeToText(DOMNode $node, bool $canonicalize, bool $ignoreCase): string
+ {
+ if ($canonicalize) {
+ $document = new DOMDocument;
+
+ try {
+ @$document->loadXML($node->C14N());
+ } catch (ValueError $e) {
+ }
+
+ $node = $document;
+ }
+
+ $document = $node instanceof DOMDocument ? $node : $node->ownerDocument;
+
+ $document->formatOutput = true;
+ $document->normalizeDocument();
+
+ $text = $node instanceof DOMDocument ? $node->saveXML() : $document->saveXML($node);
+
+ return $ignoreCase ? strtolower($text) : $text;
+ }
+}
diff --git a/vendor/sebastian/comparator/src/DateTimeComparator.php b/vendor/sebastian/comparator/src/DateTimeComparator.php
new file mode 100644
index 000000000..0a303b623
--- /dev/null
+++ b/vendor/sebastian/comparator/src/DateTimeComparator.php
@@ -0,0 +1,95 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use function abs;
+use function floor;
+use function sprintf;
+use DateInterval;
+use DateTime;
+use DateTimeInterface;
+use DateTimeZone;
+use Exception;
+
+/**
+ * Compares DateTimeInterface instances for equality.
+ */
+class DateTimeComparator extends ObjectComparator
+{
+ /**
+ * Returns whether the comparator can compare two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return bool
+ */
+ public function accepts($expected, $actual)
+ {
+ return ($expected instanceof DateTime || $expected instanceof DateTimeInterface) &&
+ ($actual instanceof DateTime || $actual instanceof DateTimeInterface);
+ }
+
+ /**
+ * Asserts that two values are equal.
+ *
+ * @param mixed $expected First value to compare
+ * @param mixed $actual Second value to compare
+ * @param float $delta Allowed numerical distance between two values to consider them equal
+ * @param bool $canonicalize Arrays are sorted before comparison when set to true
+ * @param bool $ignoreCase Case is ignored when set to true
+ * @param array $processed List of already processed elements (used to prevent infinite recursion)
+ *
+ * @throws Exception
+ * @throws ComparisonFailure
+ */
+ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = [])/*: void*/
+ {
+ /** @var DateTimeInterface $expected */
+ /** @var DateTimeInterface $actual */
+ $absDelta = abs($delta);
+ $delta = new DateInterval(sprintf('PT%dS', $absDelta));
+ $delta->f = $absDelta - floor($absDelta);
+
+ $actualClone = (clone $actual)
+ ->setTimezone(new DateTimeZone('UTC'));
+
+ $expectedLower = (clone $expected)
+ ->setTimezone(new DateTimeZone('UTC'))
+ ->sub($delta);
+
+ $expectedUpper = (clone $expected)
+ ->setTimezone(new DateTimeZone('UTC'))
+ ->add($delta);
+
+ if ($actualClone < $expectedLower || $actualClone > $expectedUpper) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $this->dateTimeToString($expected),
+ $this->dateTimeToString($actual),
+ false,
+ 'Failed asserting that two DateTime objects are equal.'
+ );
+ }
+ }
+
+ /**
+ * Returns an ISO 8601 formatted string representation of a datetime or
+ * 'Invalid DateTimeInterface object' if the provided DateTimeInterface was not properly
+ * initialized.
+ */
+ private function dateTimeToString(DateTimeInterface $datetime): string
+ {
+ $string = $datetime->format('Y-m-d\TH:i:s.uO');
+
+ return $string ?: 'Invalid DateTimeInterface object';
+ }
+}
diff --git a/vendor/sebastian/comparator/src/DoubleComparator.php b/vendor/sebastian/comparator/src/DoubleComparator.php
new file mode 100644
index 000000000..d90b9e06b
--- /dev/null
+++ b/vendor/sebastian/comparator/src/DoubleComparator.php
@@ -0,0 +1,59 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use function is_float;
+use function is_numeric;
+
+/**
+ * Compares doubles for equality.
+ */
+class DoubleComparator extends NumericComparator
+{
+ /**
+ * Smallest value available in PHP.
+ *
+ * @var float
+ */
+ public const EPSILON = 0.0000000001;
+
+ /**
+ * Returns whether the comparator can compare two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return bool
+ */
+ public function accepts($expected, $actual)
+ {
+ return (is_float($expected) || is_float($actual)) && is_numeric($expected) && is_numeric($actual);
+ }
+
+ /**
+ * Asserts that two values are equal.
+ *
+ * @param mixed $expected First value to compare
+ * @param mixed $actual Second value to compare
+ * @param float $delta Allowed numerical distance between two values to consider them equal
+ * @param bool $canonicalize Arrays are sorted before comparison when set to true
+ * @param bool $ignoreCase Case is ignored when set to true
+ *
+ * @throws ComparisonFailure
+ */
+ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/
+ {
+ if ($delta == 0) {
+ $delta = self::EPSILON;
+ }
+
+ parent::assertEquals($expected, $actual, $delta, $canonicalize, $ignoreCase);
+ }
+}
diff --git a/vendor/sebastian/comparator/src/ExceptionComparator.php b/vendor/sebastian/comparator/src/ExceptionComparator.php
new file mode 100644
index 000000000..1fc0174ef
--- /dev/null
+++ b/vendor/sebastian/comparator/src/ExceptionComparator.php
@@ -0,0 +1,54 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use Exception;
+
+/**
+ * Compares Exception instances for equality.
+ */
+class ExceptionComparator extends ObjectComparator
+{
+ /**
+ * Returns whether the comparator can compare two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return bool
+ */
+ public function accepts($expected, $actual)
+ {
+ return $expected instanceof Exception && $actual instanceof Exception;
+ }
+
+ /**
+ * Converts an object to an array containing all of its private, protected
+ * and public properties.
+ *
+ * @param object $object
+ *
+ * @return array
+ */
+ protected function toArray($object)
+ {
+ $array = parent::toArray($object);
+
+ unset(
+ $array['file'],
+ $array['line'],
+ $array['trace'],
+ $array['string'],
+ $array['xdebug_message']
+ );
+
+ return $array;
+ }
+}
diff --git a/vendor/sebastian/comparator/src/Factory.php b/vendor/sebastian/comparator/src/Factory.php
new file mode 100644
index 000000000..5b16366f0
--- /dev/null
+++ b/vendor/sebastian/comparator/src/Factory.php
@@ -0,0 +1,142 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use function array_unshift;
+
+/**
+ * Factory for comparators which compare values for equality.
+ */
+class Factory
+{
+ /**
+ * @var Factory
+ */
+ private static $instance;
+
+ /**
+ * @var Comparator[]
+ */
+ private $customComparators = [];
+
+ /**
+ * @var Comparator[]
+ */
+ private $defaultComparators = [];
+
+ /**
+ * @return Factory
+ */
+ public static function getInstance()
+ {
+ if (self::$instance === null) {
+ self::$instance = new self; // @codeCoverageIgnore
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * Constructs a new factory.
+ */
+ public function __construct()
+ {
+ $this->registerDefaultComparators();
+ }
+
+ /**
+ * Returns the correct comparator for comparing two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return Comparator
+ */
+ public function getComparatorFor($expected, $actual)
+ {
+ foreach ($this->customComparators as $comparator) {
+ if ($comparator->accepts($expected, $actual)) {
+ return $comparator;
+ }
+ }
+
+ foreach ($this->defaultComparators as $comparator) {
+ if ($comparator->accepts($expected, $actual)) {
+ return $comparator;
+ }
+ }
+
+ throw new RuntimeException('No suitable Comparator implementation found');
+ }
+
+ /**
+ * Registers a new comparator.
+ *
+ * This comparator will be returned by getComparatorFor() if its accept() method
+ * returns TRUE for the compared values. It has higher priority than the
+ * existing comparators, meaning that its accept() method will be invoked
+ * before those of the other comparators.
+ *
+ * @param Comparator $comparator The comparator to be registered
+ */
+ public function register(Comparator $comparator)/*: void*/
+ {
+ array_unshift($this->customComparators, $comparator);
+
+ $comparator->setFactory($this);
+ }
+
+ /**
+ * Unregisters a comparator.
+ *
+ * This comparator will no longer be considered by getComparatorFor().
+ *
+ * @param Comparator $comparator The comparator to be unregistered
+ */
+ public function unregister(Comparator $comparator)/*: void*/
+ {
+ foreach ($this->customComparators as $key => $_comparator) {
+ if ($comparator === $_comparator) {
+ unset($this->customComparators[$key]);
+ }
+ }
+ }
+
+ /**
+ * Unregisters all non-default comparators.
+ */
+ public function reset()/*: void*/
+ {
+ $this->customComparators = [];
+ }
+
+ private function registerDefaultComparators(): void
+ {
+ $this->registerDefaultComparator(new MockObjectComparator);
+ $this->registerDefaultComparator(new DateTimeComparator);
+ $this->registerDefaultComparator(new DOMNodeComparator);
+ $this->registerDefaultComparator(new SplObjectStorageComparator);
+ $this->registerDefaultComparator(new ExceptionComparator);
+ $this->registerDefaultComparator(new ObjectComparator);
+ $this->registerDefaultComparator(new ResourceComparator);
+ $this->registerDefaultComparator(new ArrayComparator);
+ $this->registerDefaultComparator(new DoubleComparator);
+ $this->registerDefaultComparator(new NumericComparator);
+ $this->registerDefaultComparator(new ScalarComparator);
+ $this->registerDefaultComparator(new TypeComparator);
+ }
+
+ private function registerDefaultComparator(Comparator $comparator): void
+ {
+ $this->defaultComparators[] = $comparator;
+
+ $comparator->setFactory($this);
+ }
+}
diff --git a/vendor/sebastian/comparator/src/MockObjectComparator.php b/vendor/sebastian/comparator/src/MockObjectComparator.php
new file mode 100644
index 000000000..cb6703161
--- /dev/null
+++ b/vendor/sebastian/comparator/src/MockObjectComparator.php
@@ -0,0 +1,48 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use PHPUnit\Framework\MockObject\MockObject;
+
+/**
+ * Compares PHPUnit\Framework\MockObject\MockObject instances for equality.
+ */
+class MockObjectComparator extends ObjectComparator
+{
+ /**
+ * Returns whether the comparator can compare two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return bool
+ */
+ public function accepts($expected, $actual)
+ {
+ return $expected instanceof MockObject && $actual instanceof MockObject;
+ }
+
+ /**
+ * Converts an object to an array containing all of its private, protected
+ * and public properties.
+ *
+ * @param object $object
+ *
+ * @return array
+ */
+ protected function toArray($object)
+ {
+ $array = parent::toArray($object);
+
+ unset($array['__phpunit_invocationMocker']);
+
+ return $array;
+ }
+}
diff --git a/vendor/sebastian/comparator/src/NumericComparator.php b/vendor/sebastian/comparator/src/NumericComparator.php
new file mode 100644
index 000000000..12e6721d6
--- /dev/null
+++ b/vendor/sebastian/comparator/src/NumericComparator.php
@@ -0,0 +1,86 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use function abs;
+use function is_float;
+use function is_infinite;
+use function is_nan;
+use function is_numeric;
+use function is_string;
+use function sprintf;
+
+/**
+ * Compares numerical values for equality.
+ */
+class NumericComparator extends ScalarComparator
+{
+ /**
+ * Returns whether the comparator can compare two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return bool
+ */
+ public function accepts($expected, $actual)
+ {
+ // all numerical values, but not if one of them is a double
+ // or both of them are strings
+ return is_numeric($expected) && is_numeric($actual) &&
+ !(is_float($expected) || is_float($actual)) &&
+ !(is_string($expected) && is_string($actual));
+ }
+
+ /**
+ * Asserts that two values are equal.
+ *
+ * @param mixed $expected First value to compare
+ * @param mixed $actual Second value to compare
+ * @param float $delta Allowed numerical distance between two values to consider them equal
+ * @param bool $canonicalize Arrays are sorted before comparison when set to true
+ * @param bool $ignoreCase Case is ignored when set to true
+ *
+ * @throws ComparisonFailure
+ */
+ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/
+ {
+ if ($this->isInfinite($actual) && $this->isInfinite($expected)) {
+ return;
+ }
+
+ if (($this->isInfinite($actual) xor $this->isInfinite($expected)) ||
+ ($this->isNan($actual) || $this->isNan($expected)) ||
+ abs($actual - $expected) > $delta) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ '',
+ '',
+ false,
+ sprintf(
+ 'Failed asserting that %s matches expected %s.',
+ $this->exporter->export($actual),
+ $this->exporter->export($expected)
+ )
+ );
+ }
+ }
+
+ private function isInfinite($value): bool
+ {
+ return is_float($value) && is_infinite($value);
+ }
+
+ private function isNan($value): bool
+ {
+ return is_float($value) && is_nan($value);
+ }
+}
diff --git a/vendor/sebastian/comparator/src/ObjectComparator.php b/vendor/sebastian/comparator/src/ObjectComparator.php
new file mode 100644
index 000000000..9380ba150
--- /dev/null
+++ b/vendor/sebastian/comparator/src/ObjectComparator.php
@@ -0,0 +1,112 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use function get_class;
+use function in_array;
+use function is_object;
+use function sprintf;
+use function substr_replace;
+
+/**
+ * Compares objects for equality.
+ */
+class ObjectComparator extends ArrayComparator
+{
+ /**
+ * Returns whether the comparator can compare two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return bool
+ */
+ public function accepts($expected, $actual)
+ {
+ return is_object($expected) && is_object($actual);
+ }
+
+ /**
+ * Asserts that two values are equal.
+ *
+ * @param mixed $expected First value to compare
+ * @param mixed $actual Second value to compare
+ * @param float $delta Allowed numerical distance between two values to consider them equal
+ * @param bool $canonicalize Arrays are sorted before comparison when set to true
+ * @param bool $ignoreCase Case is ignored when set to true
+ * @param array $processed List of already processed elements (used to prevent infinite recursion)
+ *
+ * @throws ComparisonFailure
+ */
+ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = [])/*: void*/
+ {
+ if (get_class($actual) !== get_class($expected)) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $this->exporter->export($expected),
+ $this->exporter->export($actual),
+ false,
+ sprintf(
+ '%s is not instance of expected class "%s".',
+ $this->exporter->export($actual),
+ get_class($expected)
+ )
+ );
+ }
+
+ // don't compare twice to allow for cyclic dependencies
+ if (in_array([$actual, $expected], $processed, true) ||
+ in_array([$expected, $actual], $processed, true)) {
+ return;
+ }
+
+ $processed[] = [$actual, $expected];
+
+ // don't compare objects if they are identical
+ // this helps to avoid the error "maximum function nesting level reached"
+ // CAUTION: this conditional clause is not tested
+ if ($actual !== $expected) {
+ try {
+ parent::assertEquals(
+ $this->toArray($expected),
+ $this->toArray($actual),
+ $delta,
+ $canonicalize,
+ $ignoreCase,
+ $processed
+ );
+ } catch (ComparisonFailure $e) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ // replace "Array" with "MyClass object"
+ substr_replace($e->getExpectedAsString(), get_class($expected) . ' Object', 0, 5),
+ substr_replace($e->getActualAsString(), get_class($actual) . ' Object', 0, 5),
+ false,
+ 'Failed asserting that two objects are equal.'
+ );
+ }
+ }
+ }
+
+ /**
+ * Converts an object to an array containing all of its private, protected
+ * and public properties.
+ *
+ * @param object $object
+ *
+ * @return array
+ */
+ protected function toArray($object)
+ {
+ return $this->exporter->toArray($object);
+ }
+}
diff --git a/vendor/sebastian/comparator/src/ResourceComparator.php b/vendor/sebastian/comparator/src/ResourceComparator.php
new file mode 100644
index 000000000..7822598b1
--- /dev/null
+++ b/vendor/sebastian/comparator/src/ResourceComparator.php
@@ -0,0 +1,54 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use function is_resource;
+
+/**
+ * Compares resources for equality.
+ */
+class ResourceComparator extends Comparator
+{
+ /**
+ * Returns whether the comparator can compare two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return bool
+ */
+ public function accepts($expected, $actual)
+ {
+ return is_resource($expected) && is_resource($actual);
+ }
+
+ /**
+ * Asserts that two values are equal.
+ *
+ * @param mixed $expected First value to compare
+ * @param mixed $actual Second value to compare
+ * @param float $delta Allowed numerical distance between two values to consider them equal
+ * @param bool $canonicalize Arrays are sorted before comparison when set to true
+ * @param bool $ignoreCase Case is ignored when set to true
+ *
+ * @throws ComparisonFailure
+ */
+ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/
+ {
+ if ($actual != $expected) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $this->exporter->export($expected),
+ $this->exporter->export($actual)
+ );
+ }
+ }
+}
diff --git a/vendor/sebastian/comparator/src/ScalarComparator.php b/vendor/sebastian/comparator/src/ScalarComparator.php
new file mode 100644
index 000000000..08ded922b
--- /dev/null
+++ b/vendor/sebastian/comparator/src/ScalarComparator.php
@@ -0,0 +1,98 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use function is_object;
+use function is_scalar;
+use function is_string;
+use function method_exists;
+use function sprintf;
+use function strtolower;
+
+/**
+ * Compares scalar or NULL values for equality.
+ */
+class ScalarComparator extends Comparator
+{
+ /**
+ * Returns whether the comparator can compare two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return bool
+ *
+ * @since Method available since Release 3.6.0
+ */
+ public function accepts($expected, $actual)
+ {
+ return ((is_scalar($expected) xor null === $expected) &&
+ (is_scalar($actual) xor null === $actual))
+ // allow comparison between strings and objects featuring __toString()
+ || (is_string($expected) && is_object($actual) && method_exists($actual, '__toString'))
+ || (is_object($expected) && method_exists($expected, '__toString') && is_string($actual));
+ }
+
+ /**
+ * Asserts that two values are equal.
+ *
+ * @param mixed $expected First value to compare
+ * @param mixed $actual Second value to compare
+ * @param float $delta Allowed numerical distance between two values to consider them equal
+ * @param bool $canonicalize Arrays are sorted before comparison when set to true
+ * @param bool $ignoreCase Case is ignored when set to true
+ *
+ * @throws ComparisonFailure
+ */
+ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/
+ {
+ $expectedToCompare = $expected;
+ $actualToCompare = $actual;
+
+ // always compare as strings to avoid strange behaviour
+ // otherwise 0 == 'Foobar'
+ if (is_string($expected) || is_string($actual)) {
+ $expectedToCompare = (string) $expectedToCompare;
+ $actualToCompare = (string) $actualToCompare;
+
+ if ($ignoreCase) {
+ $expectedToCompare = strtolower($expectedToCompare);
+ $actualToCompare = strtolower($actualToCompare);
+ }
+ }
+
+ if ($expectedToCompare !== $actualToCompare && is_string($expected) && is_string($actual)) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $this->exporter->export($expected),
+ $this->exporter->export($actual),
+ false,
+ 'Failed asserting that two strings are equal.'
+ );
+ }
+
+ if ($expectedToCompare != $actualToCompare) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ // no diff is required
+ '',
+ '',
+ false,
+ sprintf(
+ 'Failed asserting that %s matches expected %s.',
+ $this->exporter->export($actual),
+ $this->exporter->export($expected)
+ )
+ );
+ }
+ }
+}
diff --git a/vendor/sebastian/comparator/src/SplObjectStorageComparator.php b/vendor/sebastian/comparator/src/SplObjectStorageComparator.php
new file mode 100644
index 000000000..d9b6f541a
--- /dev/null
+++ b/vendor/sebastian/comparator/src/SplObjectStorageComparator.php
@@ -0,0 +1,71 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use SplObjectStorage;
+
+/**
+ * Compares \SplObjectStorage instances for equality.
+ */
+class SplObjectStorageComparator extends Comparator
+{
+ /**
+ * Returns whether the comparator can compare two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return bool
+ */
+ public function accepts($expected, $actual)
+ {
+ return $expected instanceof SplObjectStorage && $actual instanceof SplObjectStorage;
+ }
+
+ /**
+ * Asserts that two values are equal.
+ *
+ * @param mixed $expected First value to compare
+ * @param mixed $actual Second value to compare
+ * @param float $delta Allowed numerical distance between two values to consider them equal
+ * @param bool $canonicalize Arrays are sorted before comparison when set to true
+ * @param bool $ignoreCase Case is ignored when set to true
+ *
+ * @throws ComparisonFailure
+ */
+ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/
+ {
+ foreach ($actual as $object) {
+ if (!$expected->contains($object)) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $this->exporter->export($expected),
+ $this->exporter->export($actual),
+ false,
+ 'Failed asserting that two objects are equal.'
+ );
+ }
+ }
+
+ foreach ($expected as $object) {
+ if (!$actual->contains($object)) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $this->exporter->export($expected),
+ $this->exporter->export($actual),
+ false,
+ 'Failed asserting that two objects are equal.'
+ );
+ }
+ }
+ }
+}
diff --git a/vendor/sebastian/comparator/src/TypeComparator.php b/vendor/sebastian/comparator/src/TypeComparator.php
new file mode 100644
index 000000000..b0d38d72e
--- /dev/null
+++ b/vendor/sebastian/comparator/src/TypeComparator.php
@@ -0,0 +1,62 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use function gettype;
+use function sprintf;
+
+/**
+ * Compares values for type equality.
+ */
+class TypeComparator extends Comparator
+{
+ /**
+ * Returns whether the comparator can compare two values.
+ *
+ * @param mixed $expected The first value to compare
+ * @param mixed $actual The second value to compare
+ *
+ * @return bool
+ */
+ public function accepts($expected, $actual)
+ {
+ return true;
+ }
+
+ /**
+ * Asserts that two values are equal.
+ *
+ * @param mixed $expected First value to compare
+ * @param mixed $actual Second value to compare
+ * @param float $delta Allowed numerical distance between two values to consider them equal
+ * @param bool $canonicalize Arrays are sorted before comparison when set to true
+ * @param bool $ignoreCase Case is ignored when set to true
+ *
+ * @throws ComparisonFailure
+ */
+ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/
+ {
+ if (gettype($expected) != gettype($actual)) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ // we don't need a diff
+ '',
+ '',
+ false,
+ sprintf(
+ '%s does not match expected type "%s".',
+ $this->exporter->shortenedExport($actual),
+ gettype($expected)
+ )
+ );
+ }
+ }
+}
diff --git a/vendor/sebastian/comparator/src/exceptions/Exception.php b/vendor/sebastian/comparator/src/exceptions/Exception.php
new file mode 100644
index 000000000..8975aaf1b
--- /dev/null
+++ b/vendor/sebastian/comparator/src/exceptions/Exception.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+use Throwable;
+
+interface Exception extends Throwable
+{
+}
diff --git a/vendor/sebastian/comparator/src/exceptions/RuntimeException.php b/vendor/sebastian/comparator/src/exceptions/RuntimeException.php
new file mode 100644
index 000000000..ca726084a
--- /dev/null
+++ b/vendor/sebastian/comparator/src/exceptions/RuntimeException.php
@@ -0,0 +1,14 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/comparator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Comparator;
+
+final class RuntimeException extends \RuntimeException implements Exception
+{
+}
diff --git a/vendor/sebastian/complexity/.psalm/baseline.xml b/vendor/sebastian/complexity/.psalm/baseline.xml
new file mode 100644
index 000000000..77e688e07
--- /dev/null
+++ b/vendor/sebastian/complexity/.psalm/baseline.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44"/>
diff --git a/vendor/sebastian/complexity/.psalm/config.xml b/vendor/sebastian/complexity/.psalm/config.xml
new file mode 100644
index 000000000..8172fe15a
--- /dev/null
+++ b/vendor/sebastian/complexity/.psalm/config.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<psalm
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="https://getpsalm.org/schema/config"
+ xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
+ resolveFromConfigFile="false"
+ errorBaseline=".psalm/baseline.xml"
+ totallyTyped="true"
+>
+ <projectFiles>
+ <directory name="src" />
+ <ignoreFiles>
+ <directory name="vendor" />
+ </ignoreFiles>
+ </projectFiles>
+</psalm>
diff --git a/vendor/sebastian/complexity/ChangeLog.md b/vendor/sebastian/complexity/ChangeLog.md
new file mode 100644
index 000000000..cb93ff620
--- /dev/null
+++ b/vendor/sebastian/complexity/ChangeLog.md
@@ -0,0 +1,30 @@
+# ChangeLog
+
+All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
+
+## [2.0.2] - 2020-10-26
+
+### Fixed
+
+* `SebastianBergmann\Complexity\Exception` now correctly extends `\Throwable`
+
+## [2.0.1] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [2.0.0] - 2020-07-25
+
+### Removed
+
+* The `ParentConnectingVisitor` has been removed (it should have been marked as `@internal`)
+
+## [1.0.0] - 2020-07-22
+
+* Initial release
+
+[2.0.2]: https://github.com/sebastianbergmann/complexity/compare/2.0.1...2.0.2
+[2.0.1]: https://github.com/sebastianbergmann/complexity/compare/2.0.0...2.0.1
+[2.0.0]: https://github.com/sebastianbergmann/complexity/compare/1.0.0...2.0.0
+[1.0.0]: https://github.com/sebastianbergmann/complexity/compare/70ee0ad32d9e2be3f85beffa3e2eb474193f2487...1.0.0
diff --git a/vendor/sebastian/complexity/LICENSE b/vendor/sebastian/complexity/LICENSE
new file mode 100644
index 000000000..5f818df69
--- /dev/null
+++ b/vendor/sebastian/complexity/LICENSE
@@ -0,0 +1,33 @@
+sebastian/complexity
+
+Copyright (c) 2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/complexity/README.md b/vendor/sebastian/complexity/README.md
new file mode 100644
index 000000000..5f53b0b5d
--- /dev/null
+++ b/vendor/sebastian/complexity/README.md
@@ -0,0 +1,22 @@
+# sebastian/complexity
+
+Library for calculating the complexity of PHP code units.
+
+[![Latest Stable Version](https://img.shields.io/packagist/v/sebastian/complexity.svg?style=flat-square)](https://packagist.org/packages/sebastian/complexity)
+[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.3-8892BF.svg?style=flat-square)](https://php.net/)
+[![CI Status](https://github.com/sebastianbergmann/complexity/workflows/CI/badge.svg?branch=master&event=push)](https://phpunit.de/build-status.html)
+[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/complexity/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/complexity)
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/complexity
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/complexity
+```
diff --git a/vendor/sebastian/complexity/composer.json b/vendor/sebastian/complexity/composer.json
new file mode 100644
index 000000000..7aa38314e
--- /dev/null
+++ b/vendor/sebastian/complexity/composer.json
@@ -0,0 +1,41 @@
+{
+ "name": "sebastian/complexity",
+ "description": "Library for calculating the complexity of PHP code units",
+ "type": "library",
+ "homepage": "https://github.com/sebastianbergmann/complexity",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/complexity/issues"
+ },
+ "require": {
+ "php": ">=7.3",
+ "nikic/php-parser": "^4.7"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/complexity/src/Calculator.php b/vendor/sebastian/complexity/src/Calculator.php
new file mode 100644
index 000000000..9abdcd169
--- /dev/null
+++ b/vendor/sebastian/complexity/src/Calculator.php
@@ -0,0 +1,88 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/complexity.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Complexity;
+
+use PhpParser\Error;
+use PhpParser\Lexer;
+use PhpParser\Node;
+use PhpParser\NodeTraverser;
+use PhpParser\NodeVisitor\NameResolver;
+use PhpParser\NodeVisitor\ParentConnectingVisitor;
+use PhpParser\Parser;
+use PhpParser\ParserFactory;
+
+final class Calculator
+{
+ /**
+ * @throws RuntimeException
+ */
+ public function calculateForSourceFile(string $sourceFile): ComplexityCollection
+ {
+ return $this->calculateForSourceString(file_get_contents($sourceFile));
+ }
+
+ /**
+ * @throws RuntimeException
+ */
+ public function calculateForSourceString(string $source): ComplexityCollection
+ {
+ try {
+ $nodes = $this->parser()->parse($source);
+
+ assert($nodes !== null);
+
+ return $this->calculateForAbstractSyntaxTree($nodes);
+
+ // @codeCoverageIgnoreStart
+ } catch (Error $error) {
+ throw new RuntimeException(
+ $error->getMessage(),
+ (int) $error->getCode(),
+ $error
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @param Node[] $nodes
+ *
+ * @throws RuntimeException
+ */
+ public function calculateForAbstractSyntaxTree(array $nodes): ComplexityCollection
+ {
+ $traverser = new NodeTraverser;
+ $complexityCalculatingVisitor = new ComplexityCalculatingVisitor(true);
+
+ $traverser->addVisitor(new NameResolver);
+ $traverser->addVisitor(new ParentConnectingVisitor);
+ $traverser->addVisitor($complexityCalculatingVisitor);
+
+ try {
+ /* @noinspection UnusedFunctionResultInspection */
+ $traverser->traverse($nodes);
+ // @codeCoverageIgnoreStart
+ } catch (Error $error) {
+ throw new RuntimeException(
+ $error->getMessage(),
+ (int) $error->getCode(),
+ $error
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ return $complexityCalculatingVisitor->result();
+ }
+
+ private function parser(): Parser
+ {
+ return (new ParserFactory)->create(ParserFactory::PREFER_PHP7, new Lexer);
+ }
+}
diff --git a/vendor/sebastian/complexity/src/Complexity/Complexity.php b/vendor/sebastian/complexity/src/Complexity/Complexity.php
new file mode 100644
index 000000000..dc6708dde
--- /dev/null
+++ b/vendor/sebastian/complexity/src/Complexity/Complexity.php
@@ -0,0 +1,42 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/complexity.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Complexity;
+
+/**
+ * @psalm-immutable
+ */
+final class Complexity
+{
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @var int
+ */
+ private $cyclomaticComplexity;
+
+ public function __construct(string $name, int $cyclomaticComplexity)
+ {
+ $this->name = $name;
+ $this->cyclomaticComplexity = $cyclomaticComplexity;
+ }
+
+ public function name(): string
+ {
+ return $this->name;
+ }
+
+ public function cyclomaticComplexity(): int
+ {
+ return $this->cyclomaticComplexity;
+ }
+}
diff --git a/vendor/sebastian/complexity/src/Complexity/ComplexityCollection.php b/vendor/sebastian/complexity/src/Complexity/ComplexityCollection.php
new file mode 100644
index 000000000..ccbddbf77
--- /dev/null
+++ b/vendor/sebastian/complexity/src/Complexity/ComplexityCollection.php
@@ -0,0 +1,72 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/complexity.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Complexity;
+
+use function count;
+use Countable;
+use IteratorAggregate;
+
+/**
+ * @psalm-immutable
+ */
+final class ComplexityCollection implements Countable, IteratorAggregate
+{
+ /**
+ * @psalm-var list<Complexity>
+ */
+ private $items = [];
+
+ public static function fromList(Complexity ...$items): self
+ {
+ return new self($items);
+ }
+
+ /**
+ * @psalm-param list<Complexity> $items
+ */
+ private function __construct(array $items)
+ {
+ $this->items = $items;
+ }
+
+ /**
+ * @psalm-return list<Complexity>
+ */
+ public function asArray(): array
+ {
+ return $this->items;
+ }
+
+ public function getIterator(): ComplexityCollectionIterator
+ {
+ return new ComplexityCollectionIterator($this);
+ }
+
+ public function count(): int
+ {
+ return count($this->items);
+ }
+
+ public function isEmpty(): bool
+ {
+ return empty($this->items);
+ }
+
+ public function cyclomaticComplexity(): int
+ {
+ $cyclomaticComplexity = 0;
+
+ foreach ($this as $item) {
+ $cyclomaticComplexity += $item->cyclomaticComplexity();
+ }
+
+ return $cyclomaticComplexity;
+ }
+}
diff --git a/vendor/sebastian/complexity/src/Complexity/ComplexityCollectionIterator.php b/vendor/sebastian/complexity/src/Complexity/ComplexityCollectionIterator.php
new file mode 100644
index 000000000..ec39e199f
--- /dev/null
+++ b/vendor/sebastian/complexity/src/Complexity/ComplexityCollectionIterator.php
@@ -0,0 +1,55 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/complexity.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Complexity;
+
+use Iterator;
+
+final class ComplexityCollectionIterator implements Iterator
+{
+ /**
+ * @psalm-var list<Complexity>
+ */
+ private $items;
+
+ /**
+ * @var int
+ */
+ private $position = 0;
+
+ public function __construct(ComplexityCollection $items)
+ {
+ $this->items = $items->asArray();
+ }
+
+ public function rewind(): void
+ {
+ $this->position = 0;
+ }
+
+ public function valid(): bool
+ {
+ return isset($this->items[$this->position]);
+ }
+
+ public function key(): int
+ {
+ return $this->position;
+ }
+
+ public function current(): Complexity
+ {
+ return $this->items[$this->position];
+ }
+
+ public function next(): void
+ {
+ $this->position++;
+ }
+}
diff --git a/vendor/sebastian/complexity/src/Exception/Exception.php b/vendor/sebastian/complexity/src/Exception/Exception.php
new file mode 100644
index 000000000..897ecdcf7
--- /dev/null
+++ b/vendor/sebastian/complexity/src/Exception/Exception.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/complexity.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Complexity;
+
+use Throwable;
+
+interface Exception extends Throwable
+{
+}
diff --git a/vendor/sebastian/complexity/src/Exception/RuntimeException.php b/vendor/sebastian/complexity/src/Exception/RuntimeException.php
new file mode 100644
index 000000000..6c68a6f0f
--- /dev/null
+++ b/vendor/sebastian/complexity/src/Exception/RuntimeException.php
@@ -0,0 +1,14 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/complexity.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Complexity;
+
+final class RuntimeException extends \RuntimeException implements Exception
+{
+}
diff --git a/vendor/sebastian/complexity/src/Visitor/ComplexityCalculatingVisitor.php b/vendor/sebastian/complexity/src/Visitor/ComplexityCalculatingVisitor.php
new file mode 100644
index 000000000..b69f2b09f
--- /dev/null
+++ b/vendor/sebastian/complexity/src/Visitor/ComplexityCalculatingVisitor.php
@@ -0,0 +1,109 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/complexity.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Complexity;
+
+use function assert;
+use function is_array;
+use PhpParser\Node;
+use PhpParser\Node\Name;
+use PhpParser\Node\Stmt;
+use PhpParser\Node\Stmt\Class_;
+use PhpParser\Node\Stmt\ClassMethod;
+use PhpParser\Node\Stmt\Function_;
+use PhpParser\Node\Stmt\Trait_;
+use PhpParser\NodeTraverser;
+use PhpParser\NodeVisitorAbstract;
+
+final class ComplexityCalculatingVisitor extends NodeVisitorAbstract
+{
+ /**
+ * @psalm-var list<Complexity>
+ */
+ private $result = [];
+
+ /**
+ * @var bool
+ */
+ private $shortCircuitTraversal;
+
+ public function __construct(bool $shortCircuitTraversal)
+ {
+ $this->shortCircuitTraversal = $shortCircuitTraversal;
+ }
+
+ public function enterNode(Node $node): ?int
+ {
+ if (!$node instanceof ClassMethod && !$node instanceof Function_) {
+ return null;
+ }
+
+ if ($node instanceof ClassMethod) {
+ $name = $this->classMethodName($node);
+ } else {
+ $name = $this->functionName($node);
+ }
+
+ $statements = $node->getStmts();
+
+ assert(is_array($statements));
+
+ $this->result[] = new Complexity(
+ $name,
+ $this->cyclomaticComplexity($statements)
+ );
+
+ if ($this->shortCircuitTraversal) {
+ return NodeTraverser::DONT_TRAVERSE_CHILDREN;
+ }
+
+ return null;
+ }
+
+ public function result(): ComplexityCollection
+ {
+ return ComplexityCollection::fromList(...$this->result);
+ }
+
+ /**
+ * @param Stmt[] $statements
+ */
+ private function cyclomaticComplexity(array $statements): int
+ {
+ $traverser = new NodeTraverser;
+
+ $cyclomaticComplexityCalculatingVisitor = new CyclomaticComplexityCalculatingVisitor;
+
+ $traverser->addVisitor($cyclomaticComplexityCalculatingVisitor);
+
+ /* @noinspection UnusedFunctionResultInspection */
+ $traverser->traverse($statements);
+
+ return $cyclomaticComplexityCalculatingVisitor->cyclomaticComplexity();
+ }
+
+ private function classMethodName(ClassMethod $node): string
+ {
+ $parent = $node->getAttribute('parent');
+
+ assert($parent instanceof Class_ || $parent instanceof Trait_);
+ assert(isset($parent->namespacedName));
+ assert($parent->namespacedName instanceof Name);
+
+ return $parent->namespacedName->toString() . '::' . $node->name->toString();
+ }
+
+ private function functionName(Function_ $node): string
+ {
+ assert(isset($node->namespacedName));
+ assert($node->namespacedName instanceof Name);
+
+ return $node->namespacedName->toString();
+ }
+}
diff --git a/vendor/sebastian/complexity/src/Visitor/CyclomaticComplexityCalculatingVisitor.php b/vendor/sebastian/complexity/src/Visitor/CyclomaticComplexityCalculatingVisitor.php
new file mode 100644
index 000000000..d4430876d
--- /dev/null
+++ b/vendor/sebastian/complexity/src/Visitor/CyclomaticComplexityCalculatingVisitor.php
@@ -0,0 +1,59 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/complexity.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Complexity;
+
+use function get_class;
+use PhpParser\Node;
+use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
+use PhpParser\Node\Expr\BinaryOp\BooleanOr;
+use PhpParser\Node\Expr\BinaryOp\LogicalAnd;
+use PhpParser\Node\Expr\BinaryOp\LogicalOr;
+use PhpParser\Node\Expr\Ternary;
+use PhpParser\Node\Stmt\Case_;
+use PhpParser\Node\Stmt\Catch_;
+use PhpParser\Node\Stmt\ElseIf_;
+use PhpParser\Node\Stmt\For_;
+use PhpParser\Node\Stmt\Foreach_;
+use PhpParser\Node\Stmt\If_;
+use PhpParser\Node\Stmt\While_;
+use PhpParser\NodeVisitorAbstract;
+
+final class CyclomaticComplexityCalculatingVisitor extends NodeVisitorAbstract
+{
+ /**
+ * @var int
+ */
+ private $cyclomaticComplexity = 1;
+
+ public function enterNode(Node $node): void
+ {
+ /* @noinspection GetClassMissUseInspection */
+ switch (get_class($node)) {
+ case BooleanAnd::class:
+ case BooleanOr::class:
+ case Case_::class:
+ case Catch_::class:
+ case ElseIf_::class:
+ case For_::class:
+ case Foreach_::class:
+ case If_::class:
+ case LogicalAnd::class:
+ case LogicalOr::class:
+ case Ternary::class:
+ case While_::class:
+ $this->cyclomaticComplexity++;
+ }
+ }
+
+ public function cyclomaticComplexity(): int
+ {
+ return $this->cyclomaticComplexity;
+ }
+}
diff --git a/vendor/sebastian/diff/ChangeLog.md b/vendor/sebastian/diff/ChangeLog.md
new file mode 100644
index 000000000..9bdcc5b6d
--- /dev/null
+++ b/vendor/sebastian/diff/ChangeLog.md
@@ -0,0 +1,88 @@
+# ChangeLog
+
+All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [4.0.4] - 2020-10-26
+
+### Fixed
+
+* `SebastianBergmann\Diff\Exception` now correctly extends `\Throwable`
+
+## [4.0.3] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [4.0.2] - 2020-06-30
+
+### Added
+
+* This component is now supported on PHP 8
+
+## [4.0.1] - 2020-05-08
+
+### Fixed
+
+* [#99](https://github.com/sebastianbergmann/diff/pull/99): Regression in unified diff output of identical strings
+
+## [4.0.0] - 2020-02-07
+
+### Removed
+
+* Removed support for PHP 7.1 and PHP 7.2
+
+## [3.0.2] - 2019-02-04
+
+### Changed
+
+* `Chunk::setLines()` now ensures that the `$lines` array only contains `Line` objects
+
+## [3.0.1] - 2018-06-10
+
+### Fixed
+
+* Removed `"minimum-stability": "dev",` from `composer.json`
+
+## [3.0.0] - 2018-02-01
+
+* The `StrictUnifiedDiffOutputBuilder` implementation of the `DiffOutputBuilderInterface` was added
+
+### Changed
+
+* The default `DiffOutputBuilderInterface` implementation now generates context lines (unchanged lines)
+
+### Removed
+
+* Removed support for PHP 7.0
+
+### Fixed
+
+* [#70](https://github.com/sebastianbergmann/diff/issues/70): Diffing of arrays no longer works
+
+## [2.0.1] - 2017-08-03
+
+### Fixed
+
+* [#66](https://github.com/sebastianbergmann/diff/pull/66): Restored backwards compatibility for PHPUnit 6.1.4, 6.2.0, 6.2.1, 6.2.2, and 6.2.3
+
+## [2.0.0] - 2017-07-11 [YANKED]
+
+### Added
+
+* [#64](https://github.com/sebastianbergmann/diff/pull/64): Show line numbers for chunks of a diff
+
+### Removed
+
+* This component is no longer supported on PHP 5.6
+
+[4.0.4]: https://github.com/sebastianbergmann/diff/compare/4.0.3...4.0.4
+[4.0.3]: https://github.com/sebastianbergmann/diff/compare/4.0.2...4.0.3
+[4.0.2]: https://github.com/sebastianbergmann/diff/compare/4.0.1...4.0.2
+[4.0.1]: https://github.com/sebastianbergmann/diff/compare/4.0.0...4.0.1
+[4.0.0]: https://github.com/sebastianbergmann/diff/compare/3.0.2...4.0.0
+[3.0.2]: https://github.com/sebastianbergmann/diff/compare/3.0.1...3.0.2
+[3.0.1]: https://github.com/sebastianbergmann/diff/compare/3.0.0...3.0.1
+[3.0.0]: https://github.com/sebastianbergmann/diff/compare/2.0...3.0.0
+[2.0.1]: https://github.com/sebastianbergmann/diff/compare/c341c98ce083db77f896a0aa64f5ee7652915970...2.0.1
+[2.0.0]: https://github.com/sebastianbergmann/diff/compare/1.4...c341c98ce083db77f896a0aa64f5ee7652915970
diff --git a/vendor/sebastian/diff/LICENSE b/vendor/sebastian/diff/LICENSE
new file mode 100644
index 000000000..f22f31cf0
--- /dev/null
+++ b/vendor/sebastian/diff/LICENSE
@@ -0,0 +1,33 @@
+sebastian/diff
+
+Copyright (c) 2002-2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/diff/README.md b/vendor/sebastian/diff/README.md
new file mode 100644
index 000000000..734b852de
--- /dev/null
+++ b/vendor/sebastian/diff/README.md
@@ -0,0 +1,202 @@
+# sebastian/diff
+
+[![CI Status](https://github.com/sebastianbergmann/diff/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/diff/actions)
+[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/diff/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/diff)
+
+Diff implementation for PHP, factored out of PHPUnit into a stand-alone component.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/diff
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/diff
+```
+
+### Usage
+
+#### Generating diff
+
+The `Differ` class can be used to generate a textual representation of the difference between two strings:
+
+```php
+<?php
+use SebastianBergmann\Diff\Differ;
+
+$differ = new Differ;
+print $differ->diff('foo', 'bar');
+```
+
+The code above yields the output below:
+```diff
+--- Original
++++ New
+@@ @@
+-foo
++bar
+```
+
+There are three output builders available in this package:
+
+#### UnifiedDiffOutputBuilder
+
+This is default builder, which generates the output close to udiff and is used by PHPUnit.
+
+```php
+<?php
+
+use SebastianBergmann\Diff\Differ;
+use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
+
+$builder = new UnifiedDiffOutputBuilder(
+ "--- Original\n+++ New\n", // custom header
+ false // do not add line numbers to the diff
+);
+
+$differ = new Differ($builder);
+print $differ->diff('foo', 'bar');
+```
+
+#### StrictUnifiedDiffOutputBuilder
+
+Generates (strict) Unified diff's (unidiffs) with hunks,
+similar to `diff -u` and compatible with `patch` and `git apply`.
+
+```php
+<?php
+
+use SebastianBergmann\Diff\Differ;
+use SebastianBergmann\Diff\Output\StrictUnifiedDiffOutputBuilder;
+
+$builder = new StrictUnifiedDiffOutputBuilder([
+ 'collapseRanges' => true, // ranges of length one are rendered with the trailing `,1`
+ 'commonLineThreshold' => 6, // number of same lines before ending a new hunk and creating a new one (if needed)
+ 'contextLines' => 3, // like `diff: -u, -U NUM, --unified[=NUM]`, for patch/git apply compatibility best to keep at least @ 3
+ 'fromFile' => null,
+ 'fromFileDate' => null,
+ 'toFile' => null,
+ 'toFileDate' => null,
+]);
+
+$differ = new Differ($builder);
+print $differ->diff('foo', 'bar');
+```
+
+#### DiffOnlyOutputBuilder
+
+Output only the lines that differ.
+
+```php
+<?php
+
+use SebastianBergmann\Diff\Differ;
+use SebastianBergmann\Diff\Output\DiffOnlyOutputBuilder;
+
+$builder = new DiffOnlyOutputBuilder(
+ "--- Original\n+++ New\n"
+);
+
+$differ = new Differ($builder);
+print $differ->diff('foo', 'bar');
+```
+
+#### DiffOutputBuilderInterface
+
+You can pass any output builder to the `Differ` class as longs as it implements the `DiffOutputBuilderInterface`.
+
+#### Parsing diff
+
+The `Parser` class can be used to parse a unified diff into an object graph:
+
+```php
+use SebastianBergmann\Diff\Parser;
+use SebastianBergmann\Git;
+
+$git = new Git('/usr/local/src/money');
+
+$diff = $git->getDiff(
+ '948a1a07768d8edd10dcefa8315c1cbeffb31833',
+ 'c07a373d2399f3e686234c4f7f088d635eb9641b'
+);
+
+$parser = new Parser;
+
+print_r($parser->parse($diff));
+```
+
+The code above yields the output below:
+
+ Array
+ (
+ [0] => SebastianBergmann\Diff\Diff Object
+ (
+ [from:SebastianBergmann\Diff\Diff:private] => a/tests/MoneyTest.php
+ [to:SebastianBergmann\Diff\Diff:private] => b/tests/MoneyTest.php
+ [chunks:SebastianBergmann\Diff\Diff:private] => Array
+ (
+ [0] => SebastianBergmann\Diff\Chunk Object
+ (
+ [start:SebastianBergmann\Diff\Chunk:private] => 87
+ [startRange:SebastianBergmann\Diff\Chunk:private] => 7
+ [end:SebastianBergmann\Diff\Chunk:private] => 87
+ [endRange:SebastianBergmann\Diff\Chunk:private] => 7
+ [lines:SebastianBergmann\Diff\Chunk:private] => Array
+ (
+ [0] => SebastianBergmann\Diff\Line Object
+ (
+ [type:SebastianBergmann\Diff\Line:private] => 3
+ [content:SebastianBergmann\Diff\Line:private] => * @covers SebastianBergmann\Money\Money::add
+ )
+
+ [1] => SebastianBergmann\Diff\Line Object
+ (
+ [type:SebastianBergmann\Diff\Line:private] => 3
+ [content:SebastianBergmann\Diff\Line:private] => * @covers SebastianBergmann\Money\Money::newMoney
+ )
+
+ [2] => SebastianBergmann\Diff\Line Object
+ (
+ [type:SebastianBergmann\Diff\Line:private] => 3
+ [content:SebastianBergmann\Diff\Line:private] => */
+ )
+
+ [3] => SebastianBergmann\Diff\Line Object
+ (
+ [type:SebastianBergmann\Diff\Line:private] => 2
+ [content:SebastianBergmann\Diff\Line:private] => public function testAnotherMoneyWithSameCurrencyObjectCanBeAdded()
+ )
+
+ [4] => SebastianBergmann\Diff\Line Object
+ (
+ [type:SebastianBergmann\Diff\Line:private] => 1
+ [content:SebastianBergmann\Diff\Line:private] => public function testAnotherMoneyObjectWithSameCurrencyCanBeAdded()
+ )
+
+ [5] => SebastianBergmann\Diff\Line Object
+ (
+ [type:SebastianBergmann\Diff\Line:private] => 3
+ [content:SebastianBergmann\Diff\Line:private] => {
+ )
+
+ [6] => SebastianBergmann\Diff\Line Object
+ (
+ [type:SebastianBergmann\Diff\Line:private] => 3
+ [content:SebastianBergmann\Diff\Line:private] => $a = new Money(1, new Currency('EUR'));
+ )
+
+ [7] => SebastianBergmann\Diff\Line Object
+ (
+ [type:SebastianBergmann\Diff\Line:private] => 3
+ [content:SebastianBergmann\Diff\Line:private] => $b = new Money(2, new Currency('EUR'));
+ )
+ )
+ )
+ )
+ )
+ )
diff --git a/vendor/sebastian/diff/composer.json b/vendor/sebastian/diff/composer.json
new file mode 100644
index 000000000..cf92202ba
--- /dev/null
+++ b/vendor/sebastian/diff/composer.json
@@ -0,0 +1,47 @@
+{
+ "name": "sebastian/diff",
+ "description": "Diff implementation",
+ "keywords": ["diff", "udiff", "unidiff", "unified diff"],
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "[email protected]"
+ }
+ ],
+ "prefer-stable": true,
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3",
+ "symfony/process": "^4.2 || ^5"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "autoload-dev": {
+ "classmap": [
+ "tests/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/diff/src/Chunk.php b/vendor/sebastian/diff/src/Chunk.php
new file mode 100644
index 000000000..16ae34f41
--- /dev/null
+++ b/vendor/sebastian/diff/src/Chunk.php
@@ -0,0 +1,89 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff;
+
+final class Chunk
+{
+ /**
+ * @var int
+ */
+ private $start;
+
+ /**
+ * @var int
+ */
+ private $startRange;
+
+ /**
+ * @var int
+ */
+ private $end;
+
+ /**
+ * @var int
+ */
+ private $endRange;
+
+ /**
+ * @var Line[]
+ */
+ private $lines;
+
+ public function __construct(int $start = 0, int $startRange = 1, int $end = 0, int $endRange = 1, array $lines = [])
+ {
+ $this->start = $start;
+ $this->startRange = $startRange;
+ $this->end = $end;
+ $this->endRange = $endRange;
+ $this->lines = $lines;
+ }
+
+ public function getStart(): int
+ {
+ return $this->start;
+ }
+
+ public function getStartRange(): int
+ {
+ return $this->startRange;
+ }
+
+ public function getEnd(): int
+ {
+ return $this->end;
+ }
+
+ public function getEndRange(): int
+ {
+ return $this->endRange;
+ }
+
+ /**
+ * @return Line[]
+ */
+ public function getLines(): array
+ {
+ return $this->lines;
+ }
+
+ /**
+ * @param Line[] $lines
+ */
+ public function setLines(array $lines): void
+ {
+ foreach ($lines as $line) {
+ if (!$line instanceof Line) {
+ throw new InvalidArgumentException;
+ }
+ }
+
+ $this->lines = $lines;
+ }
+}
diff --git a/vendor/sebastian/diff/src/Diff.php b/vendor/sebastian/diff/src/Diff.php
new file mode 100644
index 000000000..17b2084f9
--- /dev/null
+++ b/vendor/sebastian/diff/src/Diff.php
@@ -0,0 +1,64 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff;
+
+final class Diff
+{
+ /**
+ * @var string
+ */
+ private $from;
+
+ /**
+ * @var string
+ */
+ private $to;
+
+ /**
+ * @var Chunk[]
+ */
+ private $chunks;
+
+ /**
+ * @param Chunk[] $chunks
+ */
+ public function __construct(string $from, string $to, array $chunks = [])
+ {
+ $this->from = $from;
+ $this->to = $to;
+ $this->chunks = $chunks;
+ }
+
+ public function getFrom(): string
+ {
+ return $this->from;
+ }
+
+ public function getTo(): string
+ {
+ return $this->to;
+ }
+
+ /**
+ * @return Chunk[]
+ */
+ public function getChunks(): array
+ {
+ return $this->chunks;
+ }
+
+ /**
+ * @param Chunk[] $chunks
+ */
+ public function setChunks(array $chunks): void
+ {
+ $this->chunks = $chunks;
+ }
+}
diff --git a/vendor/sebastian/diff/src/Differ.php b/vendor/sebastian/diff/src/Differ.php
new file mode 100644
index 000000000..5a4d9d102
--- /dev/null
+++ b/vendor/sebastian/diff/src/Differ.php
@@ -0,0 +1,327 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff;
+
+use const PHP_INT_SIZE;
+use const PREG_SPLIT_DELIM_CAPTURE;
+use const PREG_SPLIT_NO_EMPTY;
+use function array_shift;
+use function array_unshift;
+use function array_values;
+use function count;
+use function current;
+use function end;
+use function get_class;
+use function gettype;
+use function is_array;
+use function is_object;
+use function is_string;
+use function key;
+use function min;
+use function preg_split;
+use function prev;
+use function reset;
+use function sprintf;
+use function substr;
+use SebastianBergmann\Diff\Output\DiffOutputBuilderInterface;
+use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
+
+final class Differ
+{
+ public const OLD = 0;
+
+ public const ADDED = 1;
+
+ public const REMOVED = 2;
+
+ public const DIFF_LINE_END_WARNING = 3;
+
+ public const NO_LINE_END_EOF_WARNING = 4;
+
+ /**
+ * @var DiffOutputBuilderInterface
+ */
+ private $outputBuilder;
+
+ /**
+ * @param DiffOutputBuilderInterface $outputBuilder
+ *
+ * @throws InvalidArgumentException
+ */
+ public function __construct($outputBuilder = null)
+ {
+ if ($outputBuilder instanceof DiffOutputBuilderInterface) {
+ $this->outputBuilder = $outputBuilder;
+ } elseif (null === $outputBuilder) {
+ $this->outputBuilder = new UnifiedDiffOutputBuilder;
+ } elseif (is_string($outputBuilder)) {
+ // PHPUnit 6.1.4, 6.2.0, 6.2.1, 6.2.2, and 6.2.3 support
+ // @see https://github.com/sebastianbergmann/phpunit/issues/2734#issuecomment-314514056
+ // @deprecated
+ $this->outputBuilder = new UnifiedDiffOutputBuilder($outputBuilder);
+ } else {
+ throw new InvalidArgumentException(
+ sprintf(
+ 'Expected builder to be an instance of DiffOutputBuilderInterface, <null> or a string, got %s.',
+ is_object($outputBuilder) ? 'instance of "' . get_class($outputBuilder) . '"' : gettype($outputBuilder) . ' "' . $outputBuilder . '"'
+ )
+ );
+ }
+ }
+
+ /**
+ * Returns the diff between two arrays or strings as string.
+ *
+ * @param array|string $from
+ * @param array|string $to
+ */
+ public function diff($from, $to, LongestCommonSubsequenceCalculator $lcs = null): string
+ {
+ $diff = $this->diffToArray(
+ $this->normalizeDiffInput($from),
+ $this->normalizeDiffInput($to),
+ $lcs
+ );
+
+ return $this->outputBuilder->getDiff($diff);
+ }
+
+ /**
+ * Returns the diff between two arrays or strings as array.
+ *
+ * Each array element contains two elements:
+ * - [0] => mixed $token
+ * - [1] => 2|1|0
+ *
+ * - 2: REMOVED: $token was removed from $from
+ * - 1: ADDED: $token was added to $from
+ * - 0: OLD: $token is not changed in $to
+ *
+ * @param array|string $from
+ * @param array|string $to
+ * @param LongestCommonSubsequenceCalculator $lcs
+ */
+ public function diffToArray($from, $to, LongestCommonSubsequenceCalculator $lcs = null): array
+ {
+ if (is_string($from)) {
+ $from = $this->splitStringByLines($from);
+ } elseif (!is_array($from)) {
+ throw new InvalidArgumentException('"from" must be an array or string.');
+ }
+
+ if (is_string($to)) {
+ $to = $this->splitStringByLines($to);
+ } elseif (!is_array($to)) {
+ throw new InvalidArgumentException('"to" must be an array or string.');
+ }
+
+ [$from, $to, $start, $end] = self::getArrayDiffParted($from, $to);
+
+ if ($lcs === null) {
+ $lcs = $this->selectLcsImplementation($from, $to);
+ }
+
+ $common = $lcs->calculate(array_values($from), array_values($to));
+ $diff = [];
+
+ foreach ($start as $token) {
+ $diff[] = [$token, self::OLD];
+ }
+
+ reset($from);
+ reset($to);
+
+ foreach ($common as $token) {
+ while (($fromToken = reset($from)) !== $token) {
+ $diff[] = [array_shift($from), self::REMOVED];
+ }
+
+ while (($toToken = reset($to)) !== $token) {
+ $diff[] = [array_shift($to), self::ADDED];
+ }
+
+ $diff[] = [$token, self::OLD];
+
+ array_shift($from);
+ array_shift($to);
+ }
+
+ while (($token = array_shift($from)) !== null) {
+ $diff[] = [$token, self::REMOVED];
+ }
+
+ while (($token = array_shift($to)) !== null) {
+ $diff[] = [$token, self::ADDED];
+ }
+
+ foreach ($end as $token) {
+ $diff[] = [$token, self::OLD];
+ }
+
+ if ($this->detectUnmatchedLineEndings($diff)) {
+ array_unshift($diff, ["#Warning: Strings contain different line endings!\n", self::DIFF_LINE_END_WARNING]);
+ }
+
+ return $diff;
+ }
+
+ /**
+ * Casts variable to string if it is not a string or array.
+ *
+ * @return array|string
+ */
+ private function normalizeDiffInput($input)
+ {
+ if (!is_array($input) && !is_string($input)) {
+ return (string) $input;
+ }
+
+ return $input;
+ }
+
+ /**
+ * Checks if input is string, if so it will split it line-by-line.
+ */
+ private function splitStringByLines(string $input): array
+ {
+ return preg_split('/(.*\R)/', $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+ }
+
+ private function selectLcsImplementation(array $from, array $to): LongestCommonSubsequenceCalculator
+ {
+ // We do not want to use the time-efficient implementation if its memory
+ // footprint will probably exceed this value. Note that the footprint
+ // calculation is only an estimation for the matrix and the LCS method
+ // will typically allocate a bit more memory than this.
+ $memoryLimit = 100 * 1024 * 1024;
+
+ if ($this->calculateEstimatedFootprint($from, $to) > $memoryLimit) {
+ return new MemoryEfficientLongestCommonSubsequenceCalculator;
+ }
+
+ return new TimeEfficientLongestCommonSubsequenceCalculator;
+ }
+
+ /**
+ * Calculates the estimated memory footprint for the DP-based method.
+ *
+ * @return float|int
+ */
+ private function calculateEstimatedFootprint(array $from, array $to)
+ {
+ $itemSize = PHP_INT_SIZE === 4 ? 76 : 144;
+
+ return $itemSize * min(count($from), count($to)) ** 2;
+ }
+
+ /**
+ * Returns true if line ends don't match in a diff.
+ */
+ private function detectUnmatchedLineEndings(array $diff): bool
+ {
+ $newLineBreaks = ['' => true];
+ $oldLineBreaks = ['' => true];
+
+ foreach ($diff as $entry) {
+ if (self::OLD === $entry[1]) {
+ $ln = $this->getLinebreak($entry[0]);
+ $oldLineBreaks[$ln] = true;
+ $newLineBreaks[$ln] = true;
+ } elseif (self::ADDED === $entry[1]) {
+ $newLineBreaks[$this->getLinebreak($entry[0])] = true;
+ } elseif (self::REMOVED === $entry[1]) {
+ $oldLineBreaks[$this->getLinebreak($entry[0])] = true;
+ }
+ }
+
+ // if either input or output is a single line without breaks than no warning should be raised
+ if (['' => true] === $newLineBreaks || ['' => true] === $oldLineBreaks) {
+ return false;
+ }
+
+ // two way compare
+ foreach ($newLineBreaks as $break => $set) {
+ if (!isset($oldLineBreaks[$break])) {
+ return true;
+ }
+ }
+
+ foreach ($oldLineBreaks as $break => $set) {
+ if (!isset($newLineBreaks[$break])) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private function getLinebreak($line): string
+ {
+ if (!is_string($line)) {
+ return '';
+ }
+
+ $lc = substr($line, -1);
+
+ if ("\r" === $lc) {
+ return "\r";
+ }
+
+ if ("\n" !== $lc) {
+ return '';
+ }
+
+ if ("\r\n" === substr($line, -2)) {
+ return "\r\n";
+ }
+
+ return "\n";
+ }
+
+ private static function getArrayDiffParted(array &$from, array &$to): array
+ {
+ $start = [];
+ $end = [];
+
+ reset($to);
+
+ foreach ($from as $k => $v) {
+ $toK = key($to);
+
+ if ($toK === $k && $v === $to[$k]) {
+ $start[$k] = $v;
+
+ unset($from[$k], $to[$k]);
+ } else {
+ break;
+ }
+ }
+
+ end($from);
+ end($to);
+
+ do {
+ $fromK = key($from);
+ $toK = key($to);
+
+ if (null === $fromK || null === $toK || current($from) !== current($to)) {
+ break;
+ }
+
+ prev($from);
+ prev($to);
+
+ $end = [$fromK => $from[$fromK]] + $end;
+ unset($from[$fromK], $to[$toK]);
+ } while (true);
+
+ return [$from, $to, $start, $end];
+ }
+}
diff --git a/vendor/sebastian/diff/src/Exception/ConfigurationException.php b/vendor/sebastian/diff/src/Exception/ConfigurationException.php
new file mode 100644
index 000000000..b767b2194
--- /dev/null
+++ b/vendor/sebastian/diff/src/Exception/ConfigurationException.php
@@ -0,0 +1,38 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff;
+
+use function get_class;
+use function gettype;
+use function is_object;
+use function sprintf;
+use Exception;
+
+final class ConfigurationException extends InvalidArgumentException
+{
+ public function __construct(
+ string $option,
+ string $expected,
+ $value,
+ int $code = 0,
+ Exception $previous = null
+ ) {
+ parent::__construct(
+ sprintf(
+ 'Option "%s" must be %s, got "%s".',
+ $option,
+ $expected,
+ is_object($value) ? get_class($value) : (null === $value ? '<null>' : gettype($value) . '#' . $value)
+ ),
+ $code,
+ $previous
+ );
+ }
+}
diff --git a/vendor/sebastian/diff/src/Exception/Exception.php b/vendor/sebastian/diff/src/Exception/Exception.php
new file mode 100644
index 000000000..e20d32036
--- /dev/null
+++ b/vendor/sebastian/diff/src/Exception/Exception.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff;
+
+use Throwable;
+
+interface Exception extends Throwable
+{
+}
diff --git a/vendor/sebastian/diff/src/Exception/InvalidArgumentException.php b/vendor/sebastian/diff/src/Exception/InvalidArgumentException.php
new file mode 100644
index 000000000..846ac3fbd
--- /dev/null
+++ b/vendor/sebastian/diff/src/Exception/InvalidArgumentException.php
@@ -0,0 +1,14 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff;
+
+class InvalidArgumentException extends \InvalidArgumentException implements Exception
+{
+}
diff --git a/vendor/sebastian/diff/src/Line.php b/vendor/sebastian/diff/src/Line.php
new file mode 100644
index 000000000..3596ed264
--- /dev/null
+++ b/vendor/sebastian/diff/src/Line.php
@@ -0,0 +1,45 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff;
+
+final class Line
+{
+ public const ADDED = 1;
+
+ public const REMOVED = 2;
+
+ public const UNCHANGED = 3;
+
+ /**
+ * @var int
+ */
+ private $type;
+
+ /**
+ * @var string
+ */
+ private $content;
+
+ public function __construct(int $type = self::UNCHANGED, string $content = '')
+ {
+ $this->type = $type;
+ $this->content = $content;
+ }
+
+ public function getContent(): string
+ {
+ return $this->content;
+ }
+
+ public function getType(): int
+ {
+ return $this->type;
+ }
+}
diff --git a/vendor/sebastian/diff/src/LongestCommonSubsequenceCalculator.php b/vendor/sebastian/diff/src/LongestCommonSubsequenceCalculator.php
new file mode 100644
index 000000000..dea8fe1cb
--- /dev/null
+++ b/vendor/sebastian/diff/src/LongestCommonSubsequenceCalculator.php
@@ -0,0 +1,18 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff;
+
+interface LongestCommonSubsequenceCalculator
+{
+ /**
+ * Calculates the longest common subsequence of two arrays.
+ */
+ public function calculate(array $from, array $to): array;
+}
diff --git a/vendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php b/vendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php
new file mode 100644
index 000000000..0b626eaff
--- /dev/null
+++ b/vendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php
@@ -0,0 +1,88 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff;
+
+use function array_fill;
+use function array_merge;
+use function array_reverse;
+use function array_slice;
+use function count;
+use function in_array;
+use function max;
+
+final class MemoryEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function calculate(array $from, array $to): array
+ {
+ $cFrom = count($from);
+ $cTo = count($to);
+
+ if ($cFrom === 0) {
+ return [];
+ }
+
+ if ($cFrom === 1) {
+ if (in_array($from[0], $to, true)) {
+ return [$from[0]];
+ }
+
+ return [];
+ }
+
+ $i = (int) ($cFrom / 2);
+ $fromStart = array_slice($from, 0, $i);
+ $fromEnd = array_slice($from, $i);
+ $llB = $this->length($fromStart, $to);
+ $llE = $this->length(array_reverse($fromEnd), array_reverse($to));
+ $jMax = 0;
+ $max = 0;
+
+ for ($j = 0; $j <= $cTo; $j++) {
+ $m = $llB[$j] + $llE[$cTo - $j];
+
+ if ($m >= $max) {
+ $max = $m;
+ $jMax = $j;
+ }
+ }
+
+ $toStart = array_slice($to, 0, $jMax);
+ $toEnd = array_slice($to, $jMax);
+
+ return array_merge(
+ $this->calculate($fromStart, $toStart),
+ $this->calculate($fromEnd, $toEnd)
+ );
+ }
+
+ private function length(array $from, array $to): array
+ {
+ $current = array_fill(0, count($to) + 1, 0);
+ $cFrom = count($from);
+ $cTo = count($to);
+
+ for ($i = 0; $i < $cFrom; $i++) {
+ $prev = $current;
+
+ for ($j = 0; $j < $cTo; $j++) {
+ if ($from[$i] === $to[$j]) {
+ $current[$j + 1] = $prev[$j] + 1;
+ } else {
+ $current[$j + 1] = max($current[$j], $prev[$j + 1]);
+ }
+ }
+ }
+
+ return $current;
+ }
+}
diff --git a/vendor/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php b/vendor/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php
new file mode 100644
index 000000000..e55757c38
--- /dev/null
+++ b/vendor/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php
@@ -0,0 +1,52 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff\Output;
+
+use function count;
+
+abstract class AbstractChunkOutputBuilder implements DiffOutputBuilderInterface
+{
+ /**
+ * Takes input of the diff array and returns the common parts.
+ * Iterates through diff line by line.
+ */
+ protected function getCommonChunks(array $diff, int $lineThreshold = 5): array
+ {
+ $diffSize = count($diff);
+ $capturing = false;
+ $chunkStart = 0;
+ $chunkSize = 0;
+ $commonChunks = [];
+
+ for ($i = 0; $i < $diffSize; ++$i) {
+ if ($diff[$i][1] === 0 /* OLD */) {
+ if ($capturing === false) {
+ $capturing = true;
+ $chunkStart = $i;
+ $chunkSize = 0;
+ } else {
+ ++$chunkSize;
+ }
+ } elseif ($capturing !== false) {
+ if ($chunkSize >= $lineThreshold) {
+ $commonChunks[$chunkStart] = $chunkStart + $chunkSize;
+ }
+
+ $capturing = false;
+ }
+ }
+
+ if ($capturing !== false && $chunkSize >= $lineThreshold) {
+ $commonChunks[$chunkStart] = $chunkStart + $chunkSize;
+ }
+
+ return $commonChunks;
+ }
+}
diff --git a/vendor/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php b/vendor/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php
new file mode 100644
index 000000000..f79a935cb
--- /dev/null
+++ b/vendor/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php
@@ -0,0 +1,72 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff\Output;
+
+use function fclose;
+use function fopen;
+use function fwrite;
+use function stream_get_contents;
+use function substr;
+use SebastianBergmann\Diff\Differ;
+
+/**
+ * Builds a diff string representation in a loose unified diff format
+ * listing only changes lines. Does not include line numbers.
+ */
+final class DiffOnlyOutputBuilder implements DiffOutputBuilderInterface
+{
+ /**
+ * @var string
+ */
+ private $header;
+
+ public function __construct(string $header = "--- Original\n+++ New\n")
+ {
+ $this->header = $header;
+ }
+
+ public function getDiff(array $diff): string
+ {
+ $buffer = fopen('php://memory', 'r+b');
+
+ if ('' !== $this->header) {
+ fwrite($buffer, $this->header);
+
+ if ("\n" !== substr($this->header, -1, 1)) {
+ fwrite($buffer, "\n");
+ }
+ }
+
+ foreach ($diff as $diffEntry) {
+ if ($diffEntry[1] === Differ::ADDED) {
+ fwrite($buffer, '+' . $diffEntry[0]);
+ } elseif ($diffEntry[1] === Differ::REMOVED) {
+ fwrite($buffer, '-' . $diffEntry[0]);
+ } elseif ($diffEntry[1] === Differ::DIFF_LINE_END_WARNING) {
+ fwrite($buffer, ' ' . $diffEntry[0]);
+
+ continue; // Warnings should not be tested for line break, it will always be there
+ } else { /* Not changed (old) 0 */
+ continue; // we didn't write the non changs line, so do not add a line break either
+ }
+
+ $lc = substr($diffEntry[0], -1);
+
+ if ($lc !== "\n" && $lc !== "\r") {
+ fwrite($buffer, "\n"); // \No newline at end of file
+ }
+ }
+
+ $diff = stream_get_contents($buffer, -1, 0);
+ fclose($buffer);
+
+ return $diff;
+ }
+}
diff --git a/vendor/sebastian/diff/src/Output/DiffOutputBuilderInterface.php b/vendor/sebastian/diff/src/Output/DiffOutputBuilderInterface.php
new file mode 100644
index 000000000..0e18f9f2e
--- /dev/null
+++ b/vendor/sebastian/diff/src/Output/DiffOutputBuilderInterface.php
@@ -0,0 +1,19 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff\Output;
+
+/**
+ * Defines how an output builder should take a generated
+ * diff array and return a string representation of that diff.
+ */
+interface DiffOutputBuilderInterface
+{
+ public function getDiff(array $diff): string;
+}
diff --git a/vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php b/vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php
new file mode 100644
index 000000000..9c55ab2aa
--- /dev/null
+++ b/vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php
@@ -0,0 +1,338 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff\Output;
+
+use function array_merge;
+use function array_splice;
+use function count;
+use function fclose;
+use function fopen;
+use function fwrite;
+use function is_bool;
+use function is_int;
+use function is_string;
+use function max;
+use function min;
+use function sprintf;
+use function stream_get_contents;
+use function substr;
+use SebastianBergmann\Diff\ConfigurationException;
+use SebastianBergmann\Diff\Differ;
+
+/**
+ * Strict Unified diff output builder.
+ *
+ * Generates (strict) Unified diff's (unidiffs) with hunks.
+ */
+final class StrictUnifiedDiffOutputBuilder implements DiffOutputBuilderInterface
+{
+ private static $default = [
+ 'collapseRanges' => true, // ranges of length one are rendered with the trailing `,1`
+ 'commonLineThreshold' => 6, // number of same lines before ending a new hunk and creating a new one (if needed)
+ 'contextLines' => 3, // like `diff: -u, -U NUM, --unified[=NUM]`, for patch/git apply compatibility best to keep at least @ 3
+ 'fromFile' => null,
+ 'fromFileDate' => null,
+ 'toFile' => null,
+ 'toFileDate' => null,
+ ];
+
+ /**
+ * @var bool
+ */
+ private $changed;
+
+ /**
+ * @var bool
+ */
+ private $collapseRanges;
+
+ /**
+ * @var int >= 0
+ */
+ private $commonLineThreshold;
+
+ /**
+ * @var string
+ */
+ private $header;
+
+ /**
+ * @var int >= 0
+ */
+ private $contextLines;
+
+ public function __construct(array $options = [])
+ {
+ $options = array_merge(self::$default, $options);
+
+ if (!is_bool($options['collapseRanges'])) {
+ throw new ConfigurationException('collapseRanges', 'a bool', $options['collapseRanges']);
+ }
+
+ if (!is_int($options['contextLines']) || $options['contextLines'] < 0) {
+ throw new ConfigurationException('contextLines', 'an int >= 0', $options['contextLines']);
+ }
+
+ if (!is_int($options['commonLineThreshold']) || $options['commonLineThreshold'] <= 0) {
+ throw new ConfigurationException('commonLineThreshold', 'an int > 0', $options['commonLineThreshold']);
+ }
+
+ $this->assertString($options, 'fromFile');
+ $this->assertString($options, 'toFile');
+ $this->assertStringOrNull($options, 'fromFileDate');
+ $this->assertStringOrNull($options, 'toFileDate');
+
+ $this->header = sprintf(
+ "--- %s%s\n+++ %s%s\n",
+ $options['fromFile'],
+ null === $options['fromFileDate'] ? '' : "\t" . $options['fromFileDate'],
+ $options['toFile'],
+ null === $options['toFileDate'] ? '' : "\t" . $options['toFileDate']
+ );
+
+ $this->collapseRanges = $options['collapseRanges'];
+ $this->commonLineThreshold = $options['commonLineThreshold'];
+ $this->contextLines = $options['contextLines'];
+ }
+
+ public function getDiff(array $diff): string
+ {
+ if (0 === count($diff)) {
+ return '';
+ }
+
+ $this->changed = false;
+
+ $buffer = fopen('php://memory', 'r+b');
+ fwrite($buffer, $this->header);
+
+ $this->writeDiffHunks($buffer, $diff);
+
+ if (!$this->changed) {
+ fclose($buffer);
+
+ return '';
+ }
+
+ $diff = stream_get_contents($buffer, -1, 0);
+
+ fclose($buffer);
+
+ // If the last char is not a linebreak: add it.
+ // This might happen when both the `from` and `to` do not have a trailing linebreak
+ $last = substr($diff, -1);
+
+ return "\n" !== $last && "\r" !== $last
+ ? $diff . "\n"
+ : $diff;
+ }
+
+ private function writeDiffHunks($output, array $diff): void
+ {
+ // detect "No newline at end of file" and insert into `$diff` if needed
+
+ $upperLimit = count($diff);
+
+ if (0 === $diff[$upperLimit - 1][1]) {
+ $lc = substr($diff[$upperLimit - 1][0], -1);
+
+ if ("\n" !== $lc) {
+ array_splice($diff, $upperLimit, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
+ }
+ } else {
+ // search back for the last `+` and `-` line,
+ // check if has trailing linebreak, else add under it warning under it
+ $toFind = [1 => true, 2 => true];
+
+ for ($i = $upperLimit - 1; $i >= 0; --$i) {
+ if (isset($toFind[$diff[$i][1]])) {
+ unset($toFind[$diff[$i][1]]);
+ $lc = substr($diff[$i][0], -1);
+
+ if ("\n" !== $lc) {
+ array_splice($diff, $i + 1, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
+ }
+
+ if (!count($toFind)) {
+ break;
+ }
+ }
+ }
+ }
+
+ // write hunks to output buffer
+
+ $cutOff = max($this->commonLineThreshold, $this->contextLines);
+ $hunkCapture = false;
+ $sameCount = $toRange = $fromRange = 0;
+ $toStart = $fromStart = 1;
+ $i = 0;
+
+ /** @var int $i */
+ foreach ($diff as $i => $entry) {
+ if (0 === $entry[1]) { // same
+ if (false === $hunkCapture) {
+ ++$fromStart;
+ ++$toStart;
+
+ continue;
+ }
+
+ ++$sameCount;
+ ++$toRange;
+ ++$fromRange;
+
+ if ($sameCount === $cutOff) {
+ $contextStartOffset = ($hunkCapture - $this->contextLines) < 0
+ ? $hunkCapture
+ : $this->contextLines;
+
+ // note: $contextEndOffset = $this->contextLines;
+ //
+ // because we never go beyond the end of the diff.
+ // with the cutoff/contextlines here the follow is never true;
+ //
+ // if ($i - $cutOff + $this->contextLines + 1 > \count($diff)) {
+ // $contextEndOffset = count($diff) - 1;
+ // }
+ //
+ // ; that would be true for a trailing incomplete hunk case which is dealt with after this loop
+
+ $this->writeHunk(
+ $diff,
+ $hunkCapture - $contextStartOffset,
+ $i - $cutOff + $this->contextLines + 1,
+ $fromStart - $contextStartOffset,
+ $fromRange - $cutOff + $contextStartOffset + $this->contextLines,
+ $toStart - $contextStartOffset,
+ $toRange - $cutOff + $contextStartOffset + $this->contextLines,
+ $output
+ );
+
+ $fromStart += $fromRange;
+ $toStart += $toRange;
+
+ $hunkCapture = false;
+ $sameCount = $toRange = $fromRange = 0;
+ }
+
+ continue;
+ }
+
+ $sameCount = 0;
+
+ if ($entry[1] === Differ::NO_LINE_END_EOF_WARNING) {
+ continue;
+ }
+
+ $this->changed = true;
+
+ if (false === $hunkCapture) {
+ $hunkCapture = $i;
+ }
+
+ if (Differ::ADDED === $entry[1]) { // added
+ ++$toRange;
+ }
+
+ if (Differ::REMOVED === $entry[1]) { // removed
+ ++$fromRange;
+ }
+ }
+
+ if (false === $hunkCapture) {
+ return;
+ }
+
+ // we end here when cutoff (commonLineThreshold) was not reached, but we where capturing a hunk,
+ // do not render hunk till end automatically because the number of context lines might be less than the commonLineThreshold
+
+ $contextStartOffset = $hunkCapture - $this->contextLines < 0
+ ? $hunkCapture
+ : $this->contextLines;
+
+ // prevent trying to write out more common lines than there are in the diff _and_
+ // do not write more than configured through the context lines
+ $contextEndOffset = min($sameCount, $this->contextLines);
+
+ $fromRange -= $sameCount;
+ $toRange -= $sameCount;
+
+ $this->writeHunk(
+ $diff,
+ $hunkCapture - $contextStartOffset,
+ $i - $sameCount + $contextEndOffset + 1,
+ $fromStart - $contextStartOffset,
+ $fromRange + $contextStartOffset + $contextEndOffset,
+ $toStart - $contextStartOffset,
+ $toRange + $contextStartOffset + $contextEndOffset,
+ $output
+ );
+ }
+
+ private function writeHunk(
+ array $diff,
+ int $diffStartIndex,
+ int $diffEndIndex,
+ int $fromStart,
+ int $fromRange,
+ int $toStart,
+ int $toRange,
+ $output
+ ): void {
+ fwrite($output, '@@ -' . $fromStart);
+
+ if (!$this->collapseRanges || 1 !== $fromRange) {
+ fwrite($output, ',' . $fromRange);
+ }
+
+ fwrite($output, ' +' . $toStart);
+
+ if (!$this->collapseRanges || 1 !== $toRange) {
+ fwrite($output, ',' . $toRange);
+ }
+
+ fwrite($output, " @@\n");
+
+ for ($i = $diffStartIndex; $i < $diffEndIndex; ++$i) {
+ if ($diff[$i][1] === Differ::ADDED) {
+ $this->changed = true;
+ fwrite($output, '+' . $diff[$i][0]);
+ } elseif ($diff[$i][1] === Differ::REMOVED) {
+ $this->changed = true;
+ fwrite($output, '-' . $diff[$i][0]);
+ } elseif ($diff[$i][1] === Differ::OLD) {
+ fwrite($output, ' ' . $diff[$i][0]);
+ } elseif ($diff[$i][1] === Differ::NO_LINE_END_EOF_WARNING) {
+ $this->changed = true;
+ fwrite($output, $diff[$i][0]);
+ }
+ //} elseif ($diff[$i][1] === Differ::DIFF_LINE_END_WARNING) { // custom comment inserted by PHPUnit/diff package
+ // skip
+ //} else {
+ // unknown/invalid
+ //}
+ }
+ }
+
+ private function assertString(array $options, string $option): void
+ {
+ if (!is_string($options[$option])) {
+ throw new ConfigurationException($option, 'a string', $options[$option]);
+ }
+ }
+
+ private function assertStringOrNull(array $options, string $option): void
+ {
+ if (null !== $options[$option] && !is_string($options[$option])) {
+ throw new ConfigurationException($option, 'a string or <null>', $options[$option]);
+ }
+ }
+}
diff --git a/vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php b/vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php
new file mode 100644
index 000000000..8aae64504
--- /dev/null
+++ b/vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php
@@ -0,0 +1,272 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff\Output;
+
+use function array_splice;
+use function count;
+use function fclose;
+use function fopen;
+use function fwrite;
+use function max;
+use function min;
+use function stream_get_contents;
+use function strlen;
+use function substr;
+use SebastianBergmann\Diff\Differ;
+
+/**
+ * Builds a diff string representation in unified diff format in chunks.
+ */
+final class UnifiedDiffOutputBuilder extends AbstractChunkOutputBuilder
+{
+ /**
+ * @var bool
+ */
+ private $collapseRanges = true;
+
+ /**
+ * @var int >= 0
+ */
+ private $commonLineThreshold = 6;
+
+ /**
+ * @var int >= 0
+ */
+ private $contextLines = 3;
+
+ /**
+ * @var string
+ */
+ private $header;
+
+ /**
+ * @var bool
+ */
+ private $addLineNumbers;
+
+ public function __construct(string $header = "--- Original\n+++ New\n", bool $addLineNumbers = false)
+ {
+ $this->header = $header;
+ $this->addLineNumbers = $addLineNumbers;
+ }
+
+ public function getDiff(array $diff): string
+ {
+ $buffer = fopen('php://memory', 'r+b');
+
+ if ('' !== $this->header) {
+ fwrite($buffer, $this->header);
+
+ if ("\n" !== substr($this->header, -1, 1)) {
+ fwrite($buffer, "\n");
+ }
+ }
+
+ if (0 !== count($diff)) {
+ $this->writeDiffHunks($buffer, $diff);
+ }
+
+ $diff = stream_get_contents($buffer, -1, 0);
+
+ fclose($buffer);
+
+ // If the diff is non-empty and last char is not a linebreak: add it.
+ // This might happen when both the `from` and `to` do not have a trailing linebreak
+ $last = substr($diff, -1);
+
+ return 0 !== strlen($diff) && "\n" !== $last && "\r" !== $last
+ ? $diff . "\n"
+ : $diff;
+ }
+
+ private function writeDiffHunks($output, array $diff): void
+ {
+ // detect "No newline at end of file" and insert into `$diff` if needed
+
+ $upperLimit = count($diff);
+
+ if (0 === $diff[$upperLimit - 1][1]) {
+ $lc = substr($diff[$upperLimit - 1][0], -1);
+
+ if ("\n" !== $lc) {
+ array_splice($diff, $upperLimit, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
+ }
+ } else {
+ // search back for the last `+` and `-` line,
+ // check if has trailing linebreak, else add under it warning under it
+ $toFind = [1 => true, 2 => true];
+
+ for ($i = $upperLimit - 1; $i >= 0; --$i) {
+ if (isset($toFind[$diff[$i][1]])) {
+ unset($toFind[$diff[$i][1]]);
+ $lc = substr($diff[$i][0], -1);
+
+ if ("\n" !== $lc) {
+ array_splice($diff, $i + 1, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
+ }
+
+ if (!count($toFind)) {
+ break;
+ }
+ }
+ }
+ }
+
+ // write hunks to output buffer
+
+ $cutOff = max($this->commonLineThreshold, $this->contextLines);
+ $hunkCapture = false;
+ $sameCount = $toRange = $fromRange = 0;
+ $toStart = $fromStart = 1;
+ $i = 0;
+
+ /** @var int $i */
+ foreach ($diff as $i => $entry) {
+ if (0 === $entry[1]) { // same
+ if (false === $hunkCapture) {
+ ++$fromStart;
+ ++$toStart;
+
+ continue;
+ }
+
+ ++$sameCount;
+ ++$toRange;
+ ++$fromRange;
+
+ if ($sameCount === $cutOff) {
+ $contextStartOffset = ($hunkCapture - $this->contextLines) < 0
+ ? $hunkCapture
+ : $this->contextLines;
+
+ // note: $contextEndOffset = $this->contextLines;
+ //
+ // because we never go beyond the end of the diff.
+ // with the cutoff/contextlines here the follow is never true;
+ //
+ // if ($i - $cutOff + $this->contextLines + 1 > \count($diff)) {
+ // $contextEndOffset = count($diff) - 1;
+ // }
+ //
+ // ; that would be true for a trailing incomplete hunk case which is dealt with after this loop
+
+ $this->writeHunk(
+ $diff,
+ $hunkCapture - $contextStartOffset,
+ $i - $cutOff + $this->contextLines + 1,
+ $fromStart - $contextStartOffset,
+ $fromRange - $cutOff + $contextStartOffset + $this->contextLines,
+ $toStart - $contextStartOffset,
+ $toRange - $cutOff + $contextStartOffset + $this->contextLines,
+ $output
+ );
+
+ $fromStart += $fromRange;
+ $toStart += $toRange;
+
+ $hunkCapture = false;
+ $sameCount = $toRange = $fromRange = 0;
+ }
+
+ continue;
+ }
+
+ $sameCount = 0;
+
+ if ($entry[1] === Differ::NO_LINE_END_EOF_WARNING) {
+ continue;
+ }
+
+ if (false === $hunkCapture) {
+ $hunkCapture = $i;
+ }
+
+ if (Differ::ADDED === $entry[1]) {
+ ++$toRange;
+ }
+
+ if (Differ::REMOVED === $entry[1]) {
+ ++$fromRange;
+ }
+ }
+
+ if (false === $hunkCapture) {
+ return;
+ }
+
+ // we end here when cutoff (commonLineThreshold) was not reached, but we where capturing a hunk,
+ // do not render hunk till end automatically because the number of context lines might be less than the commonLineThreshold
+
+ $contextStartOffset = $hunkCapture - $this->contextLines < 0
+ ? $hunkCapture
+ : $this->contextLines;
+
+ // prevent trying to write out more common lines than there are in the diff _and_
+ // do not write more than configured through the context lines
+ $contextEndOffset = min($sameCount, $this->contextLines);
+
+ $fromRange -= $sameCount;
+ $toRange -= $sameCount;
+
+ $this->writeHunk(
+ $diff,
+ $hunkCapture - $contextStartOffset,
+ $i - $sameCount + $contextEndOffset + 1,
+ $fromStart - $contextStartOffset,
+ $fromRange + $contextStartOffset + $contextEndOffset,
+ $toStart - $contextStartOffset,
+ $toRange + $contextStartOffset + $contextEndOffset,
+ $output
+ );
+ }
+
+ private function writeHunk(
+ array $diff,
+ int $diffStartIndex,
+ int $diffEndIndex,
+ int $fromStart,
+ int $fromRange,
+ int $toStart,
+ int $toRange,
+ $output
+ ): void {
+ if ($this->addLineNumbers) {
+ fwrite($output, '@@ -' . $fromStart);
+
+ if (!$this->collapseRanges || 1 !== $fromRange) {
+ fwrite($output, ',' . $fromRange);
+ }
+
+ fwrite($output, ' +' . $toStart);
+
+ if (!$this->collapseRanges || 1 !== $toRange) {
+ fwrite($output, ',' . $toRange);
+ }
+
+ fwrite($output, " @@\n");
+ } else {
+ fwrite($output, "@@ @@\n");
+ }
+
+ for ($i = $diffStartIndex; $i < $diffEndIndex; ++$i) {
+ if ($diff[$i][1] === Differ::ADDED) {
+ fwrite($output, '+' . $diff[$i][0]);
+ } elseif ($diff[$i][1] === Differ::REMOVED) {
+ fwrite($output, '-' . $diff[$i][0]);
+ } elseif ($diff[$i][1] === Differ::OLD) {
+ fwrite($output, ' ' . $diff[$i][0]);
+ } elseif ($diff[$i][1] === Differ::NO_LINE_END_EOF_WARNING) {
+ fwrite($output, "\n"); // $diff[$i][0]
+ } else { /* Not changed (old) Differ::OLD or Warning Differ::DIFF_LINE_END_WARNING */
+ fwrite($output, ' ' . $diff[$i][0]);
+ }
+ }
+ }
+}
diff --git a/vendor/sebastian/diff/src/Parser.php b/vendor/sebastian/diff/src/Parser.php
new file mode 100644
index 000000000..cc9e38871
--- /dev/null
+++ b/vendor/sebastian/diff/src/Parser.php
@@ -0,0 +1,110 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff;
+
+use function array_pop;
+use function count;
+use function max;
+use function preg_match;
+use function preg_split;
+
+/**
+ * Unified diff parser.
+ */
+final class Parser
+{
+ /**
+ * @return Diff[]
+ */
+ public function parse(string $string): array
+ {
+ $lines = preg_split('(\r\n|\r|\n)', $string);
+
+ if (!empty($lines) && $lines[count($lines) - 1] === '') {
+ array_pop($lines);
+ }
+
+ $lineCount = count($lines);
+ $diffs = [];
+ $diff = null;
+ $collected = [];
+
+ for ($i = 0; $i < $lineCount; ++$i) {
+ if (preg_match('#^---\h+"?(?P<file>[^\\v\\t"]+)#', $lines[$i], $fromMatch) &&
+ preg_match('#^\\+\\+\\+\\h+"?(?P<file>[^\\v\\t"]+)#', $lines[$i + 1], $toMatch)) {
+ if ($diff !== null) {
+ $this->parseFileDiff($diff, $collected);
+
+ $diffs[] = $diff;
+ $collected = [];
+ }
+
+ $diff = new Diff($fromMatch['file'], $toMatch['file']);
+
+ ++$i;
+ } else {
+ if (preg_match('/^(?:diff --git |index [\da-f\.]+|[+-]{3} [ab])/', $lines[$i])) {
+ continue;
+ }
+
+ $collected[] = $lines[$i];
+ }
+ }
+
+ if ($diff !== null && count($collected)) {
+ $this->parseFileDiff($diff, $collected);
+
+ $diffs[] = $diff;
+ }
+
+ return $diffs;
+ }
+
+ private function parseFileDiff(Diff $diff, array $lines): void
+ {
+ $chunks = [];
+ $chunk = null;
+ $diffLines = [];
+
+ foreach ($lines as $line) {
+ if (preg_match('/^@@\s+-(?P<start>\d+)(?:,\s*(?P<startrange>\d+))?\s+\+(?P<end>\d+)(?:,\s*(?P<endrange>\d+))?\s+@@/', $line, $match)) {
+ $chunk = new Chunk(
+ (int) $match['start'],
+ isset($match['startrange']) ? max(1, (int) $match['startrange']) : 1,
+ (int) $match['end'],
+ isset($match['endrange']) ? max(1, (int) $match['endrange']) : 1
+ );
+
+ $chunks[] = $chunk;
+ $diffLines = [];
+
+ continue;
+ }
+
+ if (preg_match('/^(?P<type>[+ -])?(?P<line>.*)/', $line, $match)) {
+ $type = Line::UNCHANGED;
+
+ if ($match['type'] === '+') {
+ $type = Line::ADDED;
+ } elseif ($match['type'] === '-') {
+ $type = Line::REMOVED;
+ }
+
+ $diffLines[] = new Line($type, $match['line']);
+
+ if (null !== $chunk) {
+ $chunk->setLines($diffLines);
+ }
+ }
+ }
+
+ $diff->setChunks($chunks);
+ }
+}
diff --git a/vendor/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php b/vendor/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php
new file mode 100644
index 000000000..fd19cac76
--- /dev/null
+++ b/vendor/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php
@@ -0,0 +1,70 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Diff;
+
+use function array_reverse;
+use function count;
+use function max;
+use SplFixedArray;
+
+final class TimeEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function calculate(array $from, array $to): array
+ {
+ $common = [];
+ $fromLength = count($from);
+ $toLength = count($to);
+ $width = $fromLength + 1;
+ $matrix = new SplFixedArray($width * ($toLength + 1));
+
+ for ($i = 0; $i <= $fromLength; ++$i) {
+ $matrix[$i] = 0;
+ }
+
+ for ($j = 0; $j <= $toLength; ++$j) {
+ $matrix[$j * $width] = 0;
+ }
+
+ for ($i = 1; $i <= $fromLength; ++$i) {
+ for ($j = 1; $j <= $toLength; ++$j) {
+ $o = ($j * $width) + $i;
+ $matrix[$o] = max(
+ $matrix[$o - 1],
+ $matrix[$o - $width],
+ $from[$i - 1] === $to[$j - 1] ? $matrix[$o - $width - 1] + 1 : 0
+ );
+ }
+ }
+
+ $i = $fromLength;
+ $j = $toLength;
+
+ while ($i > 0 && $j > 0) {
+ if ($from[$i - 1] === $to[$j - 1]) {
+ $common[] = $from[$i - 1];
+ --$i;
+ --$j;
+ } else {
+ $o = ($j * $width) + $i;
+
+ if ($matrix[$o - $width] > $matrix[$o - 1]) {
+ --$j;
+ } else {
+ --$i;
+ }
+ }
+ }
+
+ return array_reverse($common);
+ }
+}
diff --git a/vendor/sebastian/environment/ChangeLog.md b/vendor/sebastian/environment/ChangeLog.md
new file mode 100644
index 000000000..67daf0356
--- /dev/null
+++ b/vendor/sebastian/environment/ChangeLog.md
@@ -0,0 +1,169 @@
+# Changes in sebastianbergmann/environment
+
+All notable changes in `sebastianbergmann/environment` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [5.1.3] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [5.1.2] - 2020-06-26
+
+### Added
+
+* This component is now supported on PHP 8
+
+## [5.1.1] - 2020-06-15
+
+### Changed
+
+* Tests etc. are now ignored for archive exports
+
+## [5.1.0] - 2020-04-14
+
+### Added
+
+* `Runtime::performsJustInTimeCompilation()` returns `true` if PHP 8's JIT is active, `false` otherwise
+
+## [5.0.2] - 2020-03-31
+
+### Fixed
+
+* [#55](https://github.com/sebastianbergmann/environment/issues/55): `stty` command is executed even if no tty is available
+
+## [5.0.1] - 2020-02-19
+
+### Changed
+
+* `Runtime::getNameWithVersionAndCodeCoverageDriver()` now prioritizes PCOV over Xdebug when both extensions are loaded (just like php-code-coverage does)
+
+## [5.0.0] - 2020-02-07
+
+### Removed
+
+* This component is no longer supported on PHP 7.1 and PHP 7.2
+
+## [4.2.3] - 2019-11-20
+
+### Changed
+
+* [#50](https://github.com/sebastianbergmann/environment/pull/50): Windows improvements to console capabilities
+
+### Fixed
+
+* [#49](https://github.com/sebastianbergmann/environment/issues/49): Detection how OpCache handles docblocks does not work correctly when PHPDBG is used
+
+## [4.2.2] - 2019-05-05
+
+### Fixed
+
+* [#44](https://github.com/sebastianbergmann/environment/pull/44): `TypeError` in `Console::getNumberOfColumnsInteractive()`
+
+## [4.2.1] - 2019-04-25
+
+### Fixed
+
+* Fixed an issue in `Runtime::getCurrentSettings()`
+
+## [4.2.0] - 2019-04-25
+
+### Added
+
+* [#36](https://github.com/sebastianbergmann/environment/pull/36): `Runtime::getCurrentSettings()`
+
+## [4.1.0] - 2019-02-01
+
+### Added
+
+* Implemented `Runtime::getNameWithVersionAndCodeCoverageDriver()` method
+* [#34](https://github.com/sebastianbergmann/environment/pull/34): Support for PCOV extension
+
+## [4.0.2] - 2019-01-28
+
+### Fixed
+
+* [#33](https://github.com/sebastianbergmann/environment/issues/33): `Runtime::discardsComments()` returns true too eagerly
+
+### Removed
+
+* Removed support for Zend Optimizer+ in `Runtime::discardsComments()`
+
+## [4.0.1] - 2018-11-25
+
+### Fixed
+
+* [#31](https://github.com/sebastianbergmann/environment/issues/31): Regressions in `Console` class
+
+## [4.0.0] - 2018-10-23 [YANKED]
+
+### Fixed
+
+* [#25](https://github.com/sebastianbergmann/environment/pull/25): `Console::hasColorSupport()` does not work on Windows
+
+### Removed
+
+* This component is no longer supported on PHP 7.0
+
+## [3.1.0] - 2017-07-01
+
+### Added
+
+* [#21](https://github.com/sebastianbergmann/environment/issues/21): Equivalent of `PHP_OS_FAMILY` (for PHP < 7.2)
+
+## [3.0.4] - 2017-06-20
+
+### Fixed
+
+* [#20](https://github.com/sebastianbergmann/environment/pull/20): PHP 7 mode of HHVM not forced
+
+## [3.0.3] - 2017-05-18
+
+### Fixed
+
+* [#18](https://github.com/sebastianbergmann/environment/issues/18): `Uncaught TypeError: preg_match() expects parameter 2 to be string, null given`
+
+## [3.0.2] - 2017-04-21
+
+### Fixed
+
+* [#17](https://github.com/sebastianbergmann/environment/issues/17): `Uncaught TypeError: trim() expects parameter 1 to be string, boolean given`
+
+## [3.0.1] - 2017-04-21
+
+### Fixed
+
+* Fixed inverted logic in `Runtime::discardsComments()`
+
+## [3.0.0] - 2017-04-21
+
+### Added
+
+* Implemented `Runtime::discardsComments()` for querying whether the PHP runtime discards annotations
+
+### Removed
+
+* This component is no longer supported on PHP 5.6
+
+[5.1.3]: https://github.com/sebastianbergmann/environment/compare/5.1.2...5.1.3
+[5.1.2]: https://github.com/sebastianbergmann/environment/compare/5.1.1...5.1.2
+[5.1.1]: https://github.com/sebastianbergmann/environment/compare/5.1.0...5.1.1
+[5.1.0]: https://github.com/sebastianbergmann/environment/compare/5.0.2...5.1.0
+[5.0.2]: https://github.com/sebastianbergmann/environment/compare/5.0.1...5.0.2
+[5.0.1]: https://github.com/sebastianbergmann/environment/compare/5.0.0...5.0.1
+[5.0.0]: https://github.com/sebastianbergmann/environment/compare/4.2.3...5.0.0
+[4.2.3]: https://github.com/sebastianbergmann/environment/compare/4.2.2...4.2.3
+[4.2.2]: https://github.com/sebastianbergmann/environment/compare/4.2.1...4.2.2
+[4.2.1]: https://github.com/sebastianbergmann/environment/compare/4.2.0...4.2.1
+[4.2.0]: https://github.com/sebastianbergmann/environment/compare/4.1.0...4.2.0
+[4.1.0]: https://github.com/sebastianbergmann/environment/compare/4.0.2...4.1.0
+[4.0.2]: https://github.com/sebastianbergmann/environment/compare/4.0.1...4.0.2
+[4.0.1]: https://github.com/sebastianbergmann/environment/compare/66691f8e2dc4641909166b275a9a4f45c0e89092...4.0.1
+[4.0.0]: https://github.com/sebastianbergmann/environment/compare/3.1.0...66691f8e2dc4641909166b275a9a4f45c0e89092
+[3.1.0]: https://github.com/sebastianbergmann/environment/compare/3.0...3.1.0
+[3.0.4]: https://github.com/sebastianbergmann/environment/compare/3.0.3...3.0.4
+[3.0.3]: https://github.com/sebastianbergmann/environment/compare/3.0.2...3.0.3
+[3.0.2]: https://github.com/sebastianbergmann/environment/compare/3.0.1...3.0.2
+[3.0.1]: https://github.com/sebastianbergmann/environment/compare/3.0.0...3.0.1
+[3.0.0]: https://github.com/sebastianbergmann/environment/compare/2.0...3.0.0
+
diff --git a/vendor/sebastian/environment/LICENSE b/vendor/sebastian/environment/LICENSE
new file mode 100644
index 000000000..c58093991
--- /dev/null
+++ b/vendor/sebastian/environment/LICENSE
@@ -0,0 +1,33 @@
+sebastian/environment
+
+Copyright (c) 2014-2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/environment/README.md b/vendor/sebastian/environment/README.md
new file mode 100644
index 000000000..24a9831e4
--- /dev/null
+++ b/vendor/sebastian/environment/README.md
@@ -0,0 +1,22 @@
+# sebastian/environment
+
+[![Latest Stable Version](https://img.shields.io/packagist/v/sebastian/environment.svg?style=flat-square)](https://packagist.org/packages/sebastian/environment)
+[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg?style=flat-square)](https://php.net/)
+[![CI Status](https://github.com/sebastianbergmann/environment/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/environment/actions)
+[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/environment/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/environment)
+
+This component provides functionality that helps writing PHP code that has runtime-specific (PHP / HHVM) execution paths.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/environment
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/environment
+```
diff --git a/vendor/sebastian/environment/composer.json b/vendor/sebastian/environment/composer.json
new file mode 100644
index 000000000..d50dcfd78
--- /dev/null
+++ b/vendor/sebastian/environment/composer.json
@@ -0,0 +1,40 @@
+{
+ "name": "sebastian/environment",
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "keywords": ["environment","hhvm","xdebug"],
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]"
+ }
+ ],
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "prefer-stable": true,
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-posix": "*"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.1-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/environment/src/Console.php b/vendor/sebastian/environment/src/Console.php
new file mode 100644
index 000000000..c4a2348f0
--- /dev/null
+++ b/vendor/sebastian/environment/src/Console.php
@@ -0,0 +1,189 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/environment.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Environment;
+
+use const DIRECTORY_SEPARATOR;
+use const STDIN;
+use const STDOUT;
+use function defined;
+use function fclose;
+use function fstat;
+use function function_exists;
+use function getenv;
+use function is_resource;
+use function is_string;
+use function posix_isatty;
+use function preg_match;
+use function proc_close;
+use function proc_open;
+use function sapi_windows_vt100_support;
+use function shell_exec;
+use function stream_get_contents;
+use function stream_isatty;
+use function trim;
+
+final class Console
+{
+ /**
+ * @var int
+ */
+ public const STDIN = 0;
+
+ /**
+ * @var int
+ */
+ public const STDOUT = 1;
+
+ /**
+ * @var int
+ */
+ public const STDERR = 2;
+
+ /**
+ * Returns true if STDOUT supports colorization.
+ *
+ * This code has been copied and adapted from
+ * Symfony\Component\Console\Output\StreamOutput.
+ */
+ public function hasColorSupport(): bool
+ {
+ if ('Hyper' === getenv('TERM_PROGRAM')) {
+ return true;
+ }
+
+ if ($this->isWindows()) {
+ // @codeCoverageIgnoreStart
+ return (defined('STDOUT') && function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support(STDOUT))
+ || false !== getenv('ANSICON')
+ || 'ON' === getenv('ConEmuANSI')
+ || 'xterm' === getenv('TERM');
+ // @codeCoverageIgnoreEnd
+ }
+
+ if (!defined('STDOUT')) {
+ // @codeCoverageIgnoreStart
+ return false;
+ // @codeCoverageIgnoreEnd
+ }
+
+ return $this->isInteractive(STDOUT);
+ }
+
+ /**
+ * Returns the number of columns of the terminal.
+ *
+ * @codeCoverageIgnore
+ */
+ public function getNumberOfColumns(): int
+ {
+ if (!$this->isInteractive(defined('STDIN') ? STDIN : self::STDIN)) {
+ return 80;
+ }
+
+ if ($this->isWindows()) {
+ return $this->getNumberOfColumnsWindows();
+ }
+
+ return $this->getNumberOfColumnsInteractive();
+ }
+
+ /**
+ * Returns if the file descriptor is an interactive terminal or not.
+ *
+ * Normally, we want to use a resource as a parameter, yet sadly it's not always awailable,
+ * eg when running code in interactive console (`php -a`), STDIN/STDOUT/STDERR constants are not defined.
+ *
+ * @param int|resource $fileDescriptor
+ */
+ public function isInteractive($fileDescriptor = self::STDOUT): bool
+ {
+ if (is_resource($fileDescriptor)) {
+ // These functions require a descriptor that is a real resource, not a numeric ID of it
+ if (function_exists('stream_isatty') && @stream_isatty($fileDescriptor)) {
+ return true;
+ }
+
+ // Check if formatted mode is S_IFCHR
+ if (function_exists('fstat') && @stream_isatty($fileDescriptor)) {
+ $stat = @fstat(STDOUT);
+
+ return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
+ }
+
+ return false;
+ }
+
+ return function_exists('posix_isatty') && @posix_isatty($fileDescriptor);
+ }
+
+ private function isWindows(): bool
+ {
+ return DIRECTORY_SEPARATOR === '\\';
+ }
+
+ /**
+ * @codeCoverageIgnore
+ */
+ private function getNumberOfColumnsInteractive(): int
+ {
+ if (function_exists('shell_exec') && preg_match('#\d+ (\d+)#', shell_exec('stty size') ?: '', $match) === 1) {
+ if ((int) $match[1] > 0) {
+ return (int) $match[1];
+ }
+ }
+
+ if (function_exists('shell_exec') && preg_match('#columns = (\d+);#', shell_exec('stty') ?: '', $match) === 1) {
+ if ((int) $match[1] > 0) {
+ return (int) $match[1];
+ }
+ }
+
+ return 80;
+ }
+
+ /**
+ * @codeCoverageIgnore
+ */
+ private function getNumberOfColumnsWindows(): int
+ {
+ $ansicon = getenv('ANSICON');
+ $columns = 80;
+
+ if (is_string($ansicon) && preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim($ansicon), $matches)) {
+ $columns = (int) $matches[1];
+ } elseif (function_exists('proc_open')) {
+ $process = proc_open(
+ 'mode CON',
+ [
+ 1 => ['pipe', 'w'],
+ 2 => ['pipe', 'w'],
+ ],
+ $pipes,
+ null,
+ null,
+ ['suppress_errors' => true]
+ );
+
+ if (is_resource($process)) {
+ $info = stream_get_contents($pipes[1]);
+
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+ proc_close($process);
+
+ if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
+ $columns = (int) $matches[2];
+ }
+ }
+ }
+
+ return $columns - 1;
+ }
+}
diff --git a/vendor/sebastian/environment/src/OperatingSystem.php b/vendor/sebastian/environment/src/OperatingSystem.php
new file mode 100644
index 000000000..1f3ebca7c
--- /dev/null
+++ b/vendor/sebastian/environment/src/OperatingSystem.php
@@ -0,0 +1,53 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/environment.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Environment;
+
+use const DIRECTORY_SEPARATOR;
+use const PHP_OS;
+use const PHP_OS_FAMILY;
+use function defined;
+
+final class OperatingSystem
+{
+ /**
+ * Returns PHP_OS_FAMILY (if defined (which it is on PHP >= 7.2)).
+ * Returns a string (compatible with PHP_OS_FAMILY) derived from PHP_OS otherwise.
+ */
+ public function getFamily(): string
+ {
+ if (defined('PHP_OS_FAMILY')) {
+ return PHP_OS_FAMILY;
+ }
+
+ if (DIRECTORY_SEPARATOR === '\\') {
+ return 'Windows';
+ }
+
+ switch (PHP_OS) {
+ case 'Darwin':
+ return 'Darwin';
+
+ case 'DragonFly':
+ case 'FreeBSD':
+ case 'NetBSD':
+ case 'OpenBSD':
+ return 'BSD';
+
+ case 'Linux':
+ return 'Linux';
+
+ case 'SunOS':
+ return 'Solaris';
+
+ default:
+ return 'Unknown';
+ }
+ }
+}
diff --git a/vendor/sebastian/environment/src/Runtime.php b/vendor/sebastian/environment/src/Runtime.php
new file mode 100644
index 000000000..311aefcb6
--- /dev/null
+++ b/vendor/sebastian/environment/src/Runtime.php
@@ -0,0 +1,317 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/environment.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Environment;
+
+use const PHP_BINARY;
+use const PHP_BINDIR;
+use const PHP_MAJOR_VERSION;
+use const PHP_SAPI;
+use const PHP_VERSION;
+use function array_map;
+use function array_merge;
+use function defined;
+use function escapeshellarg;
+use function explode;
+use function extension_loaded;
+use function getenv;
+use function ini_get;
+use function is_readable;
+use function parse_ini_file;
+use function php_ini_loaded_file;
+use function php_ini_scanned_files;
+use function phpversion;
+use function sprintf;
+use function strpos;
+
+/**
+ * Utility class for HHVM/PHP environment handling.
+ */
+final class Runtime
+{
+ /**
+ * @var string
+ */
+ private static $binary;
+
+ /**
+ * Returns true when Xdebug or PCOV is available or
+ * the runtime used is PHPDBG.
+ */
+ public function canCollectCodeCoverage(): bool
+ {
+ return $this->hasXdebug() || $this->hasPCOV() || $this->hasPHPDBGCodeCoverage();
+ }
+
+ /**
+ * Returns true when Zend OPcache is loaded, enabled,
+ * and is configured to discard comments.
+ */
+ public function discardsComments(): bool
+ {
+ if (!$this->isOpcacheActive()) {
+ return false;
+ }
+
+ if (ini_get('opcache.save_comments') !== '0') {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns true when Zend OPcache is loaded, enabled,
+ * and is configured to perform just-in-time compilation.
+ */
+ public function performsJustInTimeCompilation(): bool
+ {
+ if (PHP_MAJOR_VERSION < 8) {
+ return false;
+ }
+
+ if (!$this->isOpcacheActive()) {
+ return false;
+ }
+
+ if (strpos(ini_get('opcache.jit'), '0') === 0) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the path to the binary of the current runtime.
+ * Appends ' --php' to the path when the runtime is HHVM.
+ */
+ public function getBinary(): string
+ {
+ // HHVM
+ if (self::$binary === null && $this->isHHVM()) {
+ // @codeCoverageIgnoreStart
+ if ((self::$binary = getenv('PHP_BINARY')) === false) {
+ self::$binary = PHP_BINARY;
+ }
+
+ self::$binary = escapeshellarg(self::$binary) . ' --php' .
+ ' -d hhvm.php7.all=1';
+ // @codeCoverageIgnoreEnd
+ }
+
+ if (self::$binary === null && PHP_BINARY !== '') {
+ self::$binary = escapeshellarg(PHP_BINARY);
+ }
+
+ if (self::$binary === null) {
+ // @codeCoverageIgnoreStart
+ $possibleBinaryLocations = [
+ PHP_BINDIR . '/php',
+ PHP_BINDIR . '/php-cli.exe',
+ PHP_BINDIR . '/php.exe',
+ ];
+
+ foreach ($possibleBinaryLocations as $binary) {
+ if (is_readable($binary)) {
+ self::$binary = escapeshellarg($binary);
+
+ break;
+ }
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ if (self::$binary === null) {
+ // @codeCoverageIgnoreStart
+ self::$binary = 'php';
+ // @codeCoverageIgnoreEnd
+ }
+
+ return self::$binary;
+ }
+
+ public function getNameWithVersion(): string
+ {
+ return $this->getName() . ' ' . $this->getVersion();
+ }
+
+ public function getNameWithVersionAndCodeCoverageDriver(): string
+ {
+ if (!$this->canCollectCodeCoverage() || $this->hasPHPDBGCodeCoverage()) {
+ return $this->getNameWithVersion();
+ }
+
+ if ($this->hasPCOV()) {
+ return sprintf(
+ '%s with PCOV %s',
+ $this->getNameWithVersion(),
+ phpversion('pcov')
+ );
+ }
+
+ if ($this->hasXdebug()) {
+ return sprintf(
+ '%s with Xdebug %s',
+ $this->getNameWithVersion(),
+ phpversion('xdebug')
+ );
+ }
+ }
+
+ public function getName(): string
+ {
+ if ($this->isHHVM()) {
+ // @codeCoverageIgnoreStart
+ return 'HHVM';
+ // @codeCoverageIgnoreEnd
+ }
+
+ if ($this->isPHPDBG()) {
+ // @codeCoverageIgnoreStart
+ return 'PHPDBG';
+ // @codeCoverageIgnoreEnd
+ }
+
+ return 'PHP';
+ }
+
+ public function getVendorUrl(): string
+ {
+ if ($this->isHHVM()) {
+ // @codeCoverageIgnoreStart
+ return 'http://hhvm.com/';
+ // @codeCoverageIgnoreEnd
+ }
+
+ return 'https://secure.php.net/';
+ }
+
+ public function getVersion(): string
+ {
+ if ($this->isHHVM()) {
+ // @codeCoverageIgnoreStart
+ return HHVM_VERSION;
+ // @codeCoverageIgnoreEnd
+ }
+
+ return PHP_VERSION;
+ }
+
+ /**
+ * Returns true when the runtime used is PHP and Xdebug is loaded.
+ */
+ public function hasXdebug(): bool
+ {
+ return ($this->isPHP() || $this->isHHVM()) && extension_loaded('xdebug');
+ }
+
+ /**
+ * Returns true when the runtime used is HHVM.
+ */
+ public function isHHVM(): bool
+ {
+ return defined('HHVM_VERSION');
+ }
+
+ /**
+ * Returns true when the runtime used is PHP without the PHPDBG SAPI.
+ */
+ public function isPHP(): bool
+ {
+ return !$this->isHHVM() && !$this->isPHPDBG();
+ }
+
+ /**
+ * Returns true when the runtime used is PHP with the PHPDBG SAPI.
+ */
+ public function isPHPDBG(): bool
+ {
+ return PHP_SAPI === 'phpdbg' && !$this->isHHVM();
+ }
+
+ /**
+ * Returns true when the runtime used is PHP with the PHPDBG SAPI
+ * and the phpdbg_*_oplog() functions are available (PHP >= 7.0).
+ */
+ public function hasPHPDBGCodeCoverage(): bool
+ {
+ return $this->isPHPDBG();
+ }
+
+ /**
+ * Returns true when the runtime used is PHP with PCOV loaded and enabled.
+ */
+ public function hasPCOV(): bool
+ {
+ return $this->isPHP() && extension_loaded('pcov') && ini_get('pcov.enabled');
+ }
+
+ /**
+ * Parses the loaded php.ini file (if any) as well as all
+ * additional php.ini files from the additional ini dir for
+ * a list of all configuration settings loaded from files
+ * at startup. Then checks for each php.ini setting passed
+ * via the `$values` parameter whether this setting has
+ * been changed at runtime. Returns an array of strings
+ * where each string has the format `key=value` denoting
+ * the name of a changed php.ini setting with its new value.
+ *
+ * @return string[]
+ */
+ public function getCurrentSettings(array $values): array
+ {
+ $diff = [];
+ $files = [];
+
+ if ($file = php_ini_loaded_file()) {
+ $files[] = $file;
+ }
+
+ if ($scanned = php_ini_scanned_files()) {
+ $files = array_merge(
+ $files,
+ array_map(
+ 'trim',
+ explode(",\n", $scanned)
+ )
+ );
+ }
+
+ foreach ($files as $ini) {
+ $config = parse_ini_file($ini, true);
+
+ foreach ($values as $value) {
+ $set = ini_get($value);
+
+ if (isset($config[$value]) && $set != $config[$value]) {
+ $diff[] = sprintf('%s=%s', $value, $set);
+ }
+ }
+ }
+
+ return $diff;
+ }
+
+ private function isOpcacheActive(): bool
+ {
+ if (!extension_loaded('Zend OPcache')) {
+ return false;
+ }
+
+ if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') && ini_get('opcache.enable_cli') === '1') {
+ return true;
+ }
+
+ if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg' && ini_get('opcache.enable') === '1') {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/sebastian/exporter/ChangeLog.md b/vendor/sebastian/exporter/ChangeLog.md
new file mode 100644
index 000000000..c691e81ab
--- /dev/null
+++ b/vendor/sebastian/exporter/ChangeLog.md
@@ -0,0 +1,64 @@
+# ChangeLog
+
+All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
+
+## [4.0.4] - 2021-11-11
+
+### Changed
+
+* [#37](https://github.com/sebastianbergmann/exporter/pull/37): Improve export of closed resources
+
+## [4.0.3] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [4.0.2] - 2020-06-26
+
+### Added
+
+* This component is now supported on PHP 8
+
+## [4.0.1] - 2020-06-15
+
+### Changed
+
+* Tests etc. are now ignored for archive exports
+
+## [4.0.0] - 2020-02-07
+
+### Removed
+
+* This component is no longer supported on PHP 7.0, PHP 7.1, and PHP 7.2
+
+## [3.1.4] - 2021-11-11
+
+### Changed
+
+* [#38](https://github.com/sebastianbergmann/exporter/pull/38): Improve export of closed resources
+
+## [3.1.3] - 2020-11-30
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.0` to `>=7.0`
+
+## [3.1.2] - 2019-09-14
+
+### Fixed
+
+* [#29](https://github.com/sebastianbergmann/exporter/pull/29): Second parameter for `str_repeat()` must be an integer
+
+### Removed
+
+* Remove HHVM-specific code that is no longer needed
+
+[4.0.4]: https://github.com/sebastianbergmann/exporter/compare/4.0.3...4.0.4
+[4.0.3]: https://github.com/sebastianbergmann/exporter/compare/4.0.2...4.0.3
+[4.0.2]: https://github.com/sebastianbergmann/exporter/compare/4.0.1...4.0.2
+[4.0.1]: https://github.com/sebastianbergmann/exporter/compare/4.0.0...4.0.1
+[4.0.0]: https://github.com/sebastianbergmann/exporter/compare/3.1.2...4.0.0
+[3.1.4]: https://github.com/sebastianbergmann/exporter/compare/3.1.3...3.1.4
+[3.1.3]: https://github.com/sebastianbergmann/exporter/compare/3.1.2...3.1.3
+[3.1.2]: https://github.com/sebastianbergmann/exporter/compare/3.1.1...3.1.2
diff --git a/vendor/sebastian/exporter/LICENSE b/vendor/sebastian/exporter/LICENSE
new file mode 100644
index 000000000..26dc7feca
--- /dev/null
+++ b/vendor/sebastian/exporter/LICENSE
@@ -0,0 +1,33 @@
+Exporter
+
+Copyright (c) 2002-2021, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/exporter/README.md b/vendor/sebastian/exporter/README.md
new file mode 100644
index 000000000..ed8719f56
--- /dev/null
+++ b/vendor/sebastian/exporter/README.md
@@ -0,0 +1,174 @@
+# sebastian/exporter
+
+[![CI Status](https://github.com/sebastianbergmann/exporter/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/exporter/actions)
+[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/exporter/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/exporter)
+
+This component provides the functionality to export PHP variables for visualization.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/exporter
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/exporter
+```
+
+## Usage
+
+Exporting:
+
+```php
+<?php
+use SebastianBergmann\Exporter\Exporter;
+
+$exporter = new Exporter;
+
+/*
+Exception Object &0000000078de0f0d000000002003a261 (
+ 'message' => ''
+ 'string' => ''
+ 'code' => 0
+ 'file' => '/home/sebastianbergmann/test.php'
+ 'line' => 34
+ 'previous' => null
+)
+*/
+
+print $exporter->export(new Exception);
+```
+
+## Data Types
+
+Exporting simple types:
+
+```php
+<?php
+use SebastianBergmann\Exporter\Exporter;
+
+$exporter = new Exporter;
+
+// 46
+print $exporter->export(46);
+
+// 4.0
+print $exporter->export(4.0);
+
+// 'hello, world!'
+print $exporter->export('hello, world!');
+
+// false
+print $exporter->export(false);
+
+// NAN
+print $exporter->export(acos(8));
+
+// -INF
+print $exporter->export(log(0));
+
+// null
+print $exporter->export(null);
+
+// resource(13) of type (stream)
+print $exporter->export(fopen('php://stderr', 'w'));
+
+// Binary String: 0x000102030405
+print $exporter->export(chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5));
+```
+
+Exporting complex types:
+
+```php
+<?php
+use SebastianBergmann\Exporter\Exporter;
+
+$exporter = new Exporter;
+
+/*
+Array &0 (
+ 0 => Array &1 (
+ 0 => 1
+ 1 => 2
+ 2 => 3
+ )
+ 1 => Array &2 (
+ 0 => ''
+ 1 => 0
+ 2 => false
+ )
+)
+*/
+
+print $exporter->export(array(array(1,2,3), array("",0,FALSE)));
+
+/*
+Array &0 (
+ 'self' => Array &1 (
+ 'self' => Array &1
+ )
+)
+*/
+
+$array = array();
+$array['self'] = &$array;
+print $exporter->export($array);
+
+/*
+stdClass Object &0000000003a66dcc0000000025e723e2 (
+ 'self' => stdClass Object &0000000003a66dcc0000000025e723e2
+)
+*/
+
+$obj = new stdClass();
+$obj->self = $obj;
+print $exporter->export($obj);
+```
+
+Compact exports:
+
+```php
+<?php
+use SebastianBergmann\Exporter\Exporter;
+
+$exporter = new Exporter;
+
+// Array ()
+print $exporter->shortenedExport(array());
+
+// Array (...)
+print $exporter->shortenedExport(array(1,2,3,4,5));
+
+// stdClass Object ()
+print $exporter->shortenedExport(new stdClass);
+
+// Exception Object (...)
+print $exporter->shortenedExport(new Exception);
+
+// this\nis\na\nsuper\nlong\nstring\nt...\nspace
+print $exporter->shortenedExport(
+<<<LONG_STRING
+this
+is
+a
+super
+long
+string
+that
+wraps
+a
+lot
+and
+eats
+up
+a
+lot
+of
+space
+LONG_STRING
+);
+```
diff --git a/vendor/sebastian/exporter/composer.json b/vendor/sebastian/exporter/composer.json
new file mode 100644
index 000000000..baa958443
--- /dev/null
+++ b/vendor/sebastian/exporter/composer.json
@@ -0,0 +1,56 @@
+{
+ "name": "sebastian/exporter",
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "keywords": ["exporter","export"],
+ "homepage": "https://www.github.com/sebastianbergmann/exporter",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "[email protected]"
+ }
+ ],
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "prefer-stable": true,
+ "require": {
+ "php": ">=7.3",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3",
+ "ext-mbstring": "*"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ }
+}
+
diff --git a/vendor/sebastian/exporter/src/Exporter.php b/vendor/sebastian/exporter/src/Exporter.php
new file mode 100644
index 000000000..692a0b21f
--- /dev/null
+++ b/vendor/sebastian/exporter/src/Exporter.php
@@ -0,0 +1,330 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/exporter.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Exporter;
+
+use function bin2hex;
+use function count;
+use function function_exists;
+use function get_class;
+use function get_resource_type;
+use function gettype;
+use function implode;
+use function is_array;
+use function is_float;
+use function is_object;
+use function is_resource;
+use function is_string;
+use function mb_strlen;
+use function mb_substr;
+use function preg_match;
+use function spl_object_hash;
+use function sprintf;
+use function str_repeat;
+use function str_replace;
+use function strlen;
+use function substr;
+use function var_export;
+use SebastianBergmann\RecursionContext\Context;
+use SplObjectStorage;
+
+/**
+ * A nifty utility for visualizing PHP variables.
+ *
+ * <code>
+ * <?php
+ * use SebastianBergmann\Exporter\Exporter;
+ *
+ * $exporter = new Exporter;
+ * print $exporter->export(new Exception);
+ * </code>
+ */
+class Exporter
+{
+ /**
+ * Exports a value as a string.
+ *
+ * The output of this method is similar to the output of print_r(), but
+ * improved in various aspects:
+ *
+ * - NULL is rendered as "null" (instead of "")
+ * - TRUE is rendered as "true" (instead of "1")
+ * - FALSE is rendered as "false" (instead of "")
+ * - Strings are always quoted with single quotes
+ * - Carriage returns and newlines are normalized to \n
+ * - Recursion and repeated rendering is treated properly
+ *
+ * @param int $indentation The indentation level of the 2nd+ line
+ *
+ * @return string
+ */
+ public function export($value, $indentation = 0)
+ {
+ return $this->recursiveExport($value, $indentation);
+ }
+
+ /**
+ * @param array<mixed> $data
+ * @param Context $context
+ *
+ * @return string
+ */
+ public function shortenedRecursiveExport(&$data, Context $context = null)
+ {
+ $result = [];
+ $exporter = new self();
+
+ if (!$context) {
+ $context = new Context;
+ }
+
+ $array = $data;
+ $context->add($data);
+
+ foreach ($array as $key => $value) {
+ if (is_array($value)) {
+ if ($context->contains($data[$key]) !== false) {
+ $result[] = '*RECURSION*';
+ } else {
+ $result[] = sprintf(
+ 'array(%s)',
+ $this->shortenedRecursiveExport($data[$key], $context)
+ );
+ }
+ } else {
+ $result[] = $exporter->shortenedExport($value);
+ }
+ }
+
+ return implode(', ', $result);
+ }
+
+ /**
+ * Exports a value into a single-line string.
+ *
+ * The output of this method is similar to the output of
+ * SebastianBergmann\Exporter\Exporter::export().
+ *
+ * Newlines are replaced by the visible string '\n'.
+ * Contents of arrays and objects (if any) are replaced by '...'.
+ *
+ * @return string
+ *
+ * @see SebastianBergmann\Exporter\Exporter::export
+ */
+ public function shortenedExport($value)
+ {
+ if (is_string($value)) {
+ $string = str_replace("\n", '', $this->export($value));
+
+ if (function_exists('mb_strlen')) {
+ if (mb_strlen($string) > 40) {
+ $string = mb_substr($string, 0, 30) . '...' . mb_substr($string, -7);
+ }
+ } else {
+ if (strlen($string) > 40) {
+ $string = substr($string, 0, 30) . '...' . substr($string, -7);
+ }
+ }
+
+ return $string;
+ }
+
+ if (is_object($value)) {
+ return sprintf(
+ '%s Object (%s)',
+ get_class($value),
+ count($this->toArray($value)) > 0 ? '...' : ''
+ );
+ }
+
+ if (is_array($value)) {
+ return sprintf(
+ 'Array (%s)',
+ count($value) > 0 ? '...' : ''
+ );
+ }
+
+ return $this->export($value);
+ }
+
+ /**
+ * Converts an object to an array containing all of its private, protected
+ * and public properties.
+ *
+ * @return array
+ */
+ public function toArray($value)
+ {
+ if (!is_object($value)) {
+ return (array) $value;
+ }
+
+ $array = [];
+
+ foreach ((array) $value as $key => $val) {
+ // Exception traces commonly reference hundreds to thousands of
+ // objects currently loaded in memory. Including them in the result
+ // has a severe negative performance impact.
+ if ("\0Error\0trace" === $key || "\0Exception\0trace" === $key) {
+ continue;
+ }
+
+ // properties are transformed to keys in the following way:
+ // private $property => "\0Classname\0property"
+ // protected $property => "\0*\0property"
+ // public $property => "property"
+ if (preg_match('/^\0.+\0(.+)$/', (string) $key, $matches)) {
+ $key = $matches[1];
+ }
+
+ // See https://github.com/php/php-src/commit/5721132
+ if ($key === "\0gcdata") {
+ continue;
+ }
+
+ $array[$key] = $val;
+ }
+
+ // Some internal classes like SplObjectStorage don't work with the
+ // above (fast) mechanism nor with reflection in Zend.
+ // Format the output similarly to print_r() in this case
+ if ($value instanceof SplObjectStorage) {
+ foreach ($value as $key => $val) {
+ $array[spl_object_hash($val)] = [
+ 'obj' => $val,
+ 'inf' => $value->getInfo(),
+ ];
+ }
+ }
+
+ return $array;
+ }
+
+ /**
+ * Recursive implementation of export.
+ *
+ * @param mixed $value The value to export
+ * @param int $indentation The indentation level of the 2nd+ line
+ * @param \SebastianBergmann\RecursionContext\Context $processed Previously processed objects
+ *
+ * @return string
+ *
+ * @see SebastianBergmann\Exporter\Exporter::export
+ */
+ protected function recursiveExport(&$value, $indentation, $processed = null)
+ {
+ if ($value === null) {
+ return 'null';
+ }
+
+ if ($value === true) {
+ return 'true';
+ }
+
+ if ($value === false) {
+ return 'false';
+ }
+
+ if (is_float($value) && (float) ((int) $value) === $value) {
+ return "{$value}.0";
+ }
+
+ if (gettype($value) === 'resource (closed)') {
+ return 'resource (closed)';
+ }
+
+ if (is_resource($value)) {
+ return sprintf(
+ 'resource(%d) of type (%s)',
+ $value,
+ get_resource_type($value)
+ );
+ }
+
+ if (is_string($value)) {
+ // Match for most non printable chars somewhat taking multibyte chars into account
+ if (preg_match('/[^\x09-\x0d\x1b\x20-\xff]/', $value)) {
+ return 'Binary String: 0x' . bin2hex($value);
+ }
+
+ return "'" .
+ str_replace(
+ '<lf>',
+ "\n",
+ str_replace(
+ ["\r\n", "\n\r", "\r", "\n"],
+ ['\r\n<lf>', '\n\r<lf>', '\r<lf>', '\n<lf>'],
+ $value
+ )
+ ) .
+ "'";
+ }
+
+ $whitespace = str_repeat(' ', 4 * $indentation);
+
+ if (!$processed) {
+ $processed = new Context;
+ }
+
+ if (is_array($value)) {
+ if (($key = $processed->contains($value)) !== false) {
+ return 'Array &' . $key;
+ }
+
+ $array = $value;
+ $key = $processed->add($value);
+ $values = '';
+
+ if (count($array) > 0) {
+ foreach ($array as $k => $v) {
+ $values .= sprintf(
+ '%s %s => %s' . "\n",
+ $whitespace,
+ $this->recursiveExport($k, $indentation),
+ $this->recursiveExport($value[$k], $indentation + 1, $processed)
+ );
+ }
+
+ $values = "\n" . $values . $whitespace;
+ }
+
+ return sprintf('Array &%s (%s)', $key, $values);
+ }
+
+ if (is_object($value)) {
+ $class = get_class($value);
+
+ if ($hash = $processed->contains($value)) {
+ return sprintf('%s Object &%s', $class, $hash);
+ }
+
+ $hash = $processed->add($value);
+ $values = '';
+ $array = $this->toArray($value);
+
+ if (count($array) > 0) {
+ foreach ($array as $k => $v) {
+ $values .= sprintf(
+ '%s %s => %s' . "\n",
+ $whitespace,
+ $this->recursiveExport($k, $indentation),
+ $this->recursiveExport($v, $indentation + 1, $processed)
+ );
+ }
+
+ $values = "\n" . $values . $whitespace;
+ }
+
+ return sprintf('%s Object &%s (%s)', $class, $hash, $values);
+ }
+
+ return var_export($value, true);
+ }
+}
diff --git a/vendor/sebastian/global-state/ChangeLog.md b/vendor/sebastian/global-state/ChangeLog.md
new file mode 100644
index 000000000..a27a5cf16
--- /dev/null
+++ b/vendor/sebastian/global-state/ChangeLog.md
@@ -0,0 +1,79 @@
+# Changes in sebastian/global-state
+
+All notable changes in `sebastian/global-state` are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
+
+## [5.0.5] - 2022-02-14
+
+### Fixed
+
+* [#34](https://github.com/sebastianbergmann/global-state/pull/34): Uninitialised typed static properties are not handled correctly
+
+## [5.0.4] - 2022-02-10
+
+### Fixed
+
+* The `$includeTraits` parameter of `SebastianBergmann\GlobalState\Snapshot::__construct()` is not respected
+
+## [5.0.3] - 2021-06-11
+
+### Changed
+
+* `SebastianBergmann\GlobalState\CodeExporter::globalVariables()` now generates code that is compatible with PHP 8.1
+
+## [5.0.2] - 2020-10-26
+
+### Fixed
+
+* `SebastianBergmann\GlobalState\Exception` now correctly extends `\Throwable`
+
+## [5.0.1] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [5.0.0] - 2020-08-07
+
+### Changed
+
+* The `SebastianBergmann\GlobalState\Blacklist` class has been renamed to `SebastianBergmann\GlobalState\ExcludeList`
+
+## [4.0.0] - 2020-02-07
+
+### Removed
+
+* This component is no longer supported on PHP 7.2
+
+## [3.0.2] - 2022-02-10
+
+### Fixed
+
+* The `$includeTraits` parameter of `SebastianBergmann\GlobalState\Snapshot::__construct()` is not respected
+
+## [3.0.1] - 2020-11-30
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.2` to `>=7.2`
+
+## [3.0.0] - 2019-02-01
+
+### Changed
+
+* `Snapshot::canBeSerialized()` now recursively checks arrays and object graphs for variables that cannot be serialized
+
+### Removed
+
+* This component is no longer supported on PHP 7.0 and PHP 7.1
+
+[5.0.5]: https://github.com/sebastianbergmann/global-state/compare/5.0.4...5.0.5
+[5.0.4]: https://github.com/sebastianbergmann/global-state/compare/5.0.3...5.0.4
+[5.0.3]: https://github.com/sebastianbergmann/global-state/compare/5.0.2...5.0.3
+[5.0.2]: https://github.com/sebastianbergmann/global-state/compare/5.0.1...5.0.2
+[5.0.1]: https://github.com/sebastianbergmann/global-state/compare/5.0.0...5.0.1
+[5.0.0]: https://github.com/sebastianbergmann/global-state/compare/4.0.0...5.0.0
+[4.0.0]: https://github.com/sebastianbergmann/global-state/compare/3.0.2...4.0.0
+[3.0.2]: https://github.com/sebastianbergmann/phpunit/compare/3.0.1...3.0.2
+[3.0.1]: https://github.com/sebastianbergmann/phpunit/compare/3.0.0...3.0.1
+[3.0.0]: https://github.com/sebastianbergmann/phpunit/compare/2.0.0...3.0.0
+
diff --git a/vendor/sebastian/global-state/LICENSE b/vendor/sebastian/global-state/LICENSE
new file mode 100644
index 000000000..240190bd3
--- /dev/null
+++ b/vendor/sebastian/global-state/LICENSE
@@ -0,0 +1,33 @@
+sebastian/global-state
+
+Copyright (c) 2001-2022, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/global-state/README.md b/vendor/sebastian/global-state/README.md
new file mode 100644
index 000000000..af15bedde
--- /dev/null
+++ b/vendor/sebastian/global-state/README.md
@@ -0,0 +1,20 @@
+# sebastian/global-state
+
+[![CI Status](https://github.com/sebastianbergmann/global-state/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/global-state/actions)
+[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/global-state/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/global-state)
+
+Snapshotting of global state, factored out of PHPUnit into a stand-alone component.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/global-state
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/global-state
+```
diff --git a/vendor/sebastian/global-state/composer.json b/vendor/sebastian/global-state/composer.json
new file mode 100644
index 000000000..0fef446a6
--- /dev/null
+++ b/vendor/sebastian/global-state/composer.json
@@ -0,0 +1,51 @@
+{
+ "name": "sebastian/global-state",
+ "description": "Snapshotting of global state",
+ "keywords": ["global state"],
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]"
+ }
+ ],
+ "prefer-stable": true,
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/object-reflector": "^2.0",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "ext-dom": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "autoload-dev": {
+ "classmap": [
+ "tests/_fixture/"
+ ],
+ "files": [
+ "tests/_fixture/SnapshotFunctions.php"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/global-state/src/CodeExporter.php b/vendor/sebastian/global-state/src/CodeExporter.php
new file mode 100644
index 000000000..71cdbf504
--- /dev/null
+++ b/vendor/sebastian/global-state/src/CodeExporter.php
@@ -0,0 +1,109 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/global-state.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\GlobalState;
+
+use const PHP_EOL;
+use function is_array;
+use function is_scalar;
+use function serialize;
+use function sprintf;
+use function var_export;
+
+/**
+ * Exports parts of a Snapshot as PHP code.
+ */
+final class CodeExporter
+{
+ public function constants(Snapshot $snapshot): string
+ {
+ $result = '';
+
+ foreach ($snapshot->constants() as $name => $value) {
+ $result .= sprintf(
+ 'if (!defined(\'%s\')) define(\'%s\', %s);' . "\n",
+ $name,
+ $name,
+ $this->exportVariable($value)
+ );
+ }
+
+ return $result;
+ }
+
+ public function globalVariables(Snapshot $snapshot): string
+ {
+ $result = <<<'EOT'
+call_user_func(
+ function ()
+ {
+ foreach (array_keys($GLOBALS) as $key) {
+ unset($GLOBALS[$key]);
+ }
+ }
+);
+
+
+EOT;
+
+ foreach ($snapshot->globalVariables() as $name => $value) {
+ $result .= sprintf(
+ '$GLOBALS[%s] = %s;' . PHP_EOL,
+ $this->exportVariable($name),
+ $this->exportVariable($value)
+ );
+ }
+
+ return $result;
+ }
+
+ public function iniSettings(Snapshot $snapshot): string
+ {
+ $result = '';
+
+ foreach ($snapshot->iniSettings() as $key => $value) {
+ $result .= sprintf(
+ '@ini_set(%s, %s);' . "\n",
+ $this->exportVariable($key),
+ $this->exportVariable($value)
+ );
+ }
+
+ return $result;
+ }
+
+ private function exportVariable($variable): string
+ {
+ if (is_scalar($variable) || null === $variable ||
+ (is_array($variable) && $this->arrayOnlyContainsScalars($variable))) {
+ return var_export($variable, true);
+ }
+
+ return 'unserialize(' . var_export(serialize($variable), true) . ')';
+ }
+
+ private function arrayOnlyContainsScalars(array $array): bool
+ {
+ $result = true;
+
+ foreach ($array as $element) {
+ if (is_array($element)) {
+ $result = $this->arrayOnlyContainsScalars($element);
+ } elseif (!is_scalar($element) && null !== $element) {
+ $result = false;
+ }
+
+ if ($result === false) {
+ break;
+ }
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/sebastian/global-state/src/ExcludeList.php b/vendor/sebastian/global-state/src/ExcludeList.php
new file mode 100644
index 000000000..5631f1186
--- /dev/null
+++ b/vendor/sebastian/global-state/src/ExcludeList.php
@@ -0,0 +1,119 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/global-state.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\GlobalState;
+
+use function in_array;
+use function strpos;
+use ReflectionClass;
+
+final class ExcludeList
+{
+ /**
+ * @var array
+ */
+ private $globalVariables = [];
+
+ /**
+ * @var string[]
+ */
+ private $classes = [];
+
+ /**
+ * @var string[]
+ */
+ private $classNamePrefixes = [];
+
+ /**
+ * @var string[]
+ */
+ private $parentClasses = [];
+
+ /**
+ * @var string[]
+ */
+ private $interfaces = [];
+
+ /**
+ * @var array
+ */
+ private $staticAttributes = [];
+
+ public function addGlobalVariable(string $variableName): void
+ {
+ $this->globalVariables[$variableName] = true;
+ }
+
+ public function addClass(string $className): void
+ {
+ $this->classes[] = $className;
+ }
+
+ public function addSubclassesOf(string $className): void
+ {
+ $this->parentClasses[] = $className;
+ }
+
+ public function addImplementorsOf(string $interfaceName): void
+ {
+ $this->interfaces[] = $interfaceName;
+ }
+
+ public function addClassNamePrefix(string $classNamePrefix): void
+ {
+ $this->classNamePrefixes[] = $classNamePrefix;
+ }
+
+ public function addStaticAttribute(string $className, string $attributeName): void
+ {
+ if (!isset($this->staticAttributes[$className])) {
+ $this->staticAttributes[$className] = [];
+ }
+
+ $this->staticAttributes[$className][$attributeName] = true;
+ }
+
+ public function isGlobalVariableExcluded(string $variableName): bool
+ {
+ return isset($this->globalVariables[$variableName]);
+ }
+
+ public function isStaticAttributeExcluded(string $className, string $attributeName): bool
+ {
+ if (in_array($className, $this->classes, true)) {
+ return true;
+ }
+
+ foreach ($this->classNamePrefixes as $prefix) {
+ if (strpos($className, $prefix) === 0) {
+ return true;
+ }
+ }
+
+ $class = new ReflectionClass($className);
+
+ foreach ($this->parentClasses as $type) {
+ if ($class->isSubclassOf($type)) {
+ return true;
+ }
+ }
+
+ foreach ($this->interfaces as $type) {
+ if ($class->implementsInterface($type)) {
+ return true;
+ }
+ }
+
+ if (isset($this->staticAttributes[$className][$attributeName])) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/sebastian/global-state/src/Restorer.php b/vendor/sebastian/global-state/src/Restorer.php
new file mode 100644
index 000000000..1633fcc11
--- /dev/null
+++ b/vendor/sebastian/global-state/src/Restorer.php
@@ -0,0 +1,143 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/global-state.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\GlobalState;
+
+use function array_diff;
+use function array_key_exists;
+use function array_keys;
+use function array_merge;
+use function function_exists;
+use function get_defined_functions;
+use function in_array;
+use function is_array;
+use ReflectionClass;
+use ReflectionProperty;
+
+/**
+ * Restorer of snapshots of global state.
+ */
+class Restorer
+{
+ /**
+ * Deletes function definitions that are not defined in a snapshot.
+ *
+ * @throws RuntimeException when the uopz_delete() function is not available
+ *
+ * @see https://github.com/krakjoe/uopz
+ */
+ public function restoreFunctions(Snapshot $snapshot): void
+ {
+ if (!function_exists('uopz_delete')) {
+ throw new RuntimeException('The uopz_delete() function is required for this operation');
+ }
+
+ $functions = get_defined_functions();
+
+ foreach (array_diff($functions['user'], $snapshot->functions()) as $function) {
+ uopz_delete($function);
+ }
+ }
+
+ /**
+ * Restores all global and super-global variables from a snapshot.
+ */
+ public function restoreGlobalVariables(Snapshot $snapshot): void
+ {
+ $superGlobalArrays = $snapshot->superGlobalArrays();
+
+ foreach ($superGlobalArrays as $superGlobalArray) {
+ $this->restoreSuperGlobalArray($snapshot, $superGlobalArray);
+ }
+
+ $globalVariables = $snapshot->globalVariables();
+
+ foreach (array_keys($GLOBALS) as $key) {
+ if ($key !== 'GLOBALS' &&
+ !in_array($key, $superGlobalArrays, true) &&
+ !$snapshot->excludeList()->isGlobalVariableExcluded($key)) {
+ if (array_key_exists($key, $globalVariables)) {
+ $GLOBALS[$key] = $globalVariables[$key];
+ } else {
+ unset($GLOBALS[$key]);
+ }
+ }
+ }
+ }
+
+ /**
+ * Restores all static attributes in user-defined classes from this snapshot.
+ */
+ public function restoreStaticAttributes(Snapshot $snapshot): void
+ {
+ $current = new Snapshot($snapshot->excludeList(), false, false, false, false, true, false, false, false, false);
+ $newClasses = array_diff($current->classes(), $snapshot->classes());
+
+ unset($current);
+
+ foreach ($snapshot->staticAttributes() as $className => $staticAttributes) {
+ foreach ($staticAttributes as $name => $value) {
+ $reflector = new ReflectionProperty($className, $name);
+ $reflector->setAccessible(true);
+ $reflector->setValue($value);
+ }
+ }
+
+ foreach ($newClasses as $className) {
+ $class = new ReflectionClass($className);
+ $defaults = $class->getDefaultProperties();
+
+ foreach ($class->getProperties() as $attribute) {
+ if (!$attribute->isStatic()) {
+ continue;
+ }
+
+ $name = $attribute->getName();
+
+ if ($snapshot->excludeList()->isStaticAttributeExcluded($className, $name)) {
+ continue;
+ }
+
+ if (!isset($defaults[$name])) {
+ continue;
+ }
+
+ $attribute->setAccessible(true);
+ $attribute->setValue($defaults[$name]);
+ }
+ }
+ }
+
+ /**
+ * Restores a super-global variable array from this snapshot.
+ */
+ private function restoreSuperGlobalArray(Snapshot $snapshot, string $superGlobalArray): void
+ {
+ $superGlobalVariables = $snapshot->superGlobalVariables();
+
+ if (isset($GLOBALS[$superGlobalArray]) &&
+ is_array($GLOBALS[$superGlobalArray]) &&
+ isset($superGlobalVariables[$superGlobalArray])) {
+ $keys = array_keys(
+ array_merge(
+ $GLOBALS[$superGlobalArray],
+ $superGlobalVariables[$superGlobalArray]
+ )
+ );
+
+ foreach ($keys as $key) {
+ if (isset($superGlobalVariables[$superGlobalArray][$key])) {
+ $GLOBALS[$superGlobalArray][$key] = $superGlobalVariables[$superGlobalArray][$key];
+ } else {
+ unset($GLOBALS[$superGlobalArray][$key]);
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/sebastian/global-state/src/Snapshot.php b/vendor/sebastian/global-state/src/Snapshot.php
new file mode 100644
index 000000000..e33264eb0
--- /dev/null
+++ b/vendor/sebastian/global-state/src/Snapshot.php
@@ -0,0 +1,443 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/global-state.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\GlobalState;
+
+use const PHP_VERSION_ID;
+use function array_keys;
+use function array_merge;
+use function array_reverse;
+use function func_get_args;
+use function get_declared_classes;
+use function get_declared_interfaces;
+use function get_declared_traits;
+use function get_defined_constants;
+use function get_defined_functions;
+use function get_included_files;
+use function in_array;
+use function ini_get_all;
+use function is_array;
+use function is_object;
+use function is_resource;
+use function is_scalar;
+use function serialize;
+use function unserialize;
+use ReflectionClass;
+use SebastianBergmann\ObjectReflector\ObjectReflector;
+use SebastianBergmann\RecursionContext\Context;
+use Throwable;
+
+/**
+ * A snapshot of global state.
+ */
+class Snapshot
+{
+ /**
+ * @var ExcludeList
+ */
+ private $excludeList;
+
+ /**
+ * @var array
+ */
+ private $globalVariables = [];
+
+ /**
+ * @var array
+ */
+ private $superGlobalArrays = [];
+
+ /**
+ * @var array
+ */
+ private $superGlobalVariables = [];
+
+ /**
+ * @var array
+ */
+ private $staticAttributes = [];
+
+ /**
+ * @var array
+ */
+ private $iniSettings = [];
+
+ /**
+ * @var array
+ */
+ private $includedFiles = [];
+
+ /**
+ * @var array
+ */
+ private $constants = [];
+
+ /**
+ * @var array
+ */
+ private $functions = [];
+
+ /**
+ * @var array
+ */
+ private $interfaces = [];
+
+ /**
+ * @var array
+ */
+ private $classes = [];
+
+ /**
+ * @var array
+ */
+ private $traits = [];
+
+ /**
+ * Creates a snapshot of the current global state.
+ */
+ public function __construct(ExcludeList $excludeList = null, bool $includeGlobalVariables = true, bool $includeStaticAttributes = true, bool $includeConstants = true, bool $includeFunctions = true, bool $includeClasses = true, bool $includeInterfaces = true, bool $includeTraits = true, bool $includeIniSettings = true, bool $includeIncludedFiles = true)
+ {
+ $this->excludeList = $excludeList ?: new ExcludeList;
+
+ if ($includeConstants) {
+ $this->snapshotConstants();
+ }
+
+ if ($includeFunctions) {
+ $this->snapshotFunctions();
+ }
+
+ if ($includeClasses || $includeStaticAttributes) {
+ $this->snapshotClasses();
+ }
+
+ if ($includeInterfaces) {
+ $this->snapshotInterfaces();
+ }
+
+ if ($includeGlobalVariables) {
+ $this->setupSuperGlobalArrays();
+ $this->snapshotGlobals();
+ }
+
+ if ($includeStaticAttributes) {
+ $this->snapshotStaticAttributes();
+ }
+
+ if ($includeIniSettings) {
+ $this->iniSettings = ini_get_all(null, false);
+ }
+
+ if ($includeIncludedFiles) {
+ $this->includedFiles = get_included_files();
+ }
+
+ if ($includeTraits) {
+ $this->traits = get_declared_traits();
+ }
+ }
+
+ public function excludeList(): ExcludeList
+ {
+ return $this->excludeList;
+ }
+
+ public function globalVariables(): array
+ {
+ return $this->globalVariables;
+ }
+
+ public function superGlobalVariables(): array
+ {
+ return $this->superGlobalVariables;
+ }
+
+ public function superGlobalArrays(): array
+ {
+ return $this->superGlobalArrays;
+ }
+
+ public function staticAttributes(): array
+ {
+ return $this->staticAttributes;
+ }
+
+ public function iniSettings(): array
+ {
+ return $this->iniSettings;
+ }
+
+ public function includedFiles(): array
+ {
+ return $this->includedFiles;
+ }
+
+ public function constants(): array
+ {
+ return $this->constants;
+ }
+
+ public function functions(): array
+ {
+ return $this->functions;
+ }
+
+ public function interfaces(): array
+ {
+ return $this->interfaces;
+ }
+
+ public function classes(): array
+ {
+ return $this->classes;
+ }
+
+ public function traits(): array
+ {
+ return $this->traits;
+ }
+
+ /**
+ * Creates a snapshot user-defined constants.
+ */
+ private function snapshotConstants(): void
+ {
+ $constants = get_defined_constants(true);
+
+ if (isset($constants['user'])) {
+ $this->constants = $constants['user'];
+ }
+ }
+
+ /**
+ * Creates a snapshot user-defined functions.
+ */
+ private function snapshotFunctions(): void
+ {
+ $functions = get_defined_functions();
+
+ $this->functions = $functions['user'];
+ }
+
+ /**
+ * Creates a snapshot user-defined classes.
+ */
+ private function snapshotClasses(): void
+ {
+ foreach (array_reverse(get_declared_classes()) as $className) {
+ $class = new ReflectionClass($className);
+
+ if (!$class->isUserDefined()) {
+ break;
+ }
+
+ $this->classes[] = $className;
+ }
+
+ $this->classes = array_reverse($this->classes);
+ }
+
+ /**
+ * Creates a snapshot user-defined interfaces.
+ */
+ private function snapshotInterfaces(): void
+ {
+ foreach (array_reverse(get_declared_interfaces()) as $interfaceName) {
+ $class = new ReflectionClass($interfaceName);
+
+ if (!$class->isUserDefined()) {
+ break;
+ }
+
+ $this->interfaces[] = $interfaceName;
+ }
+
+ $this->interfaces = array_reverse($this->interfaces);
+ }
+
+ /**
+ * Creates a snapshot of all global and super-global variables.
+ */
+ private function snapshotGlobals(): void
+ {
+ $superGlobalArrays = $this->superGlobalArrays();
+
+ foreach ($superGlobalArrays as $superGlobalArray) {
+ $this->snapshotSuperGlobalArray($superGlobalArray);
+ }
+
+ foreach (array_keys($GLOBALS) as $key) {
+ if ($key !== 'GLOBALS' &&
+ !in_array($key, $superGlobalArrays, true) &&
+ $this->canBeSerialized($GLOBALS[$key]) &&
+ !$this->excludeList->isGlobalVariableExcluded($key)) {
+ /* @noinspection UnserializeExploitsInspection */
+ $this->globalVariables[$key] = unserialize(serialize($GLOBALS[$key]));
+ }
+ }
+ }
+
+ /**
+ * Creates a snapshot a super-global variable array.
+ */
+ private function snapshotSuperGlobalArray(string $superGlobalArray): void
+ {
+ $this->superGlobalVariables[$superGlobalArray] = [];
+
+ if (isset($GLOBALS[$superGlobalArray]) && is_array($GLOBALS[$superGlobalArray])) {
+ foreach ($GLOBALS[$superGlobalArray] as $key => $value) {
+ /* @noinspection UnserializeExploitsInspection */
+ $this->superGlobalVariables[$superGlobalArray][$key] = unserialize(serialize($value));
+ }
+ }
+ }
+
+ /**
+ * Creates a snapshot of all static attributes in user-defined classes.
+ */
+ private function snapshotStaticAttributes(): void
+ {
+ foreach ($this->classes as $className) {
+ $class = new ReflectionClass($className);
+ $snapshot = [];
+
+ foreach ($class->getProperties() as $attribute) {
+ if ($attribute->isStatic()) {
+ $name = $attribute->getName();
+
+ if ($this->excludeList->isStaticAttributeExcluded($className, $name)) {
+ continue;
+ }
+
+ $attribute->setAccessible(true);
+
+ if (PHP_VERSION_ID >= 70400 && !$attribute->isInitialized()) {
+ continue;
+ }
+
+ $value = $attribute->getValue();
+
+ if ($this->canBeSerialized($value)) {
+ /* @noinspection UnserializeExploitsInspection */
+ $snapshot[$name] = unserialize(serialize($value));
+ }
+ }
+ }
+
+ if (!empty($snapshot)) {
+ $this->staticAttributes[$className] = $snapshot;
+ }
+ }
+ }
+
+ /**
+ * Returns a list of all super-global variable arrays.
+ */
+ private function setupSuperGlobalArrays(): void
+ {
+ $this->superGlobalArrays = [
+ '_ENV',
+ '_POST',
+ '_GET',
+ '_COOKIE',
+ '_SERVER',
+ '_FILES',
+ '_REQUEST',
+ ];
+ }
+
+ private function canBeSerialized($variable): bool
+ {
+ if (is_scalar($variable) || $variable === null) {
+ return true;
+ }
+
+ if (is_resource($variable)) {
+ return false;
+ }
+
+ foreach ($this->enumerateObjectsAndResources($variable) as $value) {
+ if (is_resource($value)) {
+ return false;
+ }
+
+ if (is_object($value)) {
+ $class = new ReflectionClass($value);
+
+ if ($class->isAnonymous()) {
+ return false;
+ }
+
+ try {
+ @serialize($value);
+ } catch (Throwable $t) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private function enumerateObjectsAndResources($variable): array
+ {
+ if (isset(func_get_args()[1])) {
+ $processed = func_get_args()[1];
+ } else {
+ $processed = new Context;
+ }
+
+ $result = [];
+
+ if ($processed->contains($variable)) {
+ return $result;
+ }
+
+ $array = $variable;
+ $processed->add($variable);
+
+ if (is_array($variable)) {
+ foreach ($array as $element) {
+ if (!is_array($element) && !is_object($element) && !is_resource($element)) {
+ continue;
+ }
+
+ if (!is_resource($element)) {
+ /** @noinspection SlowArrayOperationsInLoopInspection */
+ $result = array_merge(
+ $result,
+ $this->enumerateObjectsAndResources($element, $processed)
+ );
+ } else {
+ $result[] = $element;
+ }
+ }
+ } else {
+ $result[] = $variable;
+
+ foreach ((new ObjectReflector)->getAttributes($variable) as $value) {
+ if (!is_array($value) && !is_object($value) && !is_resource($value)) {
+ continue;
+ }
+
+ if (!is_resource($value)) {
+ /** @noinspection SlowArrayOperationsInLoopInspection */
+ $result = array_merge(
+ $result,
+ $this->enumerateObjectsAndResources($value, $processed)
+ );
+ } else {
+ $result[] = $value;
+ }
+ }
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/sebastian/global-state/src/exceptions/Exception.php b/vendor/sebastian/global-state/src/exceptions/Exception.php
new file mode 100644
index 000000000..94432008e
--- /dev/null
+++ b/vendor/sebastian/global-state/src/exceptions/Exception.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/global-state.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\GlobalState;
+
+use Throwable;
+
+interface Exception extends Throwable
+{
+}
diff --git a/vendor/sebastian/global-state/src/exceptions/RuntimeException.php b/vendor/sebastian/global-state/src/exceptions/RuntimeException.php
new file mode 100644
index 000000000..79f02a114
--- /dev/null
+++ b/vendor/sebastian/global-state/src/exceptions/RuntimeException.php
@@ -0,0 +1,14 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/global-state.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\GlobalState;
+
+final class RuntimeException extends \RuntimeException implements Exception
+{
+}
diff --git a/vendor/sebastian/lines-of-code/.psalm/baseline.xml b/vendor/sebastian/lines-of-code/.psalm/baseline.xml
new file mode 100644
index 000000000..77e688e07
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/.psalm/baseline.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44"/>
diff --git a/vendor/sebastian/lines-of-code/.psalm/config.xml b/vendor/sebastian/lines-of-code/.psalm/config.xml
new file mode 100644
index 000000000..15abef058
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/.psalm/config.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<psalm
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="https://getpsalm.org/schema/config"
+ xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
+ resolveFromConfigFile="false"
+ totallyTyped="true"
+ errorBaseline=".psalm/baseline.xml"
+>
+ <projectFiles>
+ <directory name="src" />
+ <ignoreFiles>
+ <directory name="vendor" />
+ </ignoreFiles>
+ </projectFiles>
+</psalm>
diff --git a/vendor/sebastian/lines-of-code/ChangeLog.md b/vendor/sebastian/lines-of-code/ChangeLog.md
new file mode 100644
index 000000000..39bcaad49
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/ChangeLog.md
@@ -0,0 +1,34 @@
+# ChangeLog
+
+All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
+
+## [1.0.3] - 2020-11-28
+
+### Fixed
+
+* Files that do not contain a newline were not handled correctly
+
+### Changed
+
+* A line of code is no longer considered to be a Logical Line of Code if it does not contain an `Expr` node
+
+## [1.0.2] - 2020-10-26
+
+### Fixed
+
+* `SebastianBergmann\LinesOfCode\Exception` now correctly extends `\Throwable`
+
+## [1.0.1] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [1.0.0] - 2020-07-22
+
+* Initial release
+
+[1.0.3]: https://github.com/sebastianbergmann/lines-of-code/compare/1.0.2...1.0.3
+[1.0.2]: https://github.com/sebastianbergmann/lines-of-code/compare/1.0.1...1.0.2
+[1.0.1]: https://github.com/sebastianbergmann/lines-of-code/compare/1.0.0...1.0.1
+[1.0.0]: https://github.com/sebastianbergmann/lines-of-code/compare/f959e71f00e591288acc024afe9cb966c6cf9bd6...1.0.0
diff --git a/vendor/sebastian/lines-of-code/LICENSE b/vendor/sebastian/lines-of-code/LICENSE
new file mode 100644
index 000000000..d170181fa
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/LICENSE
@@ -0,0 +1,33 @@
+sebastian/lines-of-code
+
+Copyright (c) 2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/lines-of-code/README.md b/vendor/sebastian/lines-of-code/README.md
new file mode 100644
index 000000000..9457ef5a7
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/README.md
@@ -0,0 +1,22 @@
+# sebastian/lines-of-code
+
+Library for counting the lines of code in PHP source code.
+
+[![Latest Stable Version](https://img.shields.io/packagist/v/sebastian/lines-of-code.svg?style=flat-square)](https://packagist.org/packages/sebastian/lines-of-code)
+[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.3-8892BF.svg?style=flat-square)](https://php.net/)
+[![CI Status](https://github.com/sebastianbergmann/lines-of-code/workflows/CI/badge.svg?branch=master&event=push)](https://phpunit.de/build-status.html)
+[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/lines-of-code/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/lines-of-code)
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/lines-of-code
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/lines-of-code
+```
diff --git a/vendor/sebastian/lines-of-code/composer.json b/vendor/sebastian/lines-of-code/composer.json
new file mode 100644
index 000000000..95bb9e363
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/composer.json
@@ -0,0 +1,42 @@
+{
+ "name": "sebastian/lines-of-code",
+ "description": "Library for counting the lines of code in PHP source code",
+ "type": "library",
+ "homepage": "https://github.com/sebastianbergmann/lines-of-code",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/lines-of-code/issues"
+ },
+ "prefer-stable": true,
+ "require": {
+ "php": ">=7.3",
+ "nikic/php-parser": "^4.6"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/lines-of-code/src/Counter.php b/vendor/sebastian/lines-of-code/src/Counter.php
new file mode 100644
index 000000000..cfe5e20a7
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/Counter.php
@@ -0,0 +1,91 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+use function substr_count;
+use PhpParser\Error;
+use PhpParser\Lexer;
+use PhpParser\Node;
+use PhpParser\NodeTraverser;
+use PhpParser\Parser;
+use PhpParser\ParserFactory;
+
+final class Counter
+{
+ /**
+ * @throws RuntimeException
+ */
+ public function countInSourceFile(string $sourceFile): LinesOfCode
+ {
+ return $this->countInSourceString(file_get_contents($sourceFile));
+ }
+
+ /**
+ * @throws RuntimeException
+ */
+ public function countInSourceString(string $source): LinesOfCode
+ {
+ $linesOfCode = substr_count($source, "\n");
+
+ if ($linesOfCode === 0 && !empty($source)) {
+ $linesOfCode = 1;
+ }
+
+ try {
+ $nodes = $this->parser()->parse($source);
+
+ assert($nodes !== null);
+
+ return $this->countInAbstractSyntaxTree($linesOfCode, $nodes);
+
+ // @codeCoverageIgnoreStart
+ } catch (Error $error) {
+ throw new RuntimeException(
+ $error->getMessage(),
+ (int) $error->getCode(),
+ $error
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @param Node[] $nodes
+ *
+ * @throws RuntimeException
+ */
+ public function countInAbstractSyntaxTree(int $linesOfCode, array $nodes): LinesOfCode
+ {
+ $traverser = new NodeTraverser;
+ $visitor = new LineCountingVisitor($linesOfCode);
+
+ $traverser->addVisitor($visitor);
+
+ try {
+ /* @noinspection UnusedFunctionResultInspection */
+ $traverser->traverse($nodes);
+ // @codeCoverageIgnoreStart
+ } catch (Error $error) {
+ throw new RuntimeException(
+ $error->getMessage(),
+ (int) $error->getCode(),
+ $error
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ return $visitor->result();
+ }
+
+ private function parser(): Parser
+ {
+ return (new ParserFactory)->create(ParserFactory::PREFER_PHP7, new Lexer);
+ }
+}
diff --git a/vendor/sebastian/lines-of-code/src/Exception/Exception.php b/vendor/sebastian/lines-of-code/src/Exception/Exception.php
new file mode 100644
index 000000000..11d543aa7
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/Exception/Exception.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+use Throwable;
+
+interface Exception extends Throwable
+{
+}
diff --git a/vendor/sebastian/lines-of-code/src/Exception/IllogicalValuesException.php b/vendor/sebastian/lines-of-code/src/Exception/IllogicalValuesException.php
new file mode 100644
index 000000000..46a5c1b1f
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/Exception/IllogicalValuesException.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+use LogicException;
+
+final class IllogicalValuesException extends LogicException implements Exception
+{
+}
diff --git a/vendor/sebastian/lines-of-code/src/Exception/NegativeValueException.php b/vendor/sebastian/lines-of-code/src/Exception/NegativeValueException.php
new file mode 100644
index 000000000..40d27e1f0
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/Exception/NegativeValueException.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+use InvalidArgumentException;
+
+final class NegativeValueException extends InvalidArgumentException implements Exception
+{
+}
diff --git a/vendor/sebastian/lines-of-code/src/Exception/RuntimeException.php b/vendor/sebastian/lines-of-code/src/Exception/RuntimeException.php
new file mode 100644
index 000000000..4e6d66d0d
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/Exception/RuntimeException.php
@@ -0,0 +1,14 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+final class RuntimeException extends \RuntimeException implements Exception
+{
+}
diff --git a/vendor/sebastian/lines-of-code/src/LineCountingVisitor.php b/vendor/sebastian/lines-of-code/src/LineCountingVisitor.php
new file mode 100644
index 000000000..ff433b2fc
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/LineCountingVisitor.php
@@ -0,0 +1,82 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+use function array_merge;
+use function array_unique;
+use function count;
+use PhpParser\Comment;
+use PhpParser\Node;
+use PhpParser\Node\Expr;
+use PhpParser\NodeVisitorAbstract;
+
+final class LineCountingVisitor extends NodeVisitorAbstract
+{
+ /**
+ * @var int
+ */
+ private $linesOfCode;
+
+ /**
+ * @var Comment[]
+ */
+ private $comments = [];
+
+ /**
+ * @var int[]
+ */
+ private $linesWithStatements = [];
+
+ public function __construct(int $linesOfCode)
+ {
+ $this->linesOfCode = $linesOfCode;
+ }
+
+ public function enterNode(Node $node): void
+ {
+ $this->comments = array_merge($this->comments, $node->getComments());
+
+ if (!$node instanceof Expr) {
+ return;
+ }
+
+ $this->linesWithStatements[] = $node->getStartLine();
+ }
+
+ public function result(): LinesOfCode
+ {
+ $commentLinesOfCode = 0;
+
+ foreach ($this->comments() as $comment) {
+ $commentLinesOfCode += ($comment->getEndLine() - $comment->getStartLine() + 1);
+ }
+
+ return new LinesOfCode(
+ $this->linesOfCode,
+ $commentLinesOfCode,
+ $this->linesOfCode - $commentLinesOfCode,
+ count(array_unique($this->linesWithStatements))
+ );
+ }
+
+ /**
+ * @return Comment[]
+ */
+ private function comments(): array
+ {
+ $comments = [];
+
+ foreach ($this->comments as $comment) {
+ $comments[$comment->getStartLine() . '_' . $comment->getStartTokenPos() . '_' . $comment->getEndLine() . '_' . $comment->getEndTokenPos()] = $comment;
+ }
+
+ return $comments;
+ }
+}
diff --git a/vendor/sebastian/lines-of-code/src/LinesOfCode.php b/vendor/sebastian/lines-of-code/src/LinesOfCode.php
new file mode 100644
index 000000000..41829981a
--- /dev/null
+++ b/vendor/sebastian/lines-of-code/src/LinesOfCode.php
@@ -0,0 +1,98 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/lines-of-code.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\LinesOfCode;
+
+/**
+ * @psalm-immutable
+ */
+final class LinesOfCode
+{
+ /**
+ * @var int
+ */
+ private $linesOfCode;
+
+ /**
+ * @var int
+ */
+ private $commentLinesOfCode;
+
+ /**
+ * @var int
+ */
+ private $nonCommentLinesOfCode;
+
+ /**
+ * @var int
+ */
+ private $logicalLinesOfCode;
+
+ /**
+ * @throws IllogicalValuesException
+ * @throws NegativeValueException
+ */
+ public function __construct(int $linesOfCode, int $commentLinesOfCode, int $nonCommentLinesOfCode, int $logicalLinesOfCode)
+ {
+ if ($linesOfCode < 0) {
+ throw new NegativeValueException('$linesOfCode must not be negative');
+ }
+
+ if ($commentLinesOfCode < 0) {
+ throw new NegativeValueException('$commentLinesOfCode must not be negative');
+ }
+
+ if ($nonCommentLinesOfCode < 0) {
+ throw new NegativeValueException('$nonCommentLinesOfCode must not be negative');
+ }
+
+ if ($logicalLinesOfCode < 0) {
+ throw new NegativeValueException('$logicalLinesOfCode must not be negative');
+ }
+
+ if ($linesOfCode - $commentLinesOfCode !== $nonCommentLinesOfCode) {
+ throw new IllogicalValuesException('$linesOfCode !== $commentLinesOfCode + $nonCommentLinesOfCode');
+ }
+
+ $this->linesOfCode = $linesOfCode;
+ $this->commentLinesOfCode = $commentLinesOfCode;
+ $this->nonCommentLinesOfCode = $nonCommentLinesOfCode;
+ $this->logicalLinesOfCode = $logicalLinesOfCode;
+ }
+
+ public function linesOfCode(): int
+ {
+ return $this->linesOfCode;
+ }
+
+ public function commentLinesOfCode(): int
+ {
+ return $this->commentLinesOfCode;
+ }
+
+ public function nonCommentLinesOfCode(): int
+ {
+ return $this->nonCommentLinesOfCode;
+ }
+
+ public function logicalLinesOfCode(): int
+ {
+ return $this->logicalLinesOfCode;
+ }
+
+ public function plus(self $other): self
+ {
+ return new self(
+ $this->linesOfCode() + $other->linesOfCode(),
+ $this->commentLinesOfCode() + $other->commentLinesOfCode(),
+ $this->nonCommentLinesOfCode() + $other->nonCommentLinesOfCode(),
+ $this->logicalLinesOfCode() + $other->logicalLinesOfCode(),
+ );
+ }
+}
diff --git a/vendor/sebastian/object-enumerator/.psalm/baseline.xml b/vendor/sebastian/object-enumerator/.psalm/baseline.xml
new file mode 100644
index 000000000..180b3f803
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/.psalm/baseline.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44">
+ <file src="src/Enumerator.php">
+ <DocblockTypeContradiction occurrences="2">
+ <code>!is_array($variable) &amp;&amp; !is_object($variable)</code>
+ <code>is_object($variable)</code>
+ </DocblockTypeContradiction>
+ </file>
+</files>
diff --git a/vendor/sebastian/object-enumerator/.psalm/config.xml b/vendor/sebastian/object-enumerator/.psalm/config.xml
new file mode 100644
index 000000000..2a4b16f22
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/.psalm/config.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<psalm
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="https://getpsalm.org/schema/config"
+ xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
+ resolveFromConfigFile="false"
+ totallyTyped="false"
+ errorBaseline=".psalm/baseline.xml"
+>
+ <projectFiles>
+ <directory name="src" />
+ <ignoreFiles>
+ <directory name="vendor" />
+ </ignoreFiles>
+ </projectFiles>
+</psalm>
diff --git a/vendor/sebastian/object-enumerator/ChangeLog.md b/vendor/sebastian/object-enumerator/ChangeLog.md
new file mode 100644
index 000000000..886554189
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/ChangeLog.md
@@ -0,0 +1,88 @@
+# Change Log
+
+All notable changes to `sebastianbergmann/object-enumerator` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [4.0.4] - 2020-10-26
+
+### Fixed
+
+* `SebastianBergmann\ObjectEnumerator\Exception` now correctly extends `\Throwable`
+
+## [4.0.3] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [4.0.2] - 2020-06-26
+
+### Added
+
+* This component is now supported on PHP 8
+
+## [4.0.1] - 2020-06-15
+
+### Changed
+
+* Tests etc. are now ignored for archive exports
+
+## [4.0.0] - 2020-02-07
+
+### Removed
+
+* This component is no longer supported on PHP 7.0, PHP 7.1, and PHP 7.2
+
+## [3.0.3] - 2017-08-03
+
+### Changed
+
+* Bumped required version of `sebastian/object-reflector`
+
+## [3.0.2] - 2017-03-12
+
+### Changed
+
+* `sebastian/object-reflector` is now a dependency
+
+## [3.0.1] - 2017-03-12
+
+### Fixed
+
+* Objects aggregated in inherited attributes are not enumerated
+
+## [3.0.0] - 2017-03-03
+
+### Removed
+
+* This component is no longer supported on PHP 5.6
+
+## [2.0.1] - 2017-02-18
+
+### Fixed
+
+* Fixed [#2](https://github.com/sebastianbergmann/phpunit/pull/2): Exceptions in `ReflectionProperty::getValue()` are not handled
+
+## [2.0.0] - 2016-11-19
+
+### Changed
+
+* This component is now compatible with `sebastian/recursion-context: ~1.0.4`
+
+## 1.0.0 - 2016-02-04
+
+### Added
+
+* Initial release
+
+[4.0.4]: https://github.com/sebastianbergmann/object-enumerator/compare/4.0.3...4.0.4
+[4.0.3]: https://github.com/sebastianbergmann/object-enumerator/compare/4.0.2...4.0.3
+[4.0.2]: https://github.com/sebastianbergmann/object-enumerator/compare/4.0.1...4.0.2
+[4.0.1]: https://github.com/sebastianbergmann/object-enumerator/compare/4.0.0...4.0.1
+[4.0.0]: https://github.com/sebastianbergmann/object-enumerator/compare/3.0.3...4.0.0
+[3.0.3]: https://github.com/sebastianbergmann/object-enumerator/compare/3.0.2...3.0.3
+[3.0.2]: https://github.com/sebastianbergmann/object-enumerator/compare/3.0.1...3.0.2
+[3.0.1]: https://github.com/sebastianbergmann/object-enumerator/compare/3.0.0...3.0.1
+[3.0.0]: https://github.com/sebastianbergmann/object-enumerator/compare/2.0...3.0.0
+[2.0.1]: https://github.com/sebastianbergmann/object-enumerator/compare/2.0.0...2.0.1
+[2.0.0]: https://github.com/sebastianbergmann/object-enumerator/compare/1.0...2.0.0
+
diff --git a/vendor/sebastian/object-enumerator/LICENSE b/vendor/sebastian/object-enumerator/LICENSE
new file mode 100644
index 000000000..1389ad396
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/LICENSE
@@ -0,0 +1,33 @@
+Object Enumerator
+
+Copyright (c) 2016-2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/object-enumerator/README.md b/vendor/sebastian/object-enumerator/README.md
new file mode 100644
index 000000000..afca0177b
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/README.md
@@ -0,0 +1,20 @@
+# sebastian/object-enumerator
+
+[![CI Status](https://github.com/sebastianbergmann/object-enumerator/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/object-enumerator/actions)
+[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/object-enumerator/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/object-enumerator)
+
+Traverses array structures and object graphs to enumerate all referenced objects.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/object-enumerator
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/object-enumerator
+```
diff --git a/vendor/sebastian/object-enumerator/composer.json b/vendor/sebastian/object-enumerator/composer.json
new file mode 100644
index 000000000..d68a21330
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/composer.json
@@ -0,0 +1,43 @@
+{
+ "name": "sebastian/object-enumerator",
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]"
+ }
+ ],
+ "prefer-stable": true,
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/object-reflector": "^2.0",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "autoload-dev": {
+ "classmap": [
+ "tests/_fixture/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/object-enumerator/phpunit.xml b/vendor/sebastian/object-enumerator/phpunit.xml
new file mode 100644
index 000000000..7be976b13
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/phpunit.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
+ bootstrap="vendor/autoload.php"
+ executionOrder="depends,defects"
+ forceCoversAnnotation="true"
+ beStrictAboutCoversAnnotation="true"
+ beStrictAboutOutputDuringTests="true"
+ beStrictAboutTodoAnnotatedTests="true"
+ failOnRisky="true"
+ failOnWarning="true"
+ verbose="true">
+ <testsuites>
+ <testsuite name="default">
+ <directory suffix="Test.php">tests</directory>
+ </testsuite>
+ </testsuites>
+
+ <coverage processUncoveredFiles="true">
+ <include>
+ <directory suffix=".php">src</directory>
+ </include>
+ </coverage>
+</phpunit>
diff --git a/vendor/sebastian/object-enumerator/src/Enumerator.php b/vendor/sebastian/object-enumerator/src/Enumerator.php
new file mode 100644
index 000000000..de75d17c5
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/src/Enumerator.php
@@ -0,0 +1,88 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/object-enumerator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\ObjectEnumerator;
+
+use function array_merge;
+use function func_get_args;
+use function is_array;
+use function is_object;
+use SebastianBergmann\ObjectReflector\ObjectReflector;
+use SebastianBergmann\RecursionContext\Context;
+
+/**
+ * Traverses array structures and object graphs
+ * to enumerate all referenced objects.
+ */
+class Enumerator
+{
+ /**
+ * Returns an array of all objects referenced either
+ * directly or indirectly by a variable.
+ *
+ * @param array|object $variable
+ *
+ * @return object[]
+ */
+ public function enumerate($variable)
+ {
+ if (!is_array($variable) && !is_object($variable)) {
+ throw new InvalidArgumentException;
+ }
+
+ if (isset(func_get_args()[1])) {
+ if (!func_get_args()[1] instanceof Context) {
+ throw new InvalidArgumentException;
+ }
+
+ $processed = func_get_args()[1];
+ } else {
+ $processed = new Context;
+ }
+
+ $objects = [];
+
+ if ($processed->contains($variable)) {
+ return $objects;
+ }
+
+ $array = $variable;
+ $processed->add($variable);
+
+ if (is_array($variable)) {
+ foreach ($array as $element) {
+ if (!is_array($element) && !is_object($element)) {
+ continue;
+ }
+
+ $objects = array_merge(
+ $objects,
+ $this->enumerate($element, $processed)
+ );
+ }
+ } else {
+ $objects[] = $variable;
+
+ $reflector = new ObjectReflector;
+
+ foreach ($reflector->getAttributes($variable) as $value) {
+ if (!is_array($value) && !is_object($value)) {
+ continue;
+ }
+
+ $objects = array_merge(
+ $objects,
+ $this->enumerate($value, $processed)
+ );
+ }
+ }
+
+ return $objects;
+ }
+}
diff --git a/vendor/sebastian/object-enumerator/src/Exception.php b/vendor/sebastian/object-enumerator/src/Exception.php
new file mode 100644
index 000000000..2f09d70aa
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/src/Exception.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/object-enumerator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\ObjectEnumerator;
+
+use Throwable;
+
+interface Exception extends Throwable
+{
+}
diff --git a/vendor/sebastian/object-enumerator/src/InvalidArgumentException.php b/vendor/sebastian/object-enumerator/src/InvalidArgumentException.php
new file mode 100644
index 000000000..ce2037cdb
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/src/InvalidArgumentException.php
@@ -0,0 +1,14 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/object-enumerator.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\ObjectEnumerator;
+
+class InvalidArgumentException extends \InvalidArgumentException implements Exception
+{
+}
diff --git a/vendor/sebastian/object-reflector/.psalm/baseline.xml b/vendor/sebastian/object-reflector/.psalm/baseline.xml
new file mode 100644
index 000000000..965c12757
--- /dev/null
+++ b/vendor/sebastian/object-reflector/.psalm/baseline.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44">
+ <file src="src/ObjectReflector.php">
+ <DocblockTypeContradiction occurrences="1">
+ <code>is_object($object)</code>
+ </DocblockTypeContradiction>
+ </file>
+</files>
diff --git a/vendor/sebastian/object-reflector/.psalm/config.xml b/vendor/sebastian/object-reflector/.psalm/config.xml
new file mode 100644
index 000000000..2a4b16f22
--- /dev/null
+++ b/vendor/sebastian/object-reflector/.psalm/config.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<psalm
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="https://getpsalm.org/schema/config"
+ xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
+ resolveFromConfigFile="false"
+ totallyTyped="false"
+ errorBaseline=".psalm/baseline.xml"
+>
+ <projectFiles>
+ <directory name="src" />
+ <ignoreFiles>
+ <directory name="vendor" />
+ </ignoreFiles>
+ </projectFiles>
+</psalm>
diff --git a/vendor/sebastian/object-reflector/ChangeLog.md b/vendor/sebastian/object-reflector/ChangeLog.md
new file mode 100644
index 000000000..7fa62e90f
--- /dev/null
+++ b/vendor/sebastian/object-reflector/ChangeLog.md
@@ -0,0 +1,55 @@
+# Change Log
+
+All notable changes to `sebastianbergmann/object-reflector` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [2.0.4] - 2020-10-26
+
+### Fixed
+
+* `SebastianBergmann\ObjectReflector\Exception` now correctly extends `\Throwable`
+
+## [2.0.3] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [2.0.2] - 2020-06-26
+
+### Added
+
+* This component is now supported on PHP 8
+
+## [2.0.1] - 2020-06-15
+
+### Changed
+
+* Tests etc. are now ignored for archive exports
+
+## [2.0.0] - 2020-02-07
+
+### Removed
+
+* This component is no longer supported on PHP 7.0, PHP 7.1, and PHP 7.2
+
+## [1.1.1] - 2017-03-29
+
+* Fixed [#1](https://github.com/sebastianbergmann/object-reflector/issues/1): Attributes with non-string names are not handled correctly
+
+## [1.1.0] - 2017-03-16
+
+### Changed
+
+* Changed implementation of `ObjectReflector::getattributes()` to use `(array)` cast instead of `ReflectionObject`
+
+## 1.0.0 - 2017-03-12
+
+* Initial release
+
+[2.0.4]: https://github.com/sebastianbergmann/object-reflector/compare/2.0.3...2.0.4
+[2.0.3]: https://github.com/sebastianbergmann/object-reflector/compare/2.0.2...2.0.3
+[2.0.2]: https://github.com/sebastianbergmann/object-reflector/compare/2.0.1...2.0.2
+[2.0.1]: https://github.com/sebastianbergmann/object-reflector/compare/2.0.0...2.0.1
+[2.0.0]: https://github.com/sebastianbergmann/object-reflector/compare/1.1.1...2.0.0
+[1.1.1]: https://github.com/sebastianbergmann/object-reflector/compare/1.1.0...1.1.1
+[1.1.0]: https://github.com/sebastianbergmann/object-reflector/compare/1.0.0...1.1.0
diff --git a/vendor/sebastian/object-reflector/LICENSE b/vendor/sebastian/object-reflector/LICENSE
new file mode 100644
index 000000000..a80c16192
--- /dev/null
+++ b/vendor/sebastian/object-reflector/LICENSE
@@ -0,0 +1,33 @@
+Object Reflector
+
+Copyright (c) 2017-2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/object-reflector/README.md b/vendor/sebastian/object-reflector/README.md
new file mode 100644
index 000000000..b7d5ae95f
--- /dev/null
+++ b/vendor/sebastian/object-reflector/README.md
@@ -0,0 +1,20 @@
+# sebastian/object-reflector
+
+[![CI Status](https://github.com/sebastianbergmann/object-reflector/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/object-reflector/actions)
+[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/object-reflector/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/object-reflector)
+
+Allows reflection of object attributes, including inherited and non-public ones.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/object-reflector
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/object-reflector
+```
diff --git a/vendor/sebastian/object-reflector/composer.json b/vendor/sebastian/object-reflector/composer.json
new file mode 100644
index 000000000..36a337885
--- /dev/null
+++ b/vendor/sebastian/object-reflector/composer.json
@@ -0,0 +1,41 @@
+{
+ "name": "sebastian/object-reflector",
+ "description": "Allows reflection of object attributes, including inherited and non-public ones",
+ "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]"
+ }
+ ],
+ "prefer-stable": true,
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "autoload-dev": {
+ "classmap": [
+ "tests/_fixture/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/object-reflector/src/Exception.php b/vendor/sebastian/object-reflector/src/Exception.php
new file mode 100644
index 000000000..36f8efeca
--- /dev/null
+++ b/vendor/sebastian/object-reflector/src/Exception.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/object-reflector.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\ObjectReflector;
+
+use Throwable;
+
+interface Exception extends Throwable
+{
+}
diff --git a/vendor/sebastian/object-reflector/src/InvalidArgumentException.php b/vendor/sebastian/object-reflector/src/InvalidArgumentException.php
new file mode 100644
index 000000000..34b4cca19
--- /dev/null
+++ b/vendor/sebastian/object-reflector/src/InvalidArgumentException.php
@@ -0,0 +1,14 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/object-reflector.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\ObjectReflector;
+
+class InvalidArgumentException extends \InvalidArgumentException implements Exception
+{
+}
diff --git a/vendor/sebastian/object-reflector/src/ObjectReflector.php b/vendor/sebastian/object-reflector/src/ObjectReflector.php
new file mode 100644
index 000000000..4abb5f55f
--- /dev/null
+++ b/vendor/sebastian/object-reflector/src/ObjectReflector.php
@@ -0,0 +1,51 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/object-reflector.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\ObjectReflector;
+
+use function count;
+use function explode;
+use function get_class;
+use function is_object;
+
+class ObjectReflector
+{
+ /**
+ * @param object $object
+ *
+ * @throws InvalidArgumentException
+ */
+ public function getAttributes($object): array
+ {
+ if (!is_object($object)) {
+ throw new InvalidArgumentException;
+ }
+
+ $attributes = [];
+ $className = get_class($object);
+
+ foreach ((array) $object as $name => $value) {
+ $name = explode("\0", (string) $name);
+
+ if (count($name) === 1) {
+ $name = $name[0];
+ } else {
+ if ($name[1] !== $className) {
+ $name = $name[1] . '::' . $name[2];
+ } else {
+ $name = $name[2];
+ }
+ }
+
+ $attributes[$name] = $value;
+ }
+
+ return $attributes;
+ }
+}
diff --git a/vendor/sebastian/recursion-context/.psalm/baseline.xml b/vendor/sebastian/recursion-context/.psalm/baseline.xml
new file mode 100644
index 000000000..b946db1a5
--- /dev/null
+++ b/vendor/sebastian/recursion-context/.psalm/baseline.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44">
+ <file src="src/Context.php">
+ <RedundantConditionGivenDocblockType occurrences="1">
+ <code>is_array($array)</code>
+ </RedundantConditionGivenDocblockType>
+ </file>
+</files>
diff --git a/vendor/sebastian/recursion-context/.psalm/config.xml b/vendor/sebastian/recursion-context/.psalm/config.xml
new file mode 100644
index 000000000..2a4b16f22
--- /dev/null
+++ b/vendor/sebastian/recursion-context/.psalm/config.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<psalm
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="https://getpsalm.org/schema/config"
+ xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
+ resolveFromConfigFile="false"
+ totallyTyped="false"
+ errorBaseline=".psalm/baseline.xml"
+>
+ <projectFiles>
+ <directory name="src" />
+ <ignoreFiles>
+ <directory name="vendor" />
+ </ignoreFiles>
+ </projectFiles>
+</psalm>
diff --git a/vendor/sebastian/recursion-context/ChangeLog.md b/vendor/sebastian/recursion-context/ChangeLog.md
new file mode 100644
index 000000000..2fbacc2c3
--- /dev/null
+++ b/vendor/sebastian/recursion-context/ChangeLog.md
@@ -0,0 +1,33 @@
+# ChangeLog
+
+All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
+
+## [4.0.4] - 2020-10-26
+
+### Fixed
+
+* `SebastianBergmann\RecursionContext\Exception` now correctly extends `\Throwable`
+
+## [4.0.3] - 2020-09-28
+
+### Changed
+
+* [#21](https://github.com/sebastianbergmann/recursion-context/pull/21): Add type annotations for in/out parameters
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [4.0.2] - 2020-06-26
+
+### Added
+
+* This component is now supported on PHP 8
+
+## [4.0.1] - 2020-06-15
+
+### Changed
+
+* Tests etc. are now ignored for archive exports
+
+[4.0.4]: https://github.com/sebastianbergmann/recursion-context/compare/4.0.3...4.0.4
+[4.0.3]: https://github.com/sebastianbergmann/recursion-context/compare/4.0.2...4.0.3
+[4.0.2]: https://github.com/sebastianbergmann/recursion-context/compare/4.0.1...4.0.2
+[4.0.1]: https://github.com/sebastianbergmann/recursion-context/compare/4.0.0...4.0.1
diff --git a/vendor/sebastian/recursion-context/LICENSE b/vendor/sebastian/recursion-context/LICENSE
new file mode 100644
index 000000000..0faffbbb2
--- /dev/null
+++ b/vendor/sebastian/recursion-context/LICENSE
@@ -0,0 +1,33 @@
+Recursion Context
+
+Copyright (c) 2002-2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/recursion-context/README.md b/vendor/sebastian/recursion-context/README.md
new file mode 100644
index 000000000..8e4d2a084
--- /dev/null
+++ b/vendor/sebastian/recursion-context/README.md
@@ -0,0 +1,18 @@
+# sebastian/recursion-context
+
+[![CI Status](https://github.com/sebastianbergmann/recursion-context/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/recursion-context/actions)
+[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/recursion-context/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/recursion-context)
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/recursion-context
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/recursion-context
+```
diff --git a/vendor/sebastian/recursion-context/composer.json b/vendor/sebastian/recursion-context/composer.json
new file mode 100644
index 000000000..8a5408232
--- /dev/null
+++ b/vendor/sebastian/recursion-context/composer.json
@@ -0,0 +1,44 @@
+{
+ "name": "sebastian/recursion-context",
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "[email protected]"
+ }
+ ],
+ "prefer-stable": true,
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/recursion-context/src/Context.php b/vendor/sebastian/recursion-context/src/Context.php
new file mode 100644
index 000000000..87fe7b04f
--- /dev/null
+++ b/vendor/sebastian/recursion-context/src/Context.php
@@ -0,0 +1,186 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of the Recursion Context package.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\RecursionContext;
+
+use const PHP_INT_MAX;
+use const PHP_INT_MIN;
+use function array_pop;
+use function array_slice;
+use function count;
+use function is_array;
+use function is_object;
+use function random_int;
+use function spl_object_hash;
+use SplObjectStorage;
+
+/**
+ * A context containing previously processed arrays and objects
+ * when recursively processing a value.
+ */
+final class Context
+{
+ /**
+ * @var array[]
+ */
+ private $arrays;
+
+ /**
+ * @var SplObjectStorage
+ */
+ private $objects;
+
+ /**
+ * Initialises the context.
+ */
+ public function __construct()
+ {
+ $this->arrays = [];
+ $this->objects = new SplObjectStorage;
+ }
+
+ /**
+ * @codeCoverageIgnore
+ */
+ public function __destruct()
+ {
+ foreach ($this->arrays as &$array) {
+ if (is_array($array)) {
+ array_pop($array);
+ array_pop($array);
+ }
+ }
+ }
+
+ /**
+ * Adds a value to the context.
+ *
+ * @param array|object $value the value to add
+ *
+ * @throws InvalidArgumentException Thrown if $value is not an array or object
+ *
+ * @return bool|int|string the ID of the stored value, either as a string or integer
+ *
+ * @psalm-template T
+ * @psalm-param T $value
+ * @param-out T $value
+ */
+ public function add(&$value)
+ {
+ if (is_array($value)) {
+ return $this->addArray($value);
+ }
+
+ if (is_object($value)) {
+ return $this->addObject($value);
+ }
+
+ throw new InvalidArgumentException(
+ 'Only arrays and objects are supported'
+ );
+ }
+
+ /**
+ * Checks if the given value exists within the context.
+ *
+ * @param array|object $value the value to check
+ *
+ * @throws InvalidArgumentException Thrown if $value is not an array or object
+ *
+ * @return false|int|string the string or integer ID of the stored value if it has already been seen, or false if the value is not stored
+ *
+ * @psalm-template T
+ * @psalm-param T $value
+ * @param-out T $value
+ */
+ public function contains(&$value)
+ {
+ if (is_array($value)) {
+ return $this->containsArray($value);
+ }
+
+ if (is_object($value)) {
+ return $this->containsObject($value);
+ }
+
+ throw new InvalidArgumentException(
+ 'Only arrays and objects are supported'
+ );
+ }
+
+ /**
+ * @return bool|int
+ */
+ private function addArray(array &$array)
+ {
+ $key = $this->containsArray($array);
+
+ if ($key !== false) {
+ return $key;
+ }
+
+ $key = count($this->arrays);
+ $this->arrays[] = &$array;
+
+ if (!isset($array[PHP_INT_MAX]) && !isset($array[PHP_INT_MAX - 1])) {
+ $array[] = $key;
+ $array[] = $this->objects;
+ } else { /* cover the improbable case too */
+ do {
+ $key = random_int(PHP_INT_MIN, PHP_INT_MAX);
+ } while (isset($array[$key]));
+
+ $array[$key] = $key;
+
+ do {
+ $key = random_int(PHP_INT_MIN, PHP_INT_MAX);
+ } while (isset($array[$key]));
+
+ $array[$key] = $this->objects;
+ }
+
+ return $key;
+ }
+
+ /**
+ * @param object $object
+ */
+ private function addObject($object): string
+ {
+ if (!$this->objects->contains($object)) {
+ $this->objects->attach($object);
+ }
+
+ return spl_object_hash($object);
+ }
+
+ /**
+ * @return false|int
+ */
+ private function containsArray(array &$array)
+ {
+ $end = array_slice($array, -2);
+
+ return isset($end[1]) && $end[1] === $this->objects ? $end[0] : false;
+ }
+
+ /**
+ * @param object $value
+ *
+ * @return false|string
+ */
+ private function containsObject($value)
+ {
+ if ($this->objects->contains($value)) {
+ return spl_object_hash($value);
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/sebastian/recursion-context/src/Exception.php b/vendor/sebastian/recursion-context/src/Exception.php
new file mode 100644
index 000000000..e3a9c017d
--- /dev/null
+++ b/vendor/sebastian/recursion-context/src/Exception.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of the Recursion Context package.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\RecursionContext;
+
+use Throwable;
+
+interface Exception extends Throwable
+{
+}
diff --git a/vendor/sebastian/recursion-context/src/InvalidArgumentException.php b/vendor/sebastian/recursion-context/src/InvalidArgumentException.php
new file mode 100644
index 000000000..627c8bdf4
--- /dev/null
+++ b/vendor/sebastian/recursion-context/src/InvalidArgumentException.php
@@ -0,0 +1,14 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of the Recursion Context package.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\RecursionContext;
+
+final class InvalidArgumentException extends \InvalidArgumentException implements Exception
+{
+}
diff --git a/vendor/sebastian/resource-operations/.gitattributes b/vendor/sebastian/resource-operations/.gitattributes
new file mode 100644
index 000000000..85e55ebca
--- /dev/null
+++ b/vendor/sebastian/resource-operations/.gitattributes
@@ -0,0 +1,7 @@
+/.github export-ignore
+/.php_cs.dist export-ignore
+/build.xml export-ignore
+/phpunit.xml export-ignore
+/tests export-ignore
+
+*.php diff=php
diff --git a/vendor/sebastian/resource-operations/.gitignore b/vendor/sebastian/resource-operations/.gitignore
new file mode 100644
index 000000000..a086c7819
--- /dev/null
+++ b/vendor/sebastian/resource-operations/.gitignore
@@ -0,0 +1,6 @@
+/.idea
+/.php_cs.cache
+/build/FunctionSignatureMap.php
+/composer.lock
+/vendor
+/.phpunit.result.cache
diff --git a/vendor/sebastian/resource-operations/ChangeLog.md b/vendor/sebastian/resource-operations/ChangeLog.md
new file mode 100644
index 000000000..e6dc73922
--- /dev/null
+++ b/vendor/sebastian/resource-operations/ChangeLog.md
@@ -0,0 +1,54 @@
+# ChangeLog
+
+All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
+
+## [3.0.3] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [3.0.2] - 2020-06-26
+
+### Added
+
+* This component is now supported on PHP 8
+
+## [3.0.1] - 2020-06-15
+
+### Changed
+
+* Tests etc. are now ignored for archive exports
+
+## [3.0.0] - 2020-02-07
+
+### Removed
+
+* This component is no longer supported on PHP 7.1 and PHP 7.2
+
+## [2.0.1] - 2018-10-04
+
+### Fixed
+
+* Functions and methods with nullable parameters of type `resource` are now also considered
+
+## [2.0.0] - 2018-09-27
+
+### Changed
+
+* [FunctionSignatureMap.php](https://raw.githubusercontent.com/phan/phan/master/src/Phan/Language/Internal/FunctionSignatureMap.php) from `phan/phan` is now used instead of [arginfo.php](https://raw.githubusercontent.com/rlerdorf/phan/master/includes/arginfo.php) from `rlerdorf/phan`
+
+### Removed
+
+* This component is no longer supported on PHP 5.6 and PHP 7.0
+
+## 1.0.0 - 2015-07-28
+
+* Initial release
+
+[3.0.3]: https://github.com/sebastianbergmann/comparator/resource-operations/3.0.2...3.0.3
+[3.0.2]: https://github.com/sebastianbergmann/comparator/resource-operations/3.0.1...3.0.2
+[3.0.1]: https://github.com/sebastianbergmann/comparator/resource-operations/3.0.0...3.0.1
+[3.0.0]: https://github.com/sebastianbergmann/comparator/resource-operations/2.0.1...3.0.0
+[2.0.1]: https://github.com/sebastianbergmann/comparator/resource-operations/2.0.0...2.0.1
+[2.0.0]: https://github.com/sebastianbergmann/comparator/resource-operations/1.0.0...2.0.0
diff --git a/vendor/sebastian/resource-operations/LICENSE b/vendor/sebastian/resource-operations/LICENSE
new file mode 100644
index 000000000..dccd6b074
--- /dev/null
+++ b/vendor/sebastian/resource-operations/LICENSE
@@ -0,0 +1,33 @@
+Resource Operations
+
+Copyright (c) 2015-2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/resource-operations/README.md b/vendor/sebastian/resource-operations/README.md
new file mode 100644
index 000000000..88b05ccb6
--- /dev/null
+++ b/vendor/sebastian/resource-operations/README.md
@@ -0,0 +1,14 @@
+# Resource Operations
+
+Provides a list of PHP built-in functions that operate on resources.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+ composer require sebastian/resource-operations
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+ composer require --dev sebastian/resource-operations
+
diff --git a/vendor/sebastian/resource-operations/build/generate.php b/vendor/sebastian/resource-operations/build/generate.php
new file mode 100644
index 000000000..0354dc45f
--- /dev/null
+++ b/vendor/sebastian/resource-operations/build/generate.php
@@ -0,0 +1,65 @@
+#!/usr/bin/env php
+<?php declare(strict_types=1);
+/*
+ * This file is part of resource-operations.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+$functions = require __DIR__ . '/FunctionSignatureMap.php';
+$resourceFunctions = [];
+
+foreach ($functions as $function => $arguments) {
+ foreach ($arguments as $argument) {
+ if (strpos($argument, '?') === 0) {
+ $argument = substr($argument, 1);
+ }
+
+ if ($argument === 'resource') {
+ $resourceFunctions[] = explode('\'', $function)[0];
+ }
+ }
+}
+
+$resourceFunctions = array_unique($resourceFunctions);
+sort($resourceFunctions);
+
+$buffer = <<<EOT
+<?php declare(strict_types=1);
+/*
+ * This file is part of resource-operations.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\ResourceOperations;
+
+final class ResourceOperations
+{
+ /**
+ * @return string[]
+ */
+ public static function getFunctions(): array
+ {
+ return [
+
+EOT;
+
+foreach ($resourceFunctions as $function) {
+ $buffer .= sprintf(" '%s',\n", $function);
+}
+
+$buffer .= <<< EOT
+ ];
+ }
+}
+
+EOT;
+
+file_put_contents(__DIR__ . '/../src/ResourceOperations.php', $buffer);
+
diff --git a/vendor/sebastian/resource-operations/composer.json b/vendor/sebastian/resource-operations/composer.json
new file mode 100644
index 000000000..870be3c12
--- /dev/null
+++ b/vendor/sebastian/resource-operations/composer.json
@@ -0,0 +1,37 @@
+{
+ "name": "sebastian/resource-operations",
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]"
+ }
+ ],
+ "prefer-stable": true,
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.0"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ }
+}
+
diff --git a/vendor/sebastian/resource-operations/src/ResourceOperations.php b/vendor/sebastian/resource-operations/src/ResourceOperations.php
new file mode 100644
index 000000000..f3911f36c
--- /dev/null
+++ b/vendor/sebastian/resource-operations/src/ResourceOperations.php
@@ -0,0 +1,2232 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of resource-operations.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\ResourceOperations;
+
+final class ResourceOperations
+{
+ /**
+ * @return string[]
+ */
+ public static function getFunctions(): array
+ {
+ return [
+ 'Directory::close',
+ 'Directory::read',
+ 'Directory::rewind',
+ 'DirectoryIterator::openFile',
+ 'FilesystemIterator::openFile',
+ 'Gmagick::readimagefile',
+ 'HttpResponse::getRequestBodyStream',
+ 'HttpResponse::getStream',
+ 'HttpResponse::setStream',
+ 'Imagick::pingImageFile',
+ 'Imagick::readImageFile',
+ 'Imagick::writeImageFile',
+ 'Imagick::writeImagesFile',
+ 'MongoGridFSCursor::__construct',
+ 'MongoGridFSFile::getResource',
+ 'MysqlndUhConnection::stmtInit',
+ 'MysqlndUhConnection::storeResult',
+ 'MysqlndUhConnection::useResult',
+ 'PDF_activate_item',
+ 'PDF_add_launchlink',
+ 'PDF_add_locallink',
+ 'PDF_add_nameddest',
+ 'PDF_add_note',
+ 'PDF_add_pdflink',
+ 'PDF_add_table_cell',
+ 'PDF_add_textflow',
+ 'PDF_add_thumbnail',
+ 'PDF_add_weblink',
+ 'PDF_arc',
+ 'PDF_arcn',
+ 'PDF_attach_file',
+ 'PDF_begin_document',
+ 'PDF_begin_font',
+ 'PDF_begin_glyph',
+ 'PDF_begin_item',
+ 'PDF_begin_layer',
+ 'PDF_begin_page',
+ 'PDF_begin_page_ext',
+ 'PDF_begin_pattern',
+ 'PDF_begin_template',
+ 'PDF_begin_template_ext',
+ 'PDF_circle',
+ 'PDF_clip',
+ 'PDF_close',
+ 'PDF_close_image',
+ 'PDF_close_pdi',
+ 'PDF_close_pdi_page',
+ 'PDF_closepath',
+ 'PDF_closepath_fill_stroke',
+ 'PDF_closepath_stroke',
+ 'PDF_concat',
+ 'PDF_continue_text',
+ 'PDF_create_3dview',
+ 'PDF_create_action',
+ 'PDF_create_annotation',
+ 'PDF_create_bookmark',
+ 'PDF_create_field',
+ 'PDF_create_fieldgroup',
+ 'PDF_create_gstate',
+ 'PDF_create_pvf',
+ 'PDF_create_textflow',
+ 'PDF_curveto',
+ 'PDF_define_layer',
+ 'PDF_delete',
+ 'PDF_delete_pvf',
+ 'PDF_delete_table',
+ 'PDF_delete_textflow',
+ 'PDF_encoding_set_char',
+ 'PDF_end_document',
+ 'PDF_end_font',
+ 'PDF_end_glyph',
+ 'PDF_end_item',
+ 'PDF_end_layer',
+ 'PDF_end_page',
+ 'PDF_end_page_ext',
+ 'PDF_end_pattern',
+ 'PDF_end_template',
+ 'PDF_endpath',
+ 'PDF_fill',
+ 'PDF_fill_imageblock',
+ 'PDF_fill_pdfblock',
+ 'PDF_fill_stroke',
+ 'PDF_fill_textblock',
+ 'PDF_findfont',
+ 'PDF_fit_image',
+ 'PDF_fit_pdi_page',
+ 'PDF_fit_table',
+ 'PDF_fit_textflow',
+ 'PDF_fit_textline',
+ 'PDF_get_apiname',
+ 'PDF_get_buffer',
+ 'PDF_get_errmsg',
+ 'PDF_get_errnum',
+ 'PDF_get_parameter',
+ 'PDF_get_pdi_parameter',
+ 'PDF_get_pdi_value',
+ 'PDF_get_value',
+ 'PDF_info_font',
+ 'PDF_info_matchbox',
+ 'PDF_info_table',
+ 'PDF_info_textflow',
+ 'PDF_info_textline',
+ 'PDF_initgraphics',
+ 'PDF_lineto',
+ 'PDF_load_3ddata',
+ 'PDF_load_font',
+ 'PDF_load_iccprofile',
+ 'PDF_load_image',
+ 'PDF_makespotcolor',
+ 'PDF_moveto',
+ 'PDF_new',
+ 'PDF_open_ccitt',
+ 'PDF_open_file',
+ 'PDF_open_image',
+ 'PDF_open_image_file',
+ 'PDF_open_memory_image',
+ 'PDF_open_pdi',
+ 'PDF_open_pdi_document',
+ 'PDF_open_pdi_page',
+ 'PDF_pcos_get_number',
+ 'PDF_pcos_get_stream',
+ 'PDF_pcos_get_string',
+ 'PDF_place_image',
+ 'PDF_place_pdi_page',
+ 'PDF_process_pdi',
+ 'PDF_rect',
+ 'PDF_restore',
+ 'PDF_resume_page',
+ 'PDF_rotate',
+ 'PDF_save',
+ 'PDF_scale',
+ 'PDF_set_border_color',
+ 'PDF_set_border_dash',
+ 'PDF_set_border_style',
+ 'PDF_set_gstate',
+ 'PDF_set_info',
+ 'PDF_set_layer_dependency',
+ 'PDF_set_parameter',
+ 'PDF_set_text_pos',
+ 'PDF_set_value',
+ 'PDF_setcolor',
+ 'PDF_setdash',
+ 'PDF_setdashpattern',
+ 'PDF_setflat',
+ 'PDF_setfont',
+ 'PDF_setgray',
+ 'PDF_setgray_fill',
+ 'PDF_setgray_stroke',
+ 'PDF_setlinecap',
+ 'PDF_setlinejoin',
+ 'PDF_setlinewidth',
+ 'PDF_setmatrix',
+ 'PDF_setmiterlimit',
+ 'PDF_setrgbcolor',
+ 'PDF_setrgbcolor_fill',
+ 'PDF_setrgbcolor_stroke',
+ 'PDF_shading',
+ 'PDF_shading_pattern',
+ 'PDF_shfill',
+ 'PDF_show',
+ 'PDF_show_boxed',
+ 'PDF_show_xy',
+ 'PDF_skew',
+ 'PDF_stringwidth',
+ 'PDF_stroke',
+ 'PDF_suspend_page',
+ 'PDF_translate',
+ 'PDF_utf16_to_utf8',
+ 'PDF_utf32_to_utf16',
+ 'PDF_utf8_to_utf16',
+ 'PDO::pgsqlLOBOpen',
+ 'RarEntry::getStream',
+ 'SQLite3::openBlob',
+ 'SWFMovie::saveToFile',
+ 'SplFileInfo::openFile',
+ 'SplFileObject::openFile',
+ 'SplTempFileObject::openFile',
+ 'V8Js::compileString',
+ 'V8Js::executeScript',
+ 'Vtiful\Kernel\Excel::setColumn',
+ 'Vtiful\Kernel\Excel::setRow',
+ 'Vtiful\Kernel\Format::align',
+ 'Vtiful\Kernel\Format::bold',
+ 'Vtiful\Kernel\Format::italic',
+ 'Vtiful\Kernel\Format::underline',
+ 'XMLWriter::openMemory',
+ 'XMLWriter::openURI',
+ 'ZipArchive::getStream',
+ 'Zookeeper::setLogStream',
+ 'apc_bin_dumpfile',
+ 'apc_bin_loadfile',
+ 'bbcode_add_element',
+ 'bbcode_add_smiley',
+ 'bbcode_create',
+ 'bbcode_destroy',
+ 'bbcode_parse',
+ 'bbcode_set_arg_parser',
+ 'bbcode_set_flags',
+ 'bcompiler_read',
+ 'bcompiler_write_class',
+ 'bcompiler_write_constant',
+ 'bcompiler_write_exe_footer',
+ 'bcompiler_write_file',
+ 'bcompiler_write_footer',
+ 'bcompiler_write_function',
+ 'bcompiler_write_functions_from_file',
+ 'bcompiler_write_header',
+ 'bcompiler_write_included_filename',
+ 'bzclose',
+ 'bzerrno',
+ 'bzerror',
+ 'bzerrstr',
+ 'bzflush',
+ 'bzopen',
+ 'bzread',
+ 'bzwrite',
+ 'cairo_surface_write_to_png',
+ 'closedir',
+ 'copy',
+ 'crack_closedict',
+ 'crack_opendict',
+ 'cubrid_bind',
+ 'cubrid_close_prepare',
+ 'cubrid_close_request',
+ 'cubrid_col_get',
+ 'cubrid_col_size',
+ 'cubrid_column_names',
+ 'cubrid_column_types',
+ 'cubrid_commit',
+ 'cubrid_connect',
+ 'cubrid_connect_with_url',
+ 'cubrid_current_oid',
+ 'cubrid_db_parameter',
+ 'cubrid_disconnect',
+ 'cubrid_drop',
+ 'cubrid_fetch',
+ 'cubrid_free_result',
+ 'cubrid_get',
+ 'cubrid_get_autocommit',
+ 'cubrid_get_charset',
+ 'cubrid_get_class_name',
+ 'cubrid_get_db_parameter',
+ 'cubrid_get_query_timeout',
+ 'cubrid_get_server_info',
+ 'cubrid_insert_id',
+ 'cubrid_is_instance',
+ 'cubrid_lob2_bind',
+ 'cubrid_lob2_close',
+ 'cubrid_lob2_export',
+ 'cubrid_lob2_import',
+ 'cubrid_lob2_new',
+ 'cubrid_lob2_read',
+ 'cubrid_lob2_seek',
+ 'cubrid_lob2_seek64',
+ 'cubrid_lob2_size',
+ 'cubrid_lob2_size64',
+ 'cubrid_lob2_tell',
+ 'cubrid_lob2_tell64',
+ 'cubrid_lob2_write',
+ 'cubrid_lob_export',
+ 'cubrid_lob_get',
+ 'cubrid_lob_send',
+ 'cubrid_lob_size',
+ 'cubrid_lock_read',
+ 'cubrid_lock_write',
+ 'cubrid_move_cursor',
+ 'cubrid_next_result',
+ 'cubrid_num_cols',
+ 'cubrid_num_rows',
+ 'cubrid_pconnect',
+ 'cubrid_pconnect_with_url',
+ 'cubrid_prepare',
+ 'cubrid_put',
+ 'cubrid_query',
+ 'cubrid_rollback',
+ 'cubrid_schema',
+ 'cubrid_seq_add',
+ 'cubrid_seq_drop',
+ 'cubrid_seq_insert',
+ 'cubrid_seq_put',
+ 'cubrid_set_add',
+ 'cubrid_set_autocommit',
+ 'cubrid_set_db_parameter',
+ 'cubrid_set_drop',
+ 'cubrid_set_query_timeout',
+ 'cubrid_unbuffered_query',
+ 'curl_close',
+ 'curl_copy_handle',
+ 'curl_errno',
+ 'curl_error',
+ 'curl_escape',
+ 'curl_exec',
+ 'curl_getinfo',
+ 'curl_multi_add_handle',
+ 'curl_multi_close',
+ 'curl_multi_errno',
+ 'curl_multi_exec',
+ 'curl_multi_getcontent',
+ 'curl_multi_info_read',
+ 'curl_multi_remove_handle',
+ 'curl_multi_select',
+ 'curl_multi_setopt',
+ 'curl_pause',
+ 'curl_reset',
+ 'curl_setopt',
+ 'curl_setopt_array',
+ 'curl_share_close',
+ 'curl_share_errno',
+ 'curl_share_init',
+ 'curl_share_setopt',
+ 'curl_unescape',
+ 'cyrus_authenticate',
+ 'cyrus_bind',
+ 'cyrus_close',
+ 'cyrus_connect',
+ 'cyrus_query',
+ 'cyrus_unbind',
+ 'db2_autocommit',
+ 'db2_bind_param',
+ 'db2_client_info',
+ 'db2_close',
+ 'db2_column_privileges',
+ 'db2_columns',
+ 'db2_commit',
+ 'db2_conn_error',
+ 'db2_conn_errormsg',
+ 'db2_connect',
+ 'db2_cursor_type',
+ 'db2_exec',
+ 'db2_execute',
+ 'db2_fetch_array',
+ 'db2_fetch_assoc',
+ 'db2_fetch_both',
+ 'db2_fetch_object',
+ 'db2_fetch_row',
+ 'db2_field_display_size',
+ 'db2_field_name',
+ 'db2_field_num',
+ 'db2_field_precision',
+ 'db2_field_scale',
+ 'db2_field_type',
+ 'db2_field_width',
+ 'db2_foreign_keys',
+ 'db2_free_result',
+ 'db2_free_stmt',
+ 'db2_get_option',
+ 'db2_last_insert_id',
+ 'db2_lob_read',
+ 'db2_next_result',
+ 'db2_num_fields',
+ 'db2_num_rows',
+ 'db2_pclose',
+ 'db2_pconnect',
+ 'db2_prepare',
+ 'db2_primary_keys',
+ 'db2_procedure_columns',
+ 'db2_procedures',
+ 'db2_result',
+ 'db2_rollback',
+ 'db2_server_info',
+ 'db2_set_option',
+ 'db2_special_columns',
+ 'db2_statistics',
+ 'db2_stmt_error',
+ 'db2_stmt_errormsg',
+ 'db2_table_privileges',
+ 'db2_tables',
+ 'dba_close',
+ 'dba_delete',
+ 'dba_exists',
+ 'dba_fetch',
+ 'dba_firstkey',
+ 'dba_insert',
+ 'dba_nextkey',
+ 'dba_open',
+ 'dba_optimize',
+ 'dba_popen',
+ 'dba_replace',
+ 'dba_sync',
+ 'dbplus_add',
+ 'dbplus_aql',
+ 'dbplus_close',
+ 'dbplus_curr',
+ 'dbplus_find',
+ 'dbplus_first',
+ 'dbplus_flush',
+ 'dbplus_freelock',
+ 'dbplus_freerlocks',
+ 'dbplus_getlock',
+ 'dbplus_getunique',
+ 'dbplus_info',
+ 'dbplus_last',
+ 'dbplus_lockrel',
+ 'dbplus_next',
+ 'dbplus_open',
+ 'dbplus_prev',
+ 'dbplus_rchperm',
+ 'dbplus_rcreate',
+ 'dbplus_rcrtexact',
+ 'dbplus_rcrtlike',
+ 'dbplus_restorepos',
+ 'dbplus_rkeys',
+ 'dbplus_ropen',
+ 'dbplus_rquery',
+ 'dbplus_rrename',
+ 'dbplus_rsecindex',
+ 'dbplus_runlink',
+ 'dbplus_rzap',
+ 'dbplus_savepos',
+ 'dbplus_setindex',
+ 'dbplus_setindexbynumber',
+ 'dbplus_sql',
+ 'dbplus_tremove',
+ 'dbplus_undo',
+ 'dbplus_undoprepare',
+ 'dbplus_unlockrel',
+ 'dbplus_unselect',
+ 'dbplus_update',
+ 'dbplus_xlockrel',
+ 'dbplus_xunlockrel',
+ 'deflate_add',
+ 'dio_close',
+ 'dio_fcntl',
+ 'dio_open',
+ 'dio_read',
+ 'dio_seek',
+ 'dio_stat',
+ 'dio_tcsetattr',
+ 'dio_truncate',
+ 'dio_write',
+ 'dir',
+ 'eio_busy',
+ 'eio_cancel',
+ 'eio_chmod',
+ 'eio_chown',
+ 'eio_close',
+ 'eio_custom',
+ 'eio_dup2',
+ 'eio_fallocate',
+ 'eio_fchmod',
+ 'eio_fchown',
+ 'eio_fdatasync',
+ 'eio_fstat',
+ 'eio_fstatvfs',
+ 'eio_fsync',
+ 'eio_ftruncate',
+ 'eio_futime',
+ 'eio_get_last_error',
+ 'eio_grp',
+ 'eio_grp_add',
+ 'eio_grp_cancel',
+ 'eio_grp_limit',
+ 'eio_link',
+ 'eio_lstat',
+ 'eio_mkdir',
+ 'eio_mknod',
+ 'eio_nop',
+ 'eio_open',
+ 'eio_read',
+ 'eio_readahead',
+ 'eio_readdir',
+ 'eio_readlink',
+ 'eio_realpath',
+ 'eio_rename',
+ 'eio_rmdir',
+ 'eio_seek',
+ 'eio_sendfile',
+ 'eio_stat',
+ 'eio_statvfs',
+ 'eio_symlink',
+ 'eio_sync',
+ 'eio_sync_file_range',
+ 'eio_syncfs',
+ 'eio_truncate',
+ 'eio_unlink',
+ 'eio_utime',
+ 'eio_write',
+ 'enchant_broker_describe',
+ 'enchant_broker_dict_exists',
+ 'enchant_broker_free',
+ 'enchant_broker_free_dict',
+ 'enchant_broker_get_dict_path',
+ 'enchant_broker_get_error',
+ 'enchant_broker_init',
+ 'enchant_broker_list_dicts',
+ 'enchant_broker_request_dict',
+ 'enchant_broker_request_pwl_dict',
+ 'enchant_broker_set_dict_path',
+ 'enchant_broker_set_ordering',
+ 'enchant_dict_add_to_personal',
+ 'enchant_dict_add_to_session',
+ 'enchant_dict_check',
+ 'enchant_dict_describe',
+ 'enchant_dict_get_error',
+ 'enchant_dict_is_in_session',
+ 'enchant_dict_quick_check',
+ 'enchant_dict_store_replacement',
+ 'enchant_dict_suggest',
+ 'event_add',
+ 'event_base_free',
+ 'event_base_loop',
+ 'event_base_loopbreak',
+ 'event_base_loopexit',
+ 'event_base_new',
+ 'event_base_priority_init',
+ 'event_base_reinit',
+ 'event_base_set',
+ 'event_buffer_base_set',
+ 'event_buffer_disable',
+ 'event_buffer_enable',
+ 'event_buffer_fd_set',
+ 'event_buffer_free',
+ 'event_buffer_new',
+ 'event_buffer_priority_set',
+ 'event_buffer_read',
+ 'event_buffer_set_callback',
+ 'event_buffer_timeout_set',
+ 'event_buffer_watermark_set',
+ 'event_buffer_write',
+ 'event_del',
+ 'event_free',
+ 'event_new',
+ 'event_priority_set',
+ 'event_set',
+ 'event_timer_add',
+ 'event_timer_del',
+ 'event_timer_pending',
+ 'event_timer_set',
+ 'expect_expectl',
+ 'expect_popen',
+ 'fam_cancel_monitor',
+ 'fam_close',
+ 'fam_monitor_collection',
+ 'fam_monitor_directory',
+ 'fam_monitor_file',
+ 'fam_next_event',
+ 'fam_open',
+ 'fam_pending',
+ 'fam_resume_monitor',
+ 'fam_suspend_monitor',
+ 'fann_cascadetrain_on_data',
+ 'fann_cascadetrain_on_file',
+ 'fann_clear_scaling_params',
+ 'fann_copy',
+ 'fann_create_from_file',
+ 'fann_create_shortcut_array',
+ 'fann_create_standard',
+ 'fann_create_standard_array',
+ 'fann_create_train',
+ 'fann_create_train_from_callback',
+ 'fann_descale_input',
+ 'fann_descale_output',
+ 'fann_descale_train',
+ 'fann_destroy',
+ 'fann_destroy_train',
+ 'fann_duplicate_train_data',
+ 'fann_get_MSE',
+ 'fann_get_activation_function',
+ 'fann_get_activation_steepness',
+ 'fann_get_bias_array',
+ 'fann_get_bit_fail',
+ 'fann_get_bit_fail_limit',
+ 'fann_get_cascade_activation_functions',
+ 'fann_get_cascade_activation_functions_count',
+ 'fann_get_cascade_activation_steepnesses',
+ 'fann_get_cascade_activation_steepnesses_count',
+ 'fann_get_cascade_candidate_change_fraction',
+ 'fann_get_cascade_candidate_limit',
+ 'fann_get_cascade_candidate_stagnation_epochs',
+ 'fann_get_cascade_max_cand_epochs',
+ 'fann_get_cascade_max_out_epochs',
+ 'fann_get_cascade_min_cand_epochs',
+ 'fann_get_cascade_min_out_epochs',
+ 'fann_get_cascade_num_candidate_groups',
+ 'fann_get_cascade_num_candidates',
+ 'fann_get_cascade_output_change_fraction',
+ 'fann_get_cascade_output_stagnation_epochs',
+ 'fann_get_cascade_weight_multiplier',
+ 'fann_get_connection_array',
+ 'fann_get_connection_rate',
+ 'fann_get_errno',
+ 'fann_get_errstr',
+ 'fann_get_layer_array',
+ 'fann_get_learning_momentum',
+ 'fann_get_learning_rate',
+ 'fann_get_network_type',
+ 'fann_get_num_input',
+ 'fann_get_num_layers',
+ 'fann_get_num_output',
+ 'fann_get_quickprop_decay',
+ 'fann_get_quickprop_mu',
+ 'fann_get_rprop_decrease_factor',
+ 'fann_get_rprop_delta_max',
+ 'fann_get_rprop_delta_min',
+ 'fann_get_rprop_delta_zero',
+ 'fann_get_rprop_increase_factor',
+ 'fann_get_sarprop_step_error_shift',
+ 'fann_get_sarprop_step_error_threshold_factor',
+ 'fann_get_sarprop_temperature',
+ 'fann_get_sarprop_weight_decay_shift',
+ 'fann_get_total_connections',
+ 'fann_get_total_neurons',
+ 'fann_get_train_error_function',
+ 'fann_get_train_stop_function',
+ 'fann_get_training_algorithm',
+ 'fann_init_weights',
+ 'fann_length_train_data',
+ 'fann_merge_train_data',
+ 'fann_num_input_train_data',
+ 'fann_num_output_train_data',
+ 'fann_randomize_weights',
+ 'fann_read_train_from_file',
+ 'fann_reset_errno',
+ 'fann_reset_errstr',
+ 'fann_run',
+ 'fann_save',
+ 'fann_save_train',
+ 'fann_scale_input',
+ 'fann_scale_input_train_data',
+ 'fann_scale_output',
+ 'fann_scale_output_train_data',
+ 'fann_scale_train',
+ 'fann_scale_train_data',
+ 'fann_set_activation_function',
+ 'fann_set_activation_function_hidden',
+ 'fann_set_activation_function_layer',
+ 'fann_set_activation_function_output',
+ 'fann_set_activation_steepness',
+ 'fann_set_activation_steepness_hidden',
+ 'fann_set_activation_steepness_layer',
+ 'fann_set_activation_steepness_output',
+ 'fann_set_bit_fail_limit',
+ 'fann_set_callback',
+ 'fann_set_cascade_activation_functions',
+ 'fann_set_cascade_activation_steepnesses',
+ 'fann_set_cascade_candidate_change_fraction',
+ 'fann_set_cascade_candidate_limit',
+ 'fann_set_cascade_candidate_stagnation_epochs',
+ 'fann_set_cascade_max_cand_epochs',
+ 'fann_set_cascade_max_out_epochs',
+ 'fann_set_cascade_min_cand_epochs',
+ 'fann_set_cascade_min_out_epochs',
+ 'fann_set_cascade_num_candidate_groups',
+ 'fann_set_cascade_output_change_fraction',
+ 'fann_set_cascade_output_stagnation_epochs',
+ 'fann_set_cascade_weight_multiplier',
+ 'fann_set_error_log',
+ 'fann_set_input_scaling_params',
+ 'fann_set_learning_momentum',
+ 'fann_set_learning_rate',
+ 'fann_set_output_scaling_params',
+ 'fann_set_quickprop_decay',
+ 'fann_set_quickprop_mu',
+ 'fann_set_rprop_decrease_factor',
+ 'fann_set_rprop_delta_max',
+ 'fann_set_rprop_delta_min',
+ 'fann_set_rprop_delta_zero',
+ 'fann_set_rprop_increase_factor',
+ 'fann_set_sarprop_step_error_shift',
+ 'fann_set_sarprop_step_error_threshold_factor',
+ 'fann_set_sarprop_temperature',
+ 'fann_set_sarprop_weight_decay_shift',
+ 'fann_set_scaling_params',
+ 'fann_set_train_error_function',
+ 'fann_set_train_stop_function',
+ 'fann_set_training_algorithm',
+ 'fann_set_weight',
+ 'fann_set_weight_array',
+ 'fann_shuffle_train_data',
+ 'fann_subset_train_data',
+ 'fann_test',
+ 'fann_test_data',
+ 'fann_train',
+ 'fann_train_epoch',
+ 'fann_train_on_data',
+ 'fann_train_on_file',
+ 'fbsql_affected_rows',
+ 'fbsql_autocommit',
+ 'fbsql_blob_size',
+ 'fbsql_change_user',
+ 'fbsql_clob_size',
+ 'fbsql_close',
+ 'fbsql_commit',
+ 'fbsql_connect',
+ 'fbsql_create_blob',
+ 'fbsql_create_clob',
+ 'fbsql_create_db',
+ 'fbsql_data_seek',
+ 'fbsql_database',
+ 'fbsql_database_password',
+ 'fbsql_db_query',
+ 'fbsql_db_status',
+ 'fbsql_drop_db',
+ 'fbsql_errno',
+ 'fbsql_error',
+ 'fbsql_fetch_array',
+ 'fbsql_fetch_assoc',
+ 'fbsql_fetch_field',
+ 'fbsql_fetch_lengths',
+ 'fbsql_fetch_object',
+ 'fbsql_fetch_row',
+ 'fbsql_field_flags',
+ 'fbsql_field_len',
+ 'fbsql_field_name',
+ 'fbsql_field_seek',
+ 'fbsql_field_table',
+ 'fbsql_field_type',
+ 'fbsql_free_result',
+ 'fbsql_get_autostart_info',
+ 'fbsql_hostname',
+ 'fbsql_insert_id',
+ 'fbsql_list_dbs',
+ 'fbsql_list_fields',
+ 'fbsql_list_tables',
+ 'fbsql_next_result',
+ 'fbsql_num_fields',
+ 'fbsql_num_rows',
+ 'fbsql_password',
+ 'fbsql_pconnect',
+ 'fbsql_query',
+ 'fbsql_read_blob',
+ 'fbsql_read_clob',
+ 'fbsql_result',
+ 'fbsql_rollback',
+ 'fbsql_rows_fetched',
+ 'fbsql_select_db',
+ 'fbsql_set_characterset',
+ 'fbsql_set_lob_mode',
+ 'fbsql_set_password',
+ 'fbsql_set_transaction',
+ 'fbsql_start_db',
+ 'fbsql_stop_db',
+ 'fbsql_table_name',
+ 'fbsql_username',
+ 'fclose',
+ 'fdf_add_doc_javascript',
+ 'fdf_add_template',
+ 'fdf_close',
+ 'fdf_create',
+ 'fdf_enum_values',
+ 'fdf_get_ap',
+ 'fdf_get_attachment',
+ 'fdf_get_encoding',
+ 'fdf_get_file',
+ 'fdf_get_flags',
+ 'fdf_get_opt',
+ 'fdf_get_status',
+ 'fdf_get_value',
+ 'fdf_get_version',
+ 'fdf_next_field_name',
+ 'fdf_open',
+ 'fdf_open_string',
+ 'fdf_remove_item',
+ 'fdf_save',
+ 'fdf_save_string',
+ 'fdf_set_ap',
+ 'fdf_set_encoding',
+ 'fdf_set_file',
+ 'fdf_set_flags',
+ 'fdf_set_javascript_action',
+ 'fdf_set_on_import_javascript',
+ 'fdf_set_opt',
+ 'fdf_set_status',
+ 'fdf_set_submit_form_action',
+ 'fdf_set_target_frame',
+ 'fdf_set_value',
+ 'fdf_set_version',
+ 'feof',
+ 'fflush',
+ 'ffmpeg_frame::__construct',
+ 'ffmpeg_frame::toGDImage',
+ 'fgetc',
+ 'fgetcsv',
+ 'fgets',
+ 'fgetss',
+ 'file',
+ 'file_get_contents',
+ 'file_put_contents',
+ 'finfo::buffer',
+ 'finfo::file',
+ 'finfo_buffer',
+ 'finfo_close',
+ 'finfo_file',
+ 'finfo_open',
+ 'finfo_set_flags',
+ 'flock',
+ 'fopen',
+ 'fpassthru',
+ 'fprintf',
+ 'fputcsv',
+ 'fputs',
+ 'fread',
+ 'fscanf',
+ 'fseek',
+ 'fstat',
+ 'ftell',
+ 'ftp_alloc',
+ 'ftp_append',
+ 'ftp_cdup',
+ 'ftp_chdir',
+ 'ftp_chmod',
+ 'ftp_close',
+ 'ftp_delete',
+ 'ftp_exec',
+ 'ftp_fget',
+ 'ftp_fput',
+ 'ftp_get',
+ 'ftp_get_option',
+ 'ftp_login',
+ 'ftp_mdtm',
+ 'ftp_mkdir',
+ 'ftp_mlsd',
+ 'ftp_nb_continue',
+ 'ftp_nb_fget',
+ 'ftp_nb_fput',
+ 'ftp_nb_get',
+ 'ftp_nb_put',
+ 'ftp_nlist',
+ 'ftp_pasv',
+ 'ftp_put',
+ 'ftp_pwd',
+ 'ftp_quit',
+ 'ftp_raw',
+ 'ftp_rawlist',
+ 'ftp_rename',
+ 'ftp_rmdir',
+ 'ftp_set_option',
+ 'ftp_site',
+ 'ftp_size',
+ 'ftp_systype',
+ 'ftruncate',
+ 'fwrite',
+ 'get_resource_type',
+ 'gmp_div',
+ 'gnupg::init',
+ 'gnupg_adddecryptkey',
+ 'gnupg_addencryptkey',
+ 'gnupg_addsignkey',
+ 'gnupg_cleardecryptkeys',
+ 'gnupg_clearencryptkeys',
+ 'gnupg_clearsignkeys',
+ 'gnupg_decrypt',
+ 'gnupg_decryptverify',
+ 'gnupg_encrypt',
+ 'gnupg_encryptsign',
+ 'gnupg_export',
+ 'gnupg_geterror',
+ 'gnupg_getprotocol',
+ 'gnupg_import',
+ 'gnupg_init',
+ 'gnupg_keyinfo',
+ 'gnupg_setarmor',
+ 'gnupg_seterrormode',
+ 'gnupg_setsignmode',
+ 'gnupg_sign',
+ 'gnupg_verify',
+ 'gupnp_context_get_host_ip',
+ 'gupnp_context_get_port',
+ 'gupnp_context_get_subscription_timeout',
+ 'gupnp_context_host_path',
+ 'gupnp_context_new',
+ 'gupnp_context_set_subscription_timeout',
+ 'gupnp_context_timeout_add',
+ 'gupnp_context_unhost_path',
+ 'gupnp_control_point_browse_start',
+ 'gupnp_control_point_browse_stop',
+ 'gupnp_control_point_callback_set',
+ 'gupnp_control_point_new',
+ 'gupnp_device_action_callback_set',
+ 'gupnp_device_info_get',
+ 'gupnp_device_info_get_service',
+ 'gupnp_root_device_get_available',
+ 'gupnp_root_device_get_relative_location',
+ 'gupnp_root_device_new',
+ 'gupnp_root_device_set_available',
+ 'gupnp_root_device_start',
+ 'gupnp_root_device_stop',
+ 'gupnp_service_action_get',
+ 'gupnp_service_action_return',
+ 'gupnp_service_action_return_error',
+ 'gupnp_service_action_set',
+ 'gupnp_service_freeze_notify',
+ 'gupnp_service_info_get',
+ 'gupnp_service_info_get_introspection',
+ 'gupnp_service_introspection_get_state_variable',
+ 'gupnp_service_notify',
+ 'gupnp_service_proxy_action_get',
+ 'gupnp_service_proxy_action_set',
+ 'gupnp_service_proxy_add_notify',
+ 'gupnp_service_proxy_callback_set',
+ 'gupnp_service_proxy_get_subscribed',
+ 'gupnp_service_proxy_remove_notify',
+ 'gupnp_service_proxy_send_action',
+ 'gupnp_service_proxy_set_subscribed',
+ 'gupnp_service_thaw_notify',
+ 'gzclose',
+ 'gzeof',
+ 'gzgetc',
+ 'gzgets',
+ 'gzgetss',
+ 'gzpassthru',
+ 'gzputs',
+ 'gzread',
+ 'gzrewind',
+ 'gzseek',
+ 'gztell',
+ 'gzwrite',
+ 'hash_update_stream',
+ 'http\Env\Response::send',
+ 'http_get_request_body_stream',
+ 'ibase_add_user',
+ 'ibase_affected_rows',
+ 'ibase_backup',
+ 'ibase_blob_add',
+ 'ibase_blob_cancel',
+ 'ibase_blob_close',
+ 'ibase_blob_create',
+ 'ibase_blob_get',
+ 'ibase_blob_open',
+ 'ibase_close',
+ 'ibase_commit',
+ 'ibase_commit_ret',
+ 'ibase_connect',
+ 'ibase_db_info',
+ 'ibase_delete_user',
+ 'ibase_drop_db',
+ 'ibase_execute',
+ 'ibase_fetch_assoc',
+ 'ibase_fetch_object',
+ 'ibase_fetch_row',
+ 'ibase_field_info',
+ 'ibase_free_event_handler',
+ 'ibase_free_query',
+ 'ibase_free_result',
+ 'ibase_gen_id',
+ 'ibase_maintain_db',
+ 'ibase_modify_user',
+ 'ibase_name_result',
+ 'ibase_num_fields',
+ 'ibase_num_params',
+ 'ibase_param_info',
+ 'ibase_pconnect',
+ 'ibase_prepare',
+ 'ibase_query',
+ 'ibase_restore',
+ 'ibase_rollback',
+ 'ibase_rollback_ret',
+ 'ibase_server_info',
+ 'ibase_service_attach',
+ 'ibase_service_detach',
+ 'ibase_set_event_handler',
+ 'ibase_trans',
+ 'ifx_affected_rows',
+ 'ifx_close',
+ 'ifx_connect',
+ 'ifx_do',
+ 'ifx_error',
+ 'ifx_fetch_row',
+ 'ifx_fieldproperties',
+ 'ifx_fieldtypes',
+ 'ifx_free_result',
+ 'ifx_getsqlca',
+ 'ifx_htmltbl_result',
+ 'ifx_num_fields',
+ 'ifx_num_rows',
+ 'ifx_pconnect',
+ 'ifx_prepare',
+ 'ifx_query',
+ 'image2wbmp',
+ 'imageaffine',
+ 'imagealphablending',
+ 'imageantialias',
+ 'imagearc',
+ 'imagebmp',
+ 'imagechar',
+ 'imagecharup',
+ 'imagecolorallocate',
+ 'imagecolorallocatealpha',
+ 'imagecolorat',
+ 'imagecolorclosest',
+ 'imagecolorclosestalpha',
+ 'imagecolorclosesthwb',
+ 'imagecolordeallocate',
+ 'imagecolorexact',
+ 'imagecolorexactalpha',
+ 'imagecolormatch',
+ 'imagecolorresolve',
+ 'imagecolorresolvealpha',
+ 'imagecolorset',
+ 'imagecolorsforindex',
+ 'imagecolorstotal',
+ 'imagecolortransparent',
+ 'imageconvolution',
+ 'imagecopy',
+ 'imagecopymerge',
+ 'imagecopymergegray',
+ 'imagecopyresampled',
+ 'imagecopyresized',
+ 'imagecrop',
+ 'imagecropauto',
+ 'imagedashedline',
+ 'imagedestroy',
+ 'imageellipse',
+ 'imagefill',
+ 'imagefilledarc',
+ 'imagefilledellipse',
+ 'imagefilledpolygon',
+ 'imagefilledrectangle',
+ 'imagefilltoborder',
+ 'imagefilter',
+ 'imageflip',
+ 'imagefttext',
+ 'imagegammacorrect',
+ 'imagegd',
+ 'imagegd2',
+ 'imagegetclip',
+ 'imagegif',
+ 'imagegrabscreen',
+ 'imagegrabwindow',
+ 'imageinterlace',
+ 'imageistruecolor',
+ 'imagejpeg',
+ 'imagelayereffect',
+ 'imageline',
+ 'imageopenpolygon',
+ 'imagepalettecopy',
+ 'imagepalettetotruecolor',
+ 'imagepng',
+ 'imagepolygon',
+ 'imagepsencodefont',
+ 'imagepsextendfont',
+ 'imagepsfreefont',
+ 'imagepsloadfont',
+ 'imagepsslantfont',
+ 'imagepstext',
+ 'imagerectangle',
+ 'imageresolution',
+ 'imagerotate',
+ 'imagesavealpha',
+ 'imagescale',
+ 'imagesetbrush',
+ 'imagesetclip',
+ 'imagesetinterpolation',
+ 'imagesetpixel',
+ 'imagesetstyle',
+ 'imagesetthickness',
+ 'imagesettile',
+ 'imagestring',
+ 'imagestringup',
+ 'imagesx',
+ 'imagesy',
+ 'imagetruecolortopalette',
+ 'imagettftext',
+ 'imagewbmp',
+ 'imagewebp',
+ 'imagexbm',
+ 'imap_append',
+ 'imap_body',
+ 'imap_bodystruct',
+ 'imap_check',
+ 'imap_clearflag_full',
+ 'imap_close',
+ 'imap_create',
+ 'imap_createmailbox',
+ 'imap_delete',
+ 'imap_deletemailbox',
+ 'imap_expunge',
+ 'imap_fetch_overview',
+ 'imap_fetchbody',
+ 'imap_fetchheader',
+ 'imap_fetchmime',
+ 'imap_fetchstructure',
+ 'imap_fetchtext',
+ 'imap_gc',
+ 'imap_get_quota',
+ 'imap_get_quotaroot',
+ 'imap_getacl',
+ 'imap_getmailboxes',
+ 'imap_getsubscribed',
+ 'imap_header',
+ 'imap_headerinfo',
+ 'imap_headers',
+ 'imap_list',
+ 'imap_listmailbox',
+ 'imap_listscan',
+ 'imap_listsubscribed',
+ 'imap_lsub',
+ 'imap_mail_copy',
+ 'imap_mail_move',
+ 'imap_mailboxmsginfo',
+ 'imap_msgno',
+ 'imap_num_msg',
+ 'imap_num_recent',
+ 'imap_ping',
+ 'imap_rename',
+ 'imap_renamemailbox',
+ 'imap_reopen',
+ 'imap_savebody',
+ 'imap_scan',
+ 'imap_scanmailbox',
+ 'imap_search',
+ 'imap_set_quota',
+ 'imap_setacl',
+ 'imap_setflag_full',
+ 'imap_sort',
+ 'imap_status',
+ 'imap_subscribe',
+ 'imap_thread',
+ 'imap_uid',
+ 'imap_undelete',
+ 'imap_unsubscribe',
+ 'inflate_add',
+ 'inflate_get_read_len',
+ 'inflate_get_status',
+ 'ingres_autocommit',
+ 'ingres_autocommit_state',
+ 'ingres_charset',
+ 'ingres_close',
+ 'ingres_commit',
+ 'ingres_connect',
+ 'ingres_cursor',
+ 'ingres_errno',
+ 'ingres_error',
+ 'ingres_errsqlstate',
+ 'ingres_escape_string',
+ 'ingres_execute',
+ 'ingres_fetch_array',
+ 'ingres_fetch_assoc',
+ 'ingres_fetch_object',
+ 'ingres_fetch_proc_return',
+ 'ingres_fetch_row',
+ 'ingres_field_length',
+ 'ingres_field_name',
+ 'ingres_field_nullable',
+ 'ingres_field_precision',
+ 'ingres_field_scale',
+ 'ingres_field_type',
+ 'ingres_free_result',
+ 'ingres_next_error',
+ 'ingres_num_fields',
+ 'ingres_num_rows',
+ 'ingres_pconnect',
+ 'ingres_prepare',
+ 'ingres_query',
+ 'ingres_result_seek',
+ 'ingres_rollback',
+ 'ingres_set_environment',
+ 'ingres_unbuffered_query',
+ 'inotify_add_watch',
+ 'inotify_init',
+ 'inotify_queue_len',
+ 'inotify_read',
+ 'inotify_rm_watch',
+ 'kadm5_chpass_principal',
+ 'kadm5_create_principal',
+ 'kadm5_delete_principal',
+ 'kadm5_destroy',
+ 'kadm5_flush',
+ 'kadm5_get_policies',
+ 'kadm5_get_principal',
+ 'kadm5_get_principals',
+ 'kadm5_init_with_password',
+ 'kadm5_modify_principal',
+ 'ldap_add',
+ 'ldap_bind',
+ 'ldap_close',
+ 'ldap_compare',
+ 'ldap_control_paged_result',
+ 'ldap_control_paged_result_response',
+ 'ldap_count_entries',
+ 'ldap_delete',
+ 'ldap_errno',
+ 'ldap_error',
+ 'ldap_exop',
+ 'ldap_exop_passwd',
+ 'ldap_exop_refresh',
+ 'ldap_exop_whoami',
+ 'ldap_first_attribute',
+ 'ldap_first_entry',
+ 'ldap_first_reference',
+ 'ldap_free_result',
+ 'ldap_get_attributes',
+ 'ldap_get_dn',
+ 'ldap_get_entries',
+ 'ldap_get_option',
+ 'ldap_get_values',
+ 'ldap_get_values_len',
+ 'ldap_mod_add',
+ 'ldap_mod_del',
+ 'ldap_mod_replace',
+ 'ldap_modify',
+ 'ldap_modify_batch',
+ 'ldap_next_attribute',
+ 'ldap_next_entry',
+ 'ldap_next_reference',
+ 'ldap_parse_exop',
+ 'ldap_parse_reference',
+ 'ldap_parse_result',
+ 'ldap_rename',
+ 'ldap_sasl_bind',
+ 'ldap_set_option',
+ 'ldap_set_rebind_proc',
+ 'ldap_sort',
+ 'ldap_start_tls',
+ 'ldap_unbind',
+ 'libxml_set_streams_context',
+ 'm_checkstatus',
+ 'm_completeauthorizations',
+ 'm_connect',
+ 'm_connectionerror',
+ 'm_deletetrans',
+ 'm_destroyconn',
+ 'm_getcell',
+ 'm_getcellbynum',
+ 'm_getcommadelimited',
+ 'm_getheader',
+ 'm_initconn',
+ 'm_iscommadelimited',
+ 'm_maxconntimeout',
+ 'm_monitor',
+ 'm_numcolumns',
+ 'm_numrows',
+ 'm_parsecommadelimited',
+ 'm_responsekeys',
+ 'm_responseparam',
+ 'm_returnstatus',
+ 'm_setblocking',
+ 'm_setdropfile',
+ 'm_setip',
+ 'm_setssl',
+ 'm_setssl_cafile',
+ 'm_setssl_files',
+ 'm_settimeout',
+ 'm_transactionssent',
+ 'm_transinqueue',
+ 'm_transkeyval',
+ 'm_transnew',
+ 'm_transsend',
+ 'm_validateidentifier',
+ 'm_verifyconnection',
+ 'm_verifysslcert',
+ 'mailparse_determine_best_xfer_encoding',
+ 'mailparse_msg_create',
+ 'mailparse_msg_extract_part',
+ 'mailparse_msg_extract_part_file',
+ 'mailparse_msg_extract_whole_part_file',
+ 'mailparse_msg_free',
+ 'mailparse_msg_get_part',
+ 'mailparse_msg_get_part_data',
+ 'mailparse_msg_get_structure',
+ 'mailparse_msg_parse',
+ 'mailparse_msg_parse_file',
+ 'mailparse_stream_encode',
+ 'mailparse_uudecode_all',
+ 'maxdb::use_result',
+ 'maxdb_affected_rows',
+ 'maxdb_connect',
+ 'maxdb_disable_rpl_parse',
+ 'maxdb_dump_debug_info',
+ 'maxdb_embedded_connect',
+ 'maxdb_enable_reads_from_master',
+ 'maxdb_enable_rpl_parse',
+ 'maxdb_errno',
+ 'maxdb_error',
+ 'maxdb_fetch_lengths',
+ 'maxdb_field_tell',
+ 'maxdb_get_host_info',
+ 'maxdb_get_proto_info',
+ 'maxdb_get_server_info',
+ 'maxdb_get_server_version',
+ 'maxdb_info',
+ 'maxdb_init',
+ 'maxdb_insert_id',
+ 'maxdb_master_query',
+ 'maxdb_more_results',
+ 'maxdb_next_result',
+ 'maxdb_num_fields',
+ 'maxdb_num_rows',
+ 'maxdb_rpl_parse_enabled',
+ 'maxdb_rpl_probe',
+ 'maxdb_select_db',
+ 'maxdb_sqlstate',
+ 'maxdb_stmt::result_metadata',
+ 'maxdb_stmt_affected_rows',
+ 'maxdb_stmt_errno',
+ 'maxdb_stmt_error',
+ 'maxdb_stmt_num_rows',
+ 'maxdb_stmt_param_count',
+ 'maxdb_stmt_result_metadata',
+ 'maxdb_stmt_sqlstate',
+ 'maxdb_thread_id',
+ 'maxdb_use_result',
+ 'maxdb_warning_count',
+ 'mcrypt_enc_get_algorithms_name',
+ 'mcrypt_enc_get_block_size',
+ 'mcrypt_enc_get_iv_size',
+ 'mcrypt_enc_get_key_size',
+ 'mcrypt_enc_get_modes_name',
+ 'mcrypt_enc_get_supported_key_sizes',
+ 'mcrypt_enc_is_block_algorithm',
+ 'mcrypt_enc_is_block_algorithm_mode',
+ 'mcrypt_enc_is_block_mode',
+ 'mcrypt_enc_self_test',
+ 'mcrypt_generic',
+ 'mcrypt_generic_deinit',
+ 'mcrypt_generic_end',
+ 'mcrypt_generic_init',
+ 'mcrypt_module_close',
+ 'mcrypt_module_open',
+ 'mdecrypt_generic',
+ 'mkdir',
+ 'mqseries_back',
+ 'mqseries_begin',
+ 'mqseries_close',
+ 'mqseries_cmit',
+ 'mqseries_conn',
+ 'mqseries_connx',
+ 'mqseries_disc',
+ 'mqseries_get',
+ 'mqseries_inq',
+ 'mqseries_open',
+ 'mqseries_put',
+ 'mqseries_put1',
+ 'mqseries_set',
+ 'msg_get_queue',
+ 'msg_receive',
+ 'msg_remove_queue',
+ 'msg_send',
+ 'msg_set_queue',
+ 'msg_stat_queue',
+ 'msql_affected_rows',
+ 'msql_close',
+ 'msql_connect',
+ 'msql_create_db',
+ 'msql_data_seek',
+ 'msql_db_query',
+ 'msql_drop_db',
+ 'msql_fetch_array',
+ 'msql_fetch_field',
+ 'msql_fetch_object',
+ 'msql_fetch_row',
+ 'msql_field_flags',
+ 'msql_field_len',
+ 'msql_field_name',
+ 'msql_field_seek',
+ 'msql_field_table',
+ 'msql_field_type',
+ 'msql_free_result',
+ 'msql_list_dbs',
+ 'msql_list_fields',
+ 'msql_list_tables',
+ 'msql_num_fields',
+ 'msql_num_rows',
+ 'msql_pconnect',
+ 'msql_query',
+ 'msql_result',
+ 'msql_select_db',
+ 'mssql_bind',
+ 'mssql_close',
+ 'mssql_connect',
+ 'mssql_data_seek',
+ 'mssql_execute',
+ 'mssql_fetch_array',
+ 'mssql_fetch_assoc',
+ 'mssql_fetch_batch',
+ 'mssql_fetch_field',
+ 'mssql_fetch_object',
+ 'mssql_fetch_row',
+ 'mssql_field_length',
+ 'mssql_field_name',
+ 'mssql_field_seek',
+ 'mssql_field_type',
+ 'mssql_free_result',
+ 'mssql_free_statement',
+ 'mssql_init',
+ 'mssql_next_result',
+ 'mssql_num_fields',
+ 'mssql_num_rows',
+ 'mssql_pconnect',
+ 'mssql_query',
+ 'mssql_result',
+ 'mssql_rows_affected',
+ 'mssql_select_db',
+ 'mysql_affected_rows',
+ 'mysql_client_encoding',
+ 'mysql_close',
+ 'mysql_connect',
+ 'mysql_create_db',
+ 'mysql_data_seek',
+ 'mysql_db_name',
+ 'mysql_db_query',
+ 'mysql_drop_db',
+ 'mysql_errno',
+ 'mysql_error',
+ 'mysql_fetch_array',
+ 'mysql_fetch_assoc',
+ 'mysql_fetch_field',
+ 'mysql_fetch_lengths',
+ 'mysql_fetch_object',
+ 'mysql_fetch_row',
+ 'mysql_field_flags',
+ 'mysql_field_len',
+ 'mysql_field_name',
+ 'mysql_field_seek',
+ 'mysql_field_table',
+ 'mysql_field_type',
+ 'mysql_free_result',
+ 'mysql_get_host_info',
+ 'mysql_get_proto_info',
+ 'mysql_get_server_info',
+ 'mysql_info',
+ 'mysql_insert_id',
+ 'mysql_list_dbs',
+ 'mysql_list_fields',
+ 'mysql_list_processes',
+ 'mysql_list_tables',
+ 'mysql_num_fields',
+ 'mysql_num_rows',
+ 'mysql_pconnect',
+ 'mysql_ping',
+ 'mysql_query',
+ 'mysql_real_escape_string',
+ 'mysql_result',
+ 'mysql_select_db',
+ 'mysql_set_charset',
+ 'mysql_stat',
+ 'mysql_tablename',
+ 'mysql_thread_id',
+ 'mysql_unbuffered_query',
+ 'mysqlnd_uh_convert_to_mysqlnd',
+ 'ncurses_bottom_panel',
+ 'ncurses_del_panel',
+ 'ncurses_delwin',
+ 'ncurses_getmaxyx',
+ 'ncurses_getyx',
+ 'ncurses_hide_panel',
+ 'ncurses_keypad',
+ 'ncurses_meta',
+ 'ncurses_move_panel',
+ 'ncurses_mvwaddstr',
+ 'ncurses_new_panel',
+ 'ncurses_newpad',
+ 'ncurses_newwin',
+ 'ncurses_panel_above',
+ 'ncurses_panel_below',
+ 'ncurses_panel_window',
+ 'ncurses_pnoutrefresh',
+ 'ncurses_prefresh',
+ 'ncurses_replace_panel',
+ 'ncurses_show_panel',
+ 'ncurses_top_panel',
+ 'ncurses_waddch',
+ 'ncurses_waddstr',
+ 'ncurses_wattroff',
+ 'ncurses_wattron',
+ 'ncurses_wattrset',
+ 'ncurses_wborder',
+ 'ncurses_wclear',
+ 'ncurses_wcolor_set',
+ 'ncurses_werase',
+ 'ncurses_wgetch',
+ 'ncurses_whline',
+ 'ncurses_wmouse_trafo',
+ 'ncurses_wmove',
+ 'ncurses_wnoutrefresh',
+ 'ncurses_wrefresh',
+ 'ncurses_wstandend',
+ 'ncurses_wstandout',
+ 'ncurses_wvline',
+ 'newt_button',
+ 'newt_button_bar',
+ 'newt_checkbox',
+ 'newt_checkbox_get_value',
+ 'newt_checkbox_set_flags',
+ 'newt_checkbox_set_value',
+ 'newt_checkbox_tree',
+ 'newt_checkbox_tree_add_item',
+ 'newt_checkbox_tree_find_item',
+ 'newt_checkbox_tree_get_current',
+ 'newt_checkbox_tree_get_entry_value',
+ 'newt_checkbox_tree_get_multi_selection',
+ 'newt_checkbox_tree_get_selection',
+ 'newt_checkbox_tree_multi',
+ 'newt_checkbox_tree_set_current',
+ 'newt_checkbox_tree_set_entry',
+ 'newt_checkbox_tree_set_entry_value',
+ 'newt_checkbox_tree_set_width',
+ 'newt_compact_button',
+ 'newt_component_add_callback',
+ 'newt_component_takes_focus',
+ 'newt_create_grid',
+ 'newt_draw_form',
+ 'newt_entry',
+ 'newt_entry_get_value',
+ 'newt_entry_set',
+ 'newt_entry_set_filter',
+ 'newt_entry_set_flags',
+ 'newt_form',
+ 'newt_form_add_component',
+ 'newt_form_add_components',
+ 'newt_form_add_hot_key',
+ 'newt_form_destroy',
+ 'newt_form_get_current',
+ 'newt_form_run',
+ 'newt_form_set_background',
+ 'newt_form_set_height',
+ 'newt_form_set_size',
+ 'newt_form_set_timer',
+ 'newt_form_set_width',
+ 'newt_form_watch_fd',
+ 'newt_grid_add_components_to_form',
+ 'newt_grid_basic_window',
+ 'newt_grid_free',
+ 'newt_grid_get_size',
+ 'newt_grid_h_close_stacked',
+ 'newt_grid_h_stacked',
+ 'newt_grid_place',
+ 'newt_grid_set_field',
+ 'newt_grid_simple_window',
+ 'newt_grid_v_close_stacked',
+ 'newt_grid_v_stacked',
+ 'newt_grid_wrapped_window',
+ 'newt_grid_wrapped_window_at',
+ 'newt_label',
+ 'newt_label_set_text',
+ 'newt_listbox',
+ 'newt_listbox_append_entry',
+ 'newt_listbox_clear',
+ 'newt_listbox_clear_selection',
+ 'newt_listbox_delete_entry',
+ 'newt_listbox_get_current',
+ 'newt_listbox_get_selection',
+ 'newt_listbox_insert_entry',
+ 'newt_listbox_item_count',
+ 'newt_listbox_select_item',
+ 'newt_listbox_set_current',
+ 'newt_listbox_set_current_by_key',
+ 'newt_listbox_set_data',
+ 'newt_listbox_set_entry',
+ 'newt_listbox_set_width',
+ 'newt_listitem',
+ 'newt_listitem_get_data',
+ 'newt_listitem_set',
+ 'newt_radio_get_current',
+ 'newt_radiobutton',
+ 'newt_run_form',
+ 'newt_scale',
+ 'newt_scale_set',
+ 'newt_scrollbar_set',
+ 'newt_textbox',
+ 'newt_textbox_get_num_lines',
+ 'newt_textbox_reflowed',
+ 'newt_textbox_set_height',
+ 'newt_textbox_set_text',
+ 'newt_vertical_scrollbar',
+ 'oci_bind_array_by_name',
+ 'oci_bind_by_name',
+ 'oci_cancel',
+ 'oci_close',
+ 'oci_commit',
+ 'oci_connect',
+ 'oci_define_by_name',
+ 'oci_error',
+ 'oci_execute',
+ 'oci_fetch',
+ 'oci_fetch_all',
+ 'oci_fetch_array',
+ 'oci_fetch_assoc',
+ 'oci_fetch_object',
+ 'oci_fetch_row',
+ 'oci_field_is_null',
+ 'oci_field_name',
+ 'oci_field_precision',
+ 'oci_field_scale',
+ 'oci_field_size',
+ 'oci_field_type',
+ 'oci_field_type_raw',
+ 'oci_free_cursor',
+ 'oci_free_statement',
+ 'oci_get_implicit_resultset',
+ 'oci_new_collection',
+ 'oci_new_connect',
+ 'oci_new_cursor',
+ 'oci_new_descriptor',
+ 'oci_num_fields',
+ 'oci_num_rows',
+ 'oci_parse',
+ 'oci_pconnect',
+ 'oci_register_taf_callback',
+ 'oci_result',
+ 'oci_rollback',
+ 'oci_server_version',
+ 'oci_set_action',
+ 'oci_set_client_identifier',
+ 'oci_set_client_info',
+ 'oci_set_module_name',
+ 'oci_set_prefetch',
+ 'oci_statement_type',
+ 'oci_unregister_taf_callback',
+ 'odbc_autocommit',
+ 'odbc_close',
+ 'odbc_columnprivileges',
+ 'odbc_columns',
+ 'odbc_commit',
+ 'odbc_connect',
+ 'odbc_cursor',
+ 'odbc_data_source',
+ 'odbc_do',
+ 'odbc_error',
+ 'odbc_errormsg',
+ 'odbc_exec',
+ 'odbc_execute',
+ 'odbc_fetch_array',
+ 'odbc_fetch_into',
+ 'odbc_fetch_row',
+ 'odbc_field_len',
+ 'odbc_field_name',
+ 'odbc_field_num',
+ 'odbc_field_precision',
+ 'odbc_field_scale',
+ 'odbc_field_type',
+ 'odbc_foreignkeys',
+ 'odbc_free_result',
+ 'odbc_gettypeinfo',
+ 'odbc_next_result',
+ 'odbc_num_fields',
+ 'odbc_num_rows',
+ 'odbc_pconnect',
+ 'odbc_prepare',
+ 'odbc_primarykeys',
+ 'odbc_procedurecolumns',
+ 'odbc_procedures',
+ 'odbc_result',
+ 'odbc_result_all',
+ 'odbc_rollback',
+ 'odbc_setoption',
+ 'odbc_specialcolumns',
+ 'odbc_statistics',
+ 'odbc_tableprivileges',
+ 'odbc_tables',
+ 'openal_buffer_create',
+ 'openal_buffer_data',
+ 'openal_buffer_destroy',
+ 'openal_buffer_get',
+ 'openal_buffer_loadwav',
+ 'openal_context_create',
+ 'openal_context_current',
+ 'openal_context_destroy',
+ 'openal_context_process',
+ 'openal_context_suspend',
+ 'openal_device_close',
+ 'openal_device_open',
+ 'openal_source_create',
+ 'openal_source_destroy',
+ 'openal_source_get',
+ 'openal_source_pause',
+ 'openal_source_play',
+ 'openal_source_rewind',
+ 'openal_source_set',
+ 'openal_source_stop',
+ 'openal_stream',
+ 'opendir',
+ 'openssl_csr_new',
+ 'openssl_dh_compute_key',
+ 'openssl_free_key',
+ 'openssl_pkey_export',
+ 'openssl_pkey_free',
+ 'openssl_pkey_get_details',
+ 'openssl_spki_new',
+ 'openssl_x509_free',
+ 'pclose',
+ 'pfsockopen',
+ 'pg_affected_rows',
+ 'pg_cancel_query',
+ 'pg_client_encoding',
+ 'pg_close',
+ 'pg_connect_poll',
+ 'pg_connection_busy',
+ 'pg_connection_reset',
+ 'pg_connection_status',
+ 'pg_consume_input',
+ 'pg_convert',
+ 'pg_copy_from',
+ 'pg_copy_to',
+ 'pg_dbname',
+ 'pg_delete',
+ 'pg_end_copy',
+ 'pg_escape_bytea',
+ 'pg_escape_identifier',
+ 'pg_escape_literal',
+ 'pg_escape_string',
+ 'pg_execute',
+ 'pg_fetch_all',
+ 'pg_fetch_all_columns',
+ 'pg_fetch_array',
+ 'pg_fetch_assoc',
+ 'pg_fetch_row',
+ 'pg_field_name',
+ 'pg_field_num',
+ 'pg_field_size',
+ 'pg_field_table',
+ 'pg_field_type',
+ 'pg_field_type_oid',
+ 'pg_flush',
+ 'pg_free_result',
+ 'pg_get_notify',
+ 'pg_get_pid',
+ 'pg_get_result',
+ 'pg_host',
+ 'pg_insert',
+ 'pg_last_error',
+ 'pg_last_notice',
+ 'pg_last_oid',
+ 'pg_lo_close',
+ 'pg_lo_create',
+ 'pg_lo_export',
+ 'pg_lo_import',
+ 'pg_lo_open',
+ 'pg_lo_read',
+ 'pg_lo_read_all',
+ 'pg_lo_seek',
+ 'pg_lo_tell',
+ 'pg_lo_truncate',
+ 'pg_lo_unlink',
+ 'pg_lo_write',
+ 'pg_meta_data',
+ 'pg_num_fields',
+ 'pg_num_rows',
+ 'pg_options',
+ 'pg_parameter_status',
+ 'pg_ping',
+ 'pg_port',
+ 'pg_prepare',
+ 'pg_put_line',
+ 'pg_query',
+ 'pg_query_params',
+ 'pg_result_error',
+ 'pg_result_error_field',
+ 'pg_result_seek',
+ 'pg_result_status',
+ 'pg_select',
+ 'pg_send_execute',
+ 'pg_send_prepare',
+ 'pg_send_query',
+ 'pg_send_query_params',
+ 'pg_set_client_encoding',
+ 'pg_set_error_verbosity',
+ 'pg_socket',
+ 'pg_trace',
+ 'pg_transaction_status',
+ 'pg_tty',
+ 'pg_untrace',
+ 'pg_update',
+ 'pg_version',
+ 'php_user_filter::filter',
+ 'proc_close',
+ 'proc_get_status',
+ 'proc_terminate',
+ 'ps_add_bookmark',
+ 'ps_add_launchlink',
+ 'ps_add_locallink',
+ 'ps_add_note',
+ 'ps_add_pdflink',
+ 'ps_add_weblink',
+ 'ps_arc',
+ 'ps_arcn',
+ 'ps_begin_page',
+ 'ps_begin_pattern',
+ 'ps_begin_template',
+ 'ps_circle',
+ 'ps_clip',
+ 'ps_close',
+ 'ps_close_image',
+ 'ps_closepath',
+ 'ps_closepath_stroke',
+ 'ps_continue_text',
+ 'ps_curveto',
+ 'ps_delete',
+ 'ps_end_page',
+ 'ps_end_pattern',
+ 'ps_end_template',
+ 'ps_fill',
+ 'ps_fill_stroke',
+ 'ps_findfont',
+ 'ps_get_buffer',
+ 'ps_get_parameter',
+ 'ps_get_value',
+ 'ps_hyphenate',
+ 'ps_include_file',
+ 'ps_lineto',
+ 'ps_makespotcolor',
+ 'ps_moveto',
+ 'ps_new',
+ 'ps_open_file',
+ 'ps_open_image',
+ 'ps_open_image_file',
+ 'ps_open_memory_image',
+ 'ps_place_image',
+ 'ps_rect',
+ 'ps_restore',
+ 'ps_rotate',
+ 'ps_save',
+ 'ps_scale',
+ 'ps_set_border_color',
+ 'ps_set_border_dash',
+ 'ps_set_border_style',
+ 'ps_set_info',
+ 'ps_set_parameter',
+ 'ps_set_text_pos',
+ 'ps_set_value',
+ 'ps_setcolor',
+ 'ps_setdash',
+ 'ps_setflat',
+ 'ps_setfont',
+ 'ps_setgray',
+ 'ps_setlinecap',
+ 'ps_setlinejoin',
+ 'ps_setlinewidth',
+ 'ps_setmiterlimit',
+ 'ps_setoverprintmode',
+ 'ps_setpolydash',
+ 'ps_shading',
+ 'ps_shading_pattern',
+ 'ps_shfill',
+ 'ps_show',
+ 'ps_show2',
+ 'ps_show_boxed',
+ 'ps_show_xy',
+ 'ps_show_xy2',
+ 'ps_string_geometry',
+ 'ps_stringwidth',
+ 'ps_stroke',
+ 'ps_symbol',
+ 'ps_symbol_name',
+ 'ps_symbol_width',
+ 'ps_translate',
+ 'px_close',
+ 'px_create_fp',
+ 'px_date2string',
+ 'px_delete',
+ 'px_delete_record',
+ 'px_get_field',
+ 'px_get_info',
+ 'px_get_parameter',
+ 'px_get_record',
+ 'px_get_schema',
+ 'px_get_value',
+ 'px_insert_record',
+ 'px_new',
+ 'px_numfields',
+ 'px_numrecords',
+ 'px_open_fp',
+ 'px_put_record',
+ 'px_retrieve_record',
+ 'px_set_blob_file',
+ 'px_set_parameter',
+ 'px_set_tablename',
+ 'px_set_targetencoding',
+ 'px_set_value',
+ 'px_timestamp2string',
+ 'px_update_record',
+ 'radius_acct_open',
+ 'radius_add_server',
+ 'radius_auth_open',
+ 'radius_close',
+ 'radius_config',
+ 'radius_create_request',
+ 'radius_demangle',
+ 'radius_demangle_mppe_key',
+ 'radius_get_attr',
+ 'radius_put_addr',
+ 'radius_put_attr',
+ 'radius_put_int',
+ 'radius_put_string',
+ 'radius_put_vendor_addr',
+ 'radius_put_vendor_attr',
+ 'radius_put_vendor_int',
+ 'radius_put_vendor_string',
+ 'radius_request_authenticator',
+ 'radius_salt_encrypt_attr',
+ 'radius_send_request',
+ 'radius_server_secret',
+ 'radius_strerror',
+ 'readdir',
+ 'readfile',
+ 'recode_file',
+ 'rename',
+ 'rewind',
+ 'rewinddir',
+ 'rmdir',
+ 'rpm_close',
+ 'rpm_get_tag',
+ 'rpm_open',
+ 'sapi_windows_vt100_support',
+ 'scandir',
+ 'sem_acquire',
+ 'sem_get',
+ 'sem_release',
+ 'sem_remove',
+ 'set_file_buffer',
+ 'shm_attach',
+ 'shm_detach',
+ 'shm_get_var',
+ 'shm_has_var',
+ 'shm_put_var',
+ 'shm_remove',
+ 'shm_remove_var',
+ 'shmop_close',
+ 'shmop_delete',
+ 'shmop_open',
+ 'shmop_read',
+ 'shmop_size',
+ 'shmop_write',
+ 'socket_accept',
+ 'socket_addrinfo_bind',
+ 'socket_addrinfo_connect',
+ 'socket_addrinfo_explain',
+ 'socket_bind',
+ 'socket_clear_error',
+ 'socket_close',
+ 'socket_connect',
+ 'socket_export_stream',
+ 'socket_get_option',
+ 'socket_get_status',
+ 'socket_getopt',
+ 'socket_getpeername',
+ 'socket_getsockname',
+ 'socket_import_stream',
+ 'socket_last_error',
+ 'socket_listen',
+ 'socket_read',
+ 'socket_recv',
+ 'socket_recvfrom',
+ 'socket_recvmsg',
+ 'socket_send',
+ 'socket_sendmsg',
+ 'socket_sendto',
+ 'socket_set_block',
+ 'socket_set_blocking',
+ 'socket_set_nonblock',
+ 'socket_set_option',
+ 'socket_set_timeout',
+ 'socket_shutdown',
+ 'socket_write',
+ 'sqlite_close',
+ 'sqlite_fetch_string',
+ 'sqlite_has_more',
+ 'sqlite_open',
+ 'sqlite_popen',
+ 'sqlsrv_begin_transaction',
+ 'sqlsrv_cancel',
+ 'sqlsrv_client_info',
+ 'sqlsrv_close',
+ 'sqlsrv_commit',
+ 'sqlsrv_connect',
+ 'sqlsrv_execute',
+ 'sqlsrv_fetch',
+ 'sqlsrv_fetch_array',
+ 'sqlsrv_fetch_object',
+ 'sqlsrv_field_metadata',
+ 'sqlsrv_free_stmt',
+ 'sqlsrv_get_field',
+ 'sqlsrv_has_rows',
+ 'sqlsrv_next_result',
+ 'sqlsrv_num_fields',
+ 'sqlsrv_num_rows',
+ 'sqlsrv_prepare',
+ 'sqlsrv_query',
+ 'sqlsrv_rollback',
+ 'sqlsrv_rows_affected',
+ 'sqlsrv_send_stream_data',
+ 'sqlsrv_server_info',
+ 'ssh2_auth_agent',
+ 'ssh2_auth_hostbased_file',
+ 'ssh2_auth_none',
+ 'ssh2_auth_password',
+ 'ssh2_auth_pubkey_file',
+ 'ssh2_disconnect',
+ 'ssh2_exec',
+ 'ssh2_fetch_stream',
+ 'ssh2_fingerprint',
+ 'ssh2_methods_negotiated',
+ 'ssh2_publickey_add',
+ 'ssh2_publickey_init',
+ 'ssh2_publickey_list',
+ 'ssh2_publickey_remove',
+ 'ssh2_scp_recv',
+ 'ssh2_scp_send',
+ 'ssh2_sftp',
+ 'ssh2_sftp_chmod',
+ 'ssh2_sftp_lstat',
+ 'ssh2_sftp_mkdir',
+ 'ssh2_sftp_readlink',
+ 'ssh2_sftp_realpath',
+ 'ssh2_sftp_rename',
+ 'ssh2_sftp_rmdir',
+ 'ssh2_sftp_stat',
+ 'ssh2_sftp_symlink',
+ 'ssh2_sftp_unlink',
+ 'ssh2_shell',
+ 'ssh2_tunnel',
+ 'stomp_connect',
+ 'streamWrapper::stream_cast',
+ 'stream_bucket_append',
+ 'stream_bucket_make_writeable',
+ 'stream_bucket_new',
+ 'stream_bucket_prepend',
+ 'stream_context_create',
+ 'stream_context_get_default',
+ 'stream_context_get_options',
+ 'stream_context_get_params',
+ 'stream_context_set_default',
+ 'stream_context_set_params',
+ 'stream_copy_to_stream',
+ 'stream_encoding',
+ 'stream_filter_append',
+ 'stream_filter_prepend',
+ 'stream_filter_remove',
+ 'stream_get_contents',
+ 'stream_get_line',
+ 'stream_get_meta_data',
+ 'stream_isatty',
+ 'stream_set_blocking',
+ 'stream_set_chunk_size',
+ 'stream_set_read_buffer',
+ 'stream_set_timeout',
+ 'stream_set_write_buffer',
+ 'stream_socket_accept',
+ 'stream_socket_client',
+ 'stream_socket_enable_crypto',
+ 'stream_socket_get_name',
+ 'stream_socket_recvfrom',
+ 'stream_socket_sendto',
+ 'stream_socket_server',
+ 'stream_socket_shutdown',
+ 'stream_supports_lock',
+ 'svn_fs_abort_txn',
+ 'svn_fs_apply_text',
+ 'svn_fs_begin_txn2',
+ 'svn_fs_change_node_prop',
+ 'svn_fs_check_path',
+ 'svn_fs_contents_changed',
+ 'svn_fs_copy',
+ 'svn_fs_delete',
+ 'svn_fs_dir_entries',
+ 'svn_fs_file_contents',
+ 'svn_fs_file_length',
+ 'svn_fs_is_dir',
+ 'svn_fs_is_file',
+ 'svn_fs_make_dir',
+ 'svn_fs_make_file',
+ 'svn_fs_node_created_rev',
+ 'svn_fs_node_prop',
+ 'svn_fs_props_changed',
+ 'svn_fs_revision_prop',
+ 'svn_fs_revision_root',
+ 'svn_fs_txn_root',
+ 'svn_fs_youngest_rev',
+ 'svn_repos_create',
+ 'svn_repos_fs',
+ 'svn_repos_fs_begin_txn_for_commit',
+ 'svn_repos_fs_commit_txn',
+ 'svn_repos_open',
+ 'sybase_affected_rows',
+ 'sybase_close',
+ 'sybase_connect',
+ 'sybase_data_seek',
+ 'sybase_fetch_array',
+ 'sybase_fetch_assoc',
+ 'sybase_fetch_field',
+ 'sybase_fetch_object',
+ 'sybase_fetch_row',
+ 'sybase_field_seek',
+ 'sybase_free_result',
+ 'sybase_num_fields',
+ 'sybase_num_rows',
+ 'sybase_pconnect',
+ 'sybase_query',
+ 'sybase_result',
+ 'sybase_select_db',
+ 'sybase_set_message_handler',
+ 'sybase_unbuffered_query',
+ 'tmpfile',
+ 'udm_add_search_limit',
+ 'udm_alloc_agent',
+ 'udm_alloc_agent_array',
+ 'udm_cat_list',
+ 'udm_cat_path',
+ 'udm_check_charset',
+ 'udm_clear_search_limits',
+ 'udm_crc32',
+ 'udm_errno',
+ 'udm_error',
+ 'udm_find',
+ 'udm_free_agent',
+ 'udm_free_res',
+ 'udm_get_doc_count',
+ 'udm_get_res_field',
+ 'udm_get_res_param',
+ 'udm_hash32',
+ 'udm_load_ispell_data',
+ 'udm_set_agent_param',
+ 'unlink',
+ 'vfprintf',
+ 'w32api_init_dtype',
+ 'wddx_add_vars',
+ 'wddx_packet_end',
+ 'wddx_packet_start',
+ 'xml_get_current_byte_index',
+ 'xml_get_current_column_number',
+ 'xml_get_current_line_number',
+ 'xml_get_error_code',
+ 'xml_parse',
+ 'xml_parse_into_struct',
+ 'xml_parser_create',
+ 'xml_parser_create_ns',
+ 'xml_parser_free',
+ 'xml_parser_get_option',
+ 'xml_parser_set_option',
+ 'xml_set_character_data_handler',
+ 'xml_set_default_handler',
+ 'xml_set_element_handler',
+ 'xml_set_end_namespace_decl_handler',
+ 'xml_set_external_entity_ref_handler',
+ 'xml_set_notation_decl_handler',
+ 'xml_set_object',
+ 'xml_set_processing_instruction_handler',
+ 'xml_set_start_namespace_decl_handler',
+ 'xml_set_unparsed_entity_decl_handler',
+ 'xmlrpc_server_add_introspection_data',
+ 'xmlrpc_server_call_method',
+ 'xmlrpc_server_create',
+ 'xmlrpc_server_destroy',
+ 'xmlrpc_server_register_introspection_callback',
+ 'xmlrpc_server_register_method',
+ 'xmlwriter_end_attribute',
+ 'xmlwriter_end_cdata',
+ 'xmlwriter_end_comment',
+ 'xmlwriter_end_document',
+ 'xmlwriter_end_dtd',
+ 'xmlwriter_end_dtd_attlist',
+ 'xmlwriter_end_dtd_element',
+ 'xmlwriter_end_dtd_entity',
+ 'xmlwriter_end_element',
+ 'xmlwriter_end_pi',
+ 'xmlwriter_flush',
+ 'xmlwriter_full_end_element',
+ 'xmlwriter_open_memory',
+ 'xmlwriter_open_uri',
+ 'xmlwriter_output_memory',
+ 'xmlwriter_set_indent',
+ 'xmlwriter_set_indent_string',
+ 'xmlwriter_start_attribute',
+ 'xmlwriter_start_attribute_ns',
+ 'xmlwriter_start_cdata',
+ 'xmlwriter_start_comment',
+ 'xmlwriter_start_document',
+ 'xmlwriter_start_dtd',
+ 'xmlwriter_start_dtd_attlist',
+ 'xmlwriter_start_dtd_element',
+ 'xmlwriter_start_dtd_entity',
+ 'xmlwriter_start_element',
+ 'xmlwriter_start_element_ns',
+ 'xmlwriter_start_pi',
+ 'xmlwriter_text',
+ 'xmlwriter_write_attribute',
+ 'xmlwriter_write_attribute_ns',
+ 'xmlwriter_write_cdata',
+ 'xmlwriter_write_comment',
+ 'xmlwriter_write_dtd',
+ 'xmlwriter_write_dtd_attlist',
+ 'xmlwriter_write_dtd_element',
+ 'xmlwriter_write_dtd_entity',
+ 'xmlwriter_write_element',
+ 'xmlwriter_write_element_ns',
+ 'xmlwriter_write_pi',
+ 'xmlwriter_write_raw',
+ 'xslt_create',
+ 'yaz_addinfo',
+ 'yaz_ccl_conf',
+ 'yaz_ccl_parse',
+ 'yaz_close',
+ 'yaz_database',
+ 'yaz_element',
+ 'yaz_errno',
+ 'yaz_error',
+ 'yaz_es',
+ 'yaz_es_result',
+ 'yaz_get_option',
+ 'yaz_hits',
+ 'yaz_itemorder',
+ 'yaz_present',
+ 'yaz_range',
+ 'yaz_record',
+ 'yaz_scan',
+ 'yaz_scan_result',
+ 'yaz_schema',
+ 'yaz_search',
+ 'yaz_sort',
+ 'yaz_syntax',
+ 'zip_close',
+ 'zip_entry_close',
+ 'zip_entry_compressedsize',
+ 'zip_entry_compressionmethod',
+ 'zip_entry_filesize',
+ 'zip_entry_name',
+ 'zip_entry_open',
+ 'zip_entry_read',
+ 'zip_open',
+ 'zip_read',
+ ];
+ }
+}
diff --git a/vendor/sebastian/type/ChangeLog.md b/vendor/sebastian/type/ChangeLog.md
new file mode 100644
index 000000000..73837bde5
--- /dev/null
+++ b/vendor/sebastian/type/ChangeLog.md
@@ -0,0 +1,123 @@
+# ChangeLog
+
+All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [2.3.4] - 2021-06-15
+
+* Fixed regression introduced in 2.3.3
+
+## [2.3.3] - 2021-06-15 [YANKED]
+
+### Fixed
+
+* [#15](https://github.com/sebastianbergmann/type/issues/15): "false" pseudo type is not handled properly
+
+## [2.3.2] - 2021-06-04
+
+### Fixed
+
+* Fixed handling of tentatively declared return types
+
+## [2.3.1] - 2020-10-26
+
+### Fixed
+
+* `SebastianBergmann\Type\Exception` now correctly extends `\Throwable`
+
+## [2.3.0] - 2020-10-06
+
+### Added
+
+* [#14](https://github.com/sebastianbergmann/type/issues/14): Support for `static` return type that is introduced in PHP 8
+
+## [2.2.2] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [2.2.1] - 2020-07-05
+
+### Fixed
+
+* Fixed handling of `mixed` type in `ReflectionMapper::fromMethodReturnType()`
+
+## [2.2.0] - 2020-07-05
+
+### Added
+
+* Added `MixedType` object for representing PHP 8's `mixed` type
+
+## [2.1.1] - 2020-06-26
+
+### Added
+
+* This component is now supported on PHP 8
+
+## [2.1.0] - 2020-06-01
+
+### Added
+
+* Added `UnionType` object for representing PHP 8's Union Types
+* Added `ReflectionMapper::fromMethodReturnType()` for mapping `\ReflectionMethod::getReturnType()` to a `Type` object
+* Added `Type::name()` for retrieving the name of a type
+* Added `Type::asString()` for retrieving a textual representation of a type
+
+### Changed
+
+* Deprecated `Type::getReturnTypeDeclaration()` (use `Type::asString()` instead and prefix its result with `': '`)
+* Deprecated `TypeName::getNamespaceName()` (use `TypeName::namespaceName()` instead)
+* Deprecated `TypeName::getSimpleName()` (use `TypeName::simpleName()` instead)
+* Deprecated `TypeName::getQualifiedName()` (use `TypeName::qualifiedName()` instead)
+
+## [2.0.0] - 2020-02-07
+
+### Removed
+
+* This component is no longer supported on PHP 7.2
+
+## [1.1.3] - 2019-07-02
+
+### Fixed
+
+* Fixed class name comparison in `ObjectType` to be case-insensitive
+
+## [1.1.2] - 2019-06-19
+
+### Fixed
+
+* Fixed handling of `object` type
+
+## [1.1.1] - 2019-06-08
+
+### Fixed
+
+* Fixed autoloading of `callback_function.php` fixture file
+
+## [1.1.0] - 2019-06-07
+
+### Added
+
+* Added support for `callable` type
+* Added support for `iterable` type
+
+## [1.0.0] - 2019-06-06
+
+* Initial release based on [code contributed by Michel Hartmann to PHPUnit](https://github.com/sebastianbergmann/phpunit/pull/3673)
+
+[2.3.4]: https://github.com/sebastianbergmann/type/compare/ca39369c41313ed12c071ed38ecda8fcdb248859...2.3.4
+[2.3.3]: https://github.com/sebastianbergmann/type/compare/2.3.2...ca39369c41313ed12c071ed38ecda8fcdb248859
+[2.3.2]: https://github.com/sebastianbergmann/type/compare/2.3.1...2.3.2
+[2.3.1]: https://github.com/sebastianbergmann/type/compare/2.3.0...2.3.1
+[2.3.0]: https://github.com/sebastianbergmann/type/compare/2.2.2...2.3.0
+[2.2.2]: https://github.com/sebastianbergmann/type/compare/2.2.1...2.2.2
+[2.2.1]: https://github.com/sebastianbergmann/type/compare/2.2.0...2.2.1
+[2.2.0]: https://github.com/sebastianbergmann/type/compare/2.1.1...2.2.0
+[2.1.1]: https://github.com/sebastianbergmann/type/compare/2.1.0...2.1.1
+[2.1.0]: https://github.com/sebastianbergmann/type/compare/2.0.0...2.1.0
+[2.0.0]: https://github.com/sebastianbergmann/type/compare/1.1.3...2.0.0
+[1.1.3]: https://github.com/sebastianbergmann/type/compare/1.1.2...1.1.3
+[1.1.2]: https://github.com/sebastianbergmann/type/compare/1.1.1...1.1.2
+[1.1.1]: https://github.com/sebastianbergmann/type/compare/1.1.0...1.1.1
+[1.1.0]: https://github.com/sebastianbergmann/type/compare/1.0.0...1.1.0
+[1.0.0]: https://github.com/sebastianbergmann/type/compare/ff74aa41746bd8d10e931843ebf37d42da513ede...1.0.0
diff --git a/vendor/sebastian/type/LICENSE b/vendor/sebastian/type/LICENSE
new file mode 100644
index 000000000..b840591a9
--- /dev/null
+++ b/vendor/sebastian/type/LICENSE
@@ -0,0 +1,33 @@
+sebastian/type
+
+Copyright (c) 2019-2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/type/README.md b/vendor/sebastian/type/README.md
new file mode 100644
index 000000000..1036ce7a7
--- /dev/null
+++ b/vendor/sebastian/type/README.md
@@ -0,0 +1,20 @@
+# sebastian/type
+
+[![CI Status](https://github.com/sebastianbergmann/type/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/type/actions)
+[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/type/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/type)
+
+Collection of value objects that represent the types of the PHP type system.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+```
+composer require sebastian/type
+```
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+```
+composer require --dev sebastian/type
+```
diff --git a/vendor/sebastian/type/composer.json b/vendor/sebastian/type/composer.json
new file mode 100644
index 000000000..b02d8e92a
--- /dev/null
+++ b/vendor/sebastian/type/composer.json
@@ -0,0 +1,49 @@
+{
+ "name": "sebastian/type",
+ "description": "Collection of value objects that represent the types of the PHP type system",
+ "type": "library",
+ "homepage": "https://github.com/sebastianbergmann/type",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/type/issues"
+ },
+ "prefer-stable": true,
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "autoload-dev": {
+ "classmap": [
+ "tests/_fixture"
+ ],
+ "files": [
+ "tests/_fixture/callback_function.php"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/type/src/CallableType.php b/vendor/sebastian/type/src/CallableType.php
new file mode 100644
index 000000000..026762eaf
--- /dev/null
+++ b/vendor/sebastian/type/src/CallableType.php
@@ -0,0 +1,197 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+use function assert;
+use function class_exists;
+use function count;
+use function explode;
+use function function_exists;
+use function is_array;
+use function is_object;
+use function is_string;
+use function strpos;
+use Closure;
+use ReflectionClass;
+use ReflectionException;
+use ReflectionObject;
+
+final class CallableType extends Type
+{
+ /**
+ * @var bool
+ */
+ private $allowsNull;
+
+ public function __construct(bool $nullable)
+ {
+ $this->allowsNull = $nullable;
+ }
+
+ /**
+ * @throws RuntimeException
+ */
+ public function isAssignable(Type $other): bool
+ {
+ if ($this->allowsNull && $other instanceof NullType) {
+ return true;
+ }
+
+ if ($other instanceof self) {
+ return true;
+ }
+
+ if ($other instanceof ObjectType) {
+ if ($this->isClosure($other)) {
+ return true;
+ }
+
+ if ($this->hasInvokeMethod($other)) {
+ return true;
+ }
+ }
+
+ if ($other instanceof SimpleType) {
+ if ($this->isFunction($other)) {
+ return true;
+ }
+
+ if ($this->isClassCallback($other)) {
+ return true;
+ }
+
+ if ($this->isObjectCallback($other)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function name(): string
+ {
+ return 'callable';
+ }
+
+ public function allowsNull(): bool
+ {
+ return $this->allowsNull;
+ }
+
+ private function isClosure(ObjectType $type): bool
+ {
+ return !$type->className()->isNamespaced() && $type->className()->simpleName() === Closure::class;
+ }
+
+ /**
+ * @throws RuntimeException
+ */
+ private function hasInvokeMethod(ObjectType $type): bool
+ {
+ $className = $type->className()->qualifiedName();
+ assert(class_exists($className));
+
+ try {
+ $class = new ReflectionClass($className);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new RuntimeException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ // @codeCoverageIgnoreEnd
+ }
+
+ if ($class->hasMethod('__invoke')) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private function isFunction(SimpleType $type): bool
+ {
+ if (!is_string($type->value())) {
+ return false;
+ }
+
+ return function_exists($type->value());
+ }
+
+ private function isObjectCallback(SimpleType $type): bool
+ {
+ if (!is_array($type->value())) {
+ return false;
+ }
+
+ if (count($type->value()) !== 2) {
+ return false;
+ }
+
+ if (!is_object($type->value()[0]) || !is_string($type->value()[1])) {
+ return false;
+ }
+
+ [$object, $methodName] = $type->value();
+
+ return (new ReflectionObject($object))->hasMethod($methodName);
+ }
+
+ private function isClassCallback(SimpleType $type): bool
+ {
+ if (!is_string($type->value()) && !is_array($type->value())) {
+ return false;
+ }
+
+ if (is_string($type->value())) {
+ if (strpos($type->value(), '::') === false) {
+ return false;
+ }
+
+ [$className, $methodName] = explode('::', $type->value());
+ }
+
+ if (is_array($type->value())) {
+ if (count($type->value()) !== 2) {
+ return false;
+ }
+
+ if (!is_string($type->value()[0]) || !is_string($type->value()[1])) {
+ return false;
+ }
+
+ [$className, $methodName] = $type->value();
+ }
+
+ assert(isset($className) && is_string($className) && class_exists($className));
+ assert(isset($methodName) && is_string($methodName));
+
+ try {
+ $class = new ReflectionClass($className);
+
+ if ($class->hasMethod($methodName)) {
+ $method = $class->getMethod($methodName);
+
+ return $method->isPublic() && $method->isStatic();
+ }
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new RuntimeException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ // @codeCoverageIgnoreEnd
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/sebastian/type/src/FalseType.php b/vendor/sebastian/type/src/FalseType.php
new file mode 100644
index 000000000..425f363c0
--- /dev/null
+++ b/vendor/sebastian/type/src/FalseType.php
@@ -0,0 +1,46 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+final class FalseType extends Type
+{
+ public function isAssignable(Type $other): bool
+ {
+ if ($other instanceof self) {
+ return true;
+ }
+
+ return $other instanceof SimpleType &&
+ $other->name() === 'bool' &&
+ $other->value() === false;
+ }
+
+ public function name(): string
+ {
+ return 'false';
+ }
+
+ public function allowsNull(): bool
+ {
+ return false;
+ }
+
+ /**
+ * @deprecated
+ *
+ * @codeCoverageIgnore
+ *
+ * @throws LogicException
+ */
+ public function getReturnTypeDeclaration(): string
+ {
+ throw new LogicException;
+ }
+}
diff --git a/vendor/sebastian/type/src/GenericObjectType.php b/vendor/sebastian/type/src/GenericObjectType.php
new file mode 100644
index 000000000..6871008bd
--- /dev/null
+++ b/vendor/sebastian/type/src/GenericObjectType.php
@@ -0,0 +1,46 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+final class GenericObjectType extends Type
+{
+ /**
+ * @var bool
+ */
+ private $allowsNull;
+
+ public function __construct(bool $nullable)
+ {
+ $this->allowsNull = $nullable;
+ }
+
+ public function isAssignable(Type $other): bool
+ {
+ if ($this->allowsNull && $other instanceof NullType) {
+ return true;
+ }
+
+ if (!$other instanceof ObjectType) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public function name(): string
+ {
+ return 'object';
+ }
+
+ public function allowsNull(): bool
+ {
+ return $this->allowsNull;
+ }
+}
diff --git a/vendor/sebastian/type/src/IterableType.php b/vendor/sebastian/type/src/IterableType.php
new file mode 100644
index 000000000..c5bc6627b
--- /dev/null
+++ b/vendor/sebastian/type/src/IterableType.php
@@ -0,0 +1,76 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+use function assert;
+use function class_exists;
+use function is_iterable;
+use ReflectionClass;
+use ReflectionException;
+
+final class IterableType extends Type
+{
+ /**
+ * @var bool
+ */
+ private $allowsNull;
+
+ public function __construct(bool $nullable)
+ {
+ $this->allowsNull = $nullable;
+ }
+
+ /**
+ * @throws RuntimeException
+ */
+ public function isAssignable(Type $other): bool
+ {
+ if ($this->allowsNull && $other instanceof NullType) {
+ return true;
+ }
+
+ if ($other instanceof self) {
+ return true;
+ }
+
+ if ($other instanceof SimpleType) {
+ return is_iterable($other->value());
+ }
+
+ if ($other instanceof ObjectType) {
+ $className = $other->className()->qualifiedName();
+ assert(class_exists($className));
+
+ try {
+ return (new ReflectionClass($className))->isIterable();
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new RuntimeException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ // @codeCoverageIgnoreEnd
+ }
+ }
+
+ return false;
+ }
+
+ public function name(): string
+ {
+ return 'iterable';
+ }
+
+ public function allowsNull(): bool
+ {
+ return $this->allowsNull;
+ }
+}
diff --git a/vendor/sebastian/type/src/MixedType.php b/vendor/sebastian/type/src/MixedType.php
new file mode 100644
index 000000000..7ad9191da
--- /dev/null
+++ b/vendor/sebastian/type/src/MixedType.php
@@ -0,0 +1,33 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+final class MixedType extends Type
+{
+ public function isAssignable(Type $other): bool
+ {
+ return !$other instanceof VoidType;
+ }
+
+ public function asString(): string
+ {
+ return 'mixed';
+ }
+
+ public function name(): string
+ {
+ return 'mixed';
+ }
+
+ public function allowsNull(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/sebastian/type/src/NullType.php b/vendor/sebastian/type/src/NullType.php
new file mode 100644
index 000000000..8481fceb8
--- /dev/null
+++ b/vendor/sebastian/type/src/NullType.php
@@ -0,0 +1,43 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+final class NullType extends Type
+{
+ public function isAssignable(Type $other): bool
+ {
+ return !($other instanceof VoidType);
+ }
+
+ public function name(): string
+ {
+ return 'null';
+ }
+
+ public function asString(): string
+ {
+ return 'null';
+ }
+
+ /**
+ * @deprecated
+ *
+ * @codeCoverageIgnore
+ */
+ public function getReturnTypeDeclaration(): string
+ {
+ return '';
+ }
+
+ public function allowsNull(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/sebastian/type/src/ObjectType.php b/vendor/sebastian/type/src/ObjectType.php
new file mode 100644
index 000000000..c71273cb4
--- /dev/null
+++ b/vendor/sebastian/type/src/ObjectType.php
@@ -0,0 +1,66 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+use function is_subclass_of;
+use function strcasecmp;
+
+final class ObjectType extends Type
+{
+ /**
+ * @var TypeName
+ */
+ private $className;
+
+ /**
+ * @var bool
+ */
+ private $allowsNull;
+
+ public function __construct(TypeName $className, bool $allowsNull)
+ {
+ $this->className = $className;
+ $this->allowsNull = $allowsNull;
+ }
+
+ public function isAssignable(Type $other): bool
+ {
+ if ($this->allowsNull && $other instanceof NullType) {
+ return true;
+ }
+
+ if ($other instanceof self) {
+ if (0 === strcasecmp($this->className->qualifiedName(), $other->className->qualifiedName())) {
+ return true;
+ }
+
+ if (is_subclass_of($other->className->qualifiedName(), $this->className->qualifiedName(), true)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function name(): string
+ {
+ return $this->className->qualifiedName();
+ }
+
+ public function allowsNull(): bool
+ {
+ return $this->allowsNull;
+ }
+
+ public function className(): TypeName
+ {
+ return $this->className;
+ }
+}
diff --git a/vendor/sebastian/type/src/ReflectionMapper.php b/vendor/sebastian/type/src/ReflectionMapper.php
new file mode 100644
index 000000000..db9baf425
--- /dev/null
+++ b/vendor/sebastian/type/src/ReflectionMapper.php
@@ -0,0 +1,123 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+use function assert;
+use function sprintf;
+use ReflectionMethod;
+use ReflectionNamedType;
+use ReflectionType;
+use ReflectionUnionType;
+
+final class ReflectionMapper
+{
+ public function fromMethodReturnType(ReflectionMethod $method): Type
+ {
+ if (!$this->reflectionMethodHasReturnType($method)) {
+ return new UnknownType;
+ }
+
+ $returnType = $this->reflectionMethodGetReturnType($method);
+
+ assert($returnType instanceof ReflectionNamedType || $returnType instanceof ReflectionUnionType);
+
+ if ($returnType instanceof ReflectionNamedType) {
+ if ($returnType->getName() === 'self') {
+ return ObjectType::fromName(
+ $method->getDeclaringClass()->getName(),
+ $returnType->allowsNull()
+ );
+ }
+
+ if ($returnType->getName() === 'static') {
+ return new StaticType(
+ TypeName::fromReflection($method->getDeclaringClass()),
+ $returnType->allowsNull()
+ );
+ }
+
+ if ($returnType->getName() === 'mixed') {
+ return new MixedType;
+ }
+
+ if ($returnType->getName() === 'parent') {
+ $parentClass = $method->getDeclaringClass()->getParentClass();
+
+ // @codeCoverageIgnoreStart
+ if ($parentClass === false) {
+ throw new RuntimeException(
+ sprintf(
+ '%s::%s() has a "parent" return type declaration but %s does not have a parent class',
+ $method->getDeclaringClass()->getName(),
+ $method->getName(),
+ $method->getDeclaringClass()->getName()
+ )
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ return ObjectType::fromName(
+ $parentClass->getName(),
+ $returnType->allowsNull()
+ );
+ }
+
+ return Type::fromName(
+ $returnType->getName(),
+ $returnType->allowsNull()
+ );
+ }
+
+ assert($returnType instanceof ReflectionUnionType);
+
+ $types = [];
+
+ foreach ($returnType->getTypes() as $type) {
+ assert($type instanceof ReflectionNamedType);
+
+ if ($type->getName() === 'self') {
+ $types[] = ObjectType::fromName(
+ $method->getDeclaringClass()->getName(),
+ false
+ );
+ } else {
+ $types[] = Type::fromName($type->getName(), false);
+ }
+ }
+
+ return new UnionType(...$types);
+ }
+
+ private function reflectionMethodHasReturnType(ReflectionMethod $method): bool
+ {
+ if ($method->hasReturnType()) {
+ return true;
+ }
+
+ if (!method_exists($method, 'hasTentativeReturnType')) {
+ return false;
+ }
+
+ return $method->hasTentativeReturnType();
+ }
+
+ private function reflectionMethodGetReturnType(ReflectionMethod $method): ?ReflectionType
+ {
+ if ($method->hasReturnType()) {
+ return $method->getReturnType();
+ }
+
+ if (!method_exists($method, 'getTentativeReturnType')) {
+ return null;
+ }
+
+ return $method->getTentativeReturnType();
+ }
+}
diff --git a/vendor/sebastian/type/src/SimpleType.php b/vendor/sebastian/type/src/SimpleType.php
new file mode 100644
index 000000000..8bf0bf7df
--- /dev/null
+++ b/vendor/sebastian/type/src/SimpleType.php
@@ -0,0 +1,92 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+use function strtolower;
+
+final class SimpleType extends Type
+{
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @var bool
+ */
+ private $allowsNull;
+
+ /**
+ * @var mixed
+ */
+ private $value;
+
+ public function __construct(string $name, bool $nullable, $value = null)
+ {
+ $this->name = $this->normalize($name);
+ $this->allowsNull = $nullable;
+ $this->value = $value;
+ }
+
+ public function isAssignable(Type $other): bool
+ {
+ if ($this->allowsNull && $other instanceof NullType) {
+ return true;
+ }
+
+ if ($this->name === 'bool' && $other->name() === 'false') {
+ return true;
+ }
+
+ if ($other instanceof self) {
+ return $this->name === $other->name;
+ }
+
+ return false;
+ }
+
+ public function name(): string
+ {
+ return $this->name;
+ }
+
+ public function allowsNull(): bool
+ {
+ return $this->allowsNull;
+ }
+
+ public function value()
+ {
+ return $this->value;
+ }
+
+ private function normalize(string $name): string
+ {
+ $name = strtolower($name);
+
+ switch ($name) {
+ case 'boolean':
+ return 'bool';
+
+ case 'real':
+ case 'double':
+ return 'float';
+
+ case 'integer':
+ return 'int';
+
+ case '[]':
+ return 'array';
+
+ default:
+ return $name;
+ }
+ }
+}
diff --git a/vendor/sebastian/type/src/StaticType.php b/vendor/sebastian/type/src/StaticType.php
new file mode 100644
index 000000000..6833094d1
--- /dev/null
+++ b/vendor/sebastian/type/src/StaticType.php
@@ -0,0 +1,60 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+final class StaticType extends Type
+{
+ /**
+ * @var TypeName
+ */
+ private $className;
+
+ /**
+ * @var bool
+ */
+ private $allowsNull;
+
+ public function __construct(TypeName $className, bool $allowsNull)
+ {
+ $this->className = $className;
+ $this->allowsNull = $allowsNull;
+ }
+
+ public function isAssignable(Type $other): bool
+ {
+ if ($this->allowsNull && $other instanceof NullType) {
+ return true;
+ }
+
+ if (!$other instanceof ObjectType) {
+ return false;
+ }
+
+ if (0 === strcasecmp($this->className->qualifiedName(), $other->className()->qualifiedName())) {
+ return true;
+ }
+
+ if (is_subclass_of($other->className()->qualifiedName(), $this->className->qualifiedName(), true)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public function name(): string
+ {
+ return 'static';
+ }
+
+ public function allowsNull(): bool
+ {
+ return $this->allowsNull;
+ }
+}
diff --git a/vendor/sebastian/type/src/Type.php b/vendor/sebastian/type/src/Type.php
new file mode 100644
index 000000000..679223d96
--- /dev/null
+++ b/vendor/sebastian/type/src/Type.php
@@ -0,0 +1,101 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+use function get_class;
+use function gettype;
+use function strtolower;
+
+abstract class Type
+{
+ public static function fromValue($value, bool $allowsNull): self
+ {
+ if ($value === false) {
+ return new FalseType;
+ }
+
+ $typeName = gettype($value);
+
+ if ($typeName === 'object') {
+ return new ObjectType(TypeName::fromQualifiedName(get_class($value)), $allowsNull);
+ }
+
+ $type = self::fromName($typeName, $allowsNull);
+
+ if ($type instanceof SimpleType) {
+ $type = new SimpleType($typeName, $allowsNull, $value);
+ }
+
+ return $type;
+ }
+
+ public static function fromName(string $typeName, bool $allowsNull): self
+ {
+ switch (strtolower($typeName)) {
+ case 'callable':
+ return new CallableType($allowsNull);
+
+ case 'false':
+ return new FalseType;
+
+ case 'iterable':
+ return new IterableType($allowsNull);
+
+ case 'null':
+ return new NullType;
+
+ case 'object':
+ return new GenericObjectType($allowsNull);
+
+ case 'unknown type':
+ return new UnknownType;
+
+ case 'void':
+ return new VoidType;
+
+ case 'array':
+ case 'bool':
+ case 'boolean':
+ case 'double':
+ case 'float':
+ case 'int':
+ case 'integer':
+ case 'real':
+ case 'resource':
+ case 'resource (closed)':
+ case 'string':
+ return new SimpleType($typeName, $allowsNull);
+
+ default:
+ return new ObjectType(TypeName::fromQualifiedName($typeName), $allowsNull);
+ }
+ }
+
+ public function asString(): string
+ {
+ return ($this->allowsNull() ? '?' : '') . $this->name();
+ }
+
+ /**
+ * @deprecated
+ *
+ * @codeCoverageIgnore
+ */
+ public function getReturnTypeDeclaration(): string
+ {
+ return ': ' . $this->asString();
+ }
+
+ abstract public function isAssignable(Type $other): bool;
+
+ abstract public function name(): string;
+
+ abstract public function allowsNull(): bool;
+}
diff --git a/vendor/sebastian/type/src/TypeName.php b/vendor/sebastian/type/src/TypeName.php
new file mode 100644
index 000000000..b076e89e0
--- /dev/null
+++ b/vendor/sebastian/type/src/TypeName.php
@@ -0,0 +1,113 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+use function array_pop;
+use function explode;
+use function implode;
+use function substr;
+use ReflectionClass;
+
+final class TypeName
+{
+ /**
+ * @var ?string
+ */
+ private $namespaceName;
+
+ /**
+ * @var string
+ */
+ private $simpleName;
+
+ public static function fromQualifiedName(string $fullClassName): self
+ {
+ if ($fullClassName[0] === '\\') {
+ $fullClassName = substr($fullClassName, 1);
+ }
+
+ $classNameParts = explode('\\', $fullClassName);
+
+ $simpleName = array_pop($classNameParts);
+ $namespaceName = implode('\\', $classNameParts);
+
+ return new self($namespaceName, $simpleName);
+ }
+
+ public static function fromReflection(ReflectionClass $type): self
+ {
+ return new self(
+ $type->getNamespaceName(),
+ $type->getShortName()
+ );
+ }
+
+ public function __construct(?string $namespaceName, string $simpleName)
+ {
+ if ($namespaceName === '') {
+ $namespaceName = null;
+ }
+
+ $this->namespaceName = $namespaceName;
+ $this->simpleName = $simpleName;
+ }
+
+ public function namespaceName(): ?string
+ {
+ return $this->namespaceName;
+ }
+
+ public function simpleName(): string
+ {
+ return $this->simpleName;
+ }
+
+ public function qualifiedName(): string
+ {
+ return $this->namespaceName === null
+ ? $this->simpleName
+ : $this->namespaceName . '\\' . $this->simpleName;
+ }
+
+ /**
+ * @deprecated Use namespaceName() instead
+ *
+ * @codeCoverageIgnore
+ */
+ public function getNamespaceName(): ?string
+ {
+ return $this->namespaceName();
+ }
+
+ /**
+ * @deprecated Use simpleName() instead
+ *
+ * @codeCoverageIgnore
+ */
+ public function getSimpleName(): string
+ {
+ return $this->simpleName();
+ }
+
+ /**
+ * @deprecated Use qualifiedName() instead
+ *
+ * @codeCoverageIgnore
+ */
+ public function getQualifiedName(): string
+ {
+ return $this->qualifiedName();
+ }
+
+ public function isNamespaced(): bool
+ {
+ return $this->namespaceName !== null;
+ }
+}
diff --git a/vendor/sebastian/type/src/UnionType.php b/vendor/sebastian/type/src/UnionType.php
new file mode 100644
index 000000000..10c4a49b5
--- /dev/null
+++ b/vendor/sebastian/type/src/UnionType.php
@@ -0,0 +1,115 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+use function count;
+use function implode;
+use function sort;
+
+final class UnionType extends Type
+{
+ /**
+ * @psalm-var list<Type>
+ */
+ private $types;
+
+ /**
+ * @throws RuntimeException
+ */
+ public function __construct(Type ...$types)
+ {
+ $this->ensureMinimumOfTwoTypes(...$types);
+ $this->ensureOnlyValidTypes(...$types);
+
+ $this->types = $types;
+ }
+
+ public function isAssignable(Type $other): bool
+ {
+ foreach ($this->types as $type) {
+ if ($type->isAssignable($other)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function asString(): string
+ {
+ return $this->name();
+ }
+
+ /**
+ * @deprecated
+ *
+ * @codeCoverageIgnore
+ */
+ public function getReturnTypeDeclaration(): string
+ {
+ return ': ' . $this->name();
+ }
+
+ public function name(): string
+ {
+ $types = [];
+
+ foreach ($this->types as $type) {
+ $types[] = $type->name();
+ }
+
+ sort($types);
+
+ return implode('|', $types);
+ }
+
+ public function allowsNull(): bool
+ {
+ foreach ($this->types as $type) {
+ if ($type instanceof NullType) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @throws RuntimeException
+ */
+ private function ensureMinimumOfTwoTypes(Type ...$types): void
+ {
+ if (count($types) < 2) {
+ throw new RuntimeException(
+ 'A union type must be composed of at least two types'
+ );
+ }
+ }
+
+ /**
+ * @throws RuntimeException
+ */
+ private function ensureOnlyValidTypes(Type ...$types): void
+ {
+ foreach ($types as $type) {
+ if ($type instanceof UnknownType) {
+ throw new RuntimeException(
+ 'A union type must not be composed of an unknown type'
+ );
+ }
+
+ if ($type instanceof VoidType) {
+ throw new RuntimeException(
+ 'A union type must not be composed of a void type'
+ );
+ }
+ }
+ }
+}
diff --git a/vendor/sebastian/type/src/UnknownType.php b/vendor/sebastian/type/src/UnknownType.php
new file mode 100644
index 000000000..dde4c6788
--- /dev/null
+++ b/vendor/sebastian/type/src/UnknownType.php
@@ -0,0 +1,43 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+final class UnknownType extends Type
+{
+ public function isAssignable(Type $other): bool
+ {
+ return true;
+ }
+
+ public function name(): string
+ {
+ return 'unknown type';
+ }
+
+ public function asString(): string
+ {
+ return '';
+ }
+
+ /**
+ * @deprecated
+ *
+ * @codeCoverageIgnore
+ */
+ public function getReturnTypeDeclaration(): string
+ {
+ return '';
+ }
+
+ public function allowsNull(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/sebastian/type/src/VoidType.php b/vendor/sebastian/type/src/VoidType.php
new file mode 100644
index 000000000..18c017564
--- /dev/null
+++ b/vendor/sebastian/type/src/VoidType.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+final class VoidType extends Type
+{
+ public function isAssignable(Type $other): bool
+ {
+ return $other instanceof self;
+ }
+
+ public function name(): string
+ {
+ return 'void';
+ }
+
+ public function allowsNull(): bool
+ {
+ return false;
+ }
+}
diff --git a/vendor/sebastian/type/src/exception/Exception.php b/vendor/sebastian/type/src/exception/Exception.php
new file mode 100644
index 000000000..e0e7ee579
--- /dev/null
+++ b/vendor/sebastian/type/src/exception/Exception.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+use Throwable;
+
+interface Exception extends Throwable
+{
+}
diff --git a/vendor/sebastian/type/src/exception/LogicException.php b/vendor/sebastian/type/src/exception/LogicException.php
new file mode 100644
index 000000000..243582166
--- /dev/null
+++ b/vendor/sebastian/type/src/exception/LogicException.php
@@ -0,0 +1,14 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+final class LogicException extends \LogicException implements Exception
+{
+}
diff --git a/vendor/sebastian/type/src/exception/RuntimeException.php b/vendor/sebastian/type/src/exception/RuntimeException.php
new file mode 100644
index 000000000..4dfea6a6a
--- /dev/null
+++ b/vendor/sebastian/type/src/exception/RuntimeException.php
@@ -0,0 +1,14 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of sebastian/type.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace SebastianBergmann\Type;
+
+final class RuntimeException extends \RuntimeException implements Exception
+{
+}
diff --git a/vendor/sebastian/version/.gitattributes b/vendor/sebastian/version/.gitattributes
new file mode 100644
index 000000000..54b895305
--- /dev/null
+++ b/vendor/sebastian/version/.gitattributes
@@ -0,0 +1,4 @@
+/.github export-ignore
+/.php_cs.dist export-ignore
+
+*.php diff=php
diff --git a/vendor/sebastian/version/.gitignore b/vendor/sebastian/version/.gitignore
new file mode 100644
index 000000000..ff5ec9a0e
--- /dev/null
+++ b/vendor/sebastian/version/.gitignore
@@ -0,0 +1,2 @@
+/.php_cs.cache
+/.idea
diff --git a/vendor/sebastian/version/ChangeLog.md b/vendor/sebastian/version/ChangeLog.md
new file mode 100644
index 000000000..10fd9a1a5
--- /dev/null
+++ b/vendor/sebastian/version/ChangeLog.md
@@ -0,0 +1,25 @@
+# ChangeLog
+
+All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
+
+## [3.0.2] - 2020-09-28
+
+### Changed
+
+* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
+
+## [3.0.1] - 2020-06-26
+
+### Added
+
+* This component is now supported on PHP 8
+
+## [3.0.0] - 2020-01-21
+
+### Removed
+
+* This component is no longer supported on PHP 7.1 and PHP 7.2
+
+[3.0.2]: https://github.com/sebastianbergmann/version/compare/3.0.1...3.0.2
+[3.0.1]: https://github.com/sebastianbergmann/version/compare/3.0.0...3.0.1
+[3.0.0]: https://github.com/sebastianbergmann/version/compare/2.0.1...3.0.0
diff --git a/vendor/sebastian/version/LICENSE b/vendor/sebastian/version/LICENSE
new file mode 100644
index 000000000..aa6bca299
--- /dev/null
+++ b/vendor/sebastian/version/LICENSE
@@ -0,0 +1,33 @@
+Version
+
+Copyright (c) 2013-2020, Sebastian Bergmann <[email protected]>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/sebastian/version/README.md b/vendor/sebastian/version/README.md
new file mode 100644
index 000000000..2864c8126
--- /dev/null
+++ b/vendor/sebastian/version/README.md
@@ -0,0 +1,43 @@
+# Version
+
+**Version** is a library that helps with managing the version number of Git-hosted PHP projects.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+ composer require sebastian/version
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+ composer require --dev sebastian/version
+
+## Usage
+
+The constructor of the `SebastianBergmann\Version` class expects two parameters:
+
+* `$release` is the version number of the latest release (`X.Y.Z`, for instance) or the name of the release series (`X.Y`) when no release has been made from that branch / for that release series yet.
+* `$path` is the path to the directory (or a subdirectory thereof) where the sourcecode of the project can be found. Simply passing `__DIR__` here usually suffices.
+
+Apart from the constructor, the `SebastianBergmann\Version` class has a single public method: `getVersion()`.
+
+Here is a contrived example that shows the basic usage:
+
+ <?php
+ $version = new SebastianBergmann\Version(
+ '3.7.10', '/usr/local/src/phpunit'
+ );
+
+ var_dump($version->getVersion());
+ ?>
+
+ string(18) "3.7.10-17-g00f3408"
+
+When a new release is prepared, the string that is passed to the constructor as the first argument needs to be updated.
+
+### How SebastianBergmann\Version::getVersion() works
+
+* If `$path` is not (part of) a Git repository and `$release` is in `X.Y.Z` format then `$release` is returned as-is.
+* If `$path` is not (part of) a Git repository and `$release` is in `X.Y` format then `$release` is returned suffixed with `-dev`.
+* If `$path` is (part of) a Git repository and `$release` is in `X.Y.Z` format then the output of `git describe --tags` is returned as-is.
+* If `$path` is (part of) a Git repository and `$release` is in `X.Y` format then a string is returned that begins with `X.Y` and ends with information from `git describe --tags`.
diff --git a/vendor/sebastian/version/composer.json b/vendor/sebastian/version/composer.json
new file mode 100644
index 000000000..e76dbf412
--- /dev/null
+++ b/vendor/sebastian/version/composer.json
@@ -0,0 +1,37 @@
+{
+ "name": "sebastian/version",
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "[email protected]",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/version/issues"
+ },
+ "config": {
+ "platform": {
+ "php": "7.3.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "prefer-stable": true,
+ "require": {
+ "php": ">=7.3"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/version/src/Version.php b/vendor/sebastian/version/src/Version.php
new file mode 100644
index 000000000..53ae7894e
--- /dev/null
+++ b/vendor/sebastian/version/src/Version.php
@@ -0,0 +1,97 @@
+<?php
+/*
+ * This file is part of sebastian/version.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann;
+
+final class Version
+{
+ /**
+ * @var string
+ */
+ private $path;
+
+ /**
+ * @var string
+ */
+ private $release;
+
+ /**
+ * @var string
+ */
+ private $version;
+
+ public function __construct(string $release, string $path)
+ {
+ $this->release = $release;
+ $this->path = $path;
+ }
+
+ public function getVersion(): string
+ {
+ if ($this->version === null) {
+ if (\substr_count($this->release, '.') + 1 === 3) {
+ $this->version = $this->release;
+ } else {
+ $this->version = $this->release . '-dev';
+ }
+
+ $git = $this->getGitInformation($this->path);
+
+ if ($git) {
+ if (\substr_count($this->release, '.') + 1 === 3) {
+ $this->version = $git;
+ } else {
+ $git = \explode('-', $git);
+
+ $this->version = $this->release . '-' . \end($git);
+ }
+ }
+ }
+
+ return $this->version;
+ }
+
+ /**
+ * @return bool|string
+ */
+ private function getGitInformation(string $path)
+ {
+ if (!\is_dir($path . DIRECTORY_SEPARATOR . '.git')) {
+ return false;
+ }
+
+ $process = \proc_open(
+ 'git describe --tags',
+ [
+ 1 => ['pipe', 'w'],
+ 2 => ['pipe', 'w'],
+ ],
+ $pipes,
+ $path
+ );
+
+ if (!\is_resource($process)) {
+ return false;
+ }
+
+ $result = \trim(\stream_get_contents($pipes[1]));
+
+ \fclose($pipes[1]);
+ \fclose($pipes[2]);
+
+ $returnCode = \proc_close($process);
+
+ if ($returnCode !== 0) {
+ return false;
+ }
+
+ return $result;
+ }
+}